ReactOS  0.4.13-dev-92-gf251225
misc.cpp
Go to the documentation of this file.
1 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3 // All rights reserved
4 // This file was released under the GPLv2 on June 2015.
6 /*
7 
8  File: Misc.cpp
9 
10  Module: UDF File System Driver (Kernel mode execution only)
11 
12  Description:
13  This file contains some miscellaneous support routines.
14 
15 */
16 
17 #include "udffs.h"
18 // define the file specific bug-check id
19 #define UDF_BUG_CHECK_ID UDF_FILE_MISC
20 
21 #include <stdio.h>
22 
23 //CCHAR DefLetter[] = {""};
24 
25 /*
26 
27  Function: UDFInitializeZones()
28 
29  Description:
30  Allocates some memory for global zones used to allocate FSD structures.
31  Either all memory will be allocated or we will back out gracefully.
32 
33  Expected Interrupt Level (for execution) :
34 
35  IRQL_PASSIVE_LEVEL
36 
37  Return Value: STATUS_SUCCESS/Error
38 
39 */
42 {
44  uint32 SizeOfZone = UDFGlobalData.DefaultZoneSizeInNumStructs;
45  uint32 SizeOfObjectNameZone = 0;
46  uint32 SizeOfCCBZone = 0;
47 // uint32 SizeOfFCBZone = 0;
48  uint32 SizeOfIrpContextZone = 0;
49 // uint32 SizeOfFileInfoZone = 0;
50 
51  _SEH2_TRY {
52 
53  // initialize the spinlock protecting the zones
54  KeInitializeSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock));
55 
56  // determine memory requirements
57  switch (MmQuerySystemSize()) {
58  case MmMediumSystem:
59  SizeOfObjectNameZone = (4 * SizeOfZone * UDFQuadAlign(sizeof(UDFObjectName))) + sizeof(ZONE_SEGMENT_HEADER);
60  SizeOfCCBZone = (4 * SizeOfZone * UDFQuadAlign(sizeof(UDFCCB))) + sizeof(ZONE_SEGMENT_HEADER);
61  SizeOfIrpContextZone = (4 * SizeOfZone * UDFQuadAlign(sizeof(UDFIrpContext))) + sizeof(ZONE_SEGMENT_HEADER);
62  UDFGlobalData.MaxDelayedCloseCount = 24;
63  UDFGlobalData.MinDelayedCloseCount = 6;
64  UDFGlobalData.MaxDirDelayedCloseCount = 8;
65  UDFGlobalData.MinDirDelayedCloseCount = 2;
70  break;
71  case MmLargeSystem:
72  SizeOfObjectNameZone = (8 * SizeOfZone * UDFQuadAlign(sizeof(UDFObjectName))) + sizeof(ZONE_SEGMENT_HEADER);
73  SizeOfCCBZone = (8 * SizeOfZone * UDFQuadAlign(sizeof(UDFCCB))) + sizeof(ZONE_SEGMENT_HEADER);
74  SizeOfIrpContextZone = (8 * SizeOfZone * UDFQuadAlign(sizeof(UDFIrpContext))) + sizeof(ZONE_SEGMENT_HEADER);
75  UDFGlobalData.MaxDelayedCloseCount = 72;
76  UDFGlobalData.MinDelayedCloseCount = 18;
77  UDFGlobalData.MaxDirDelayedCloseCount = 24;
78  UDFGlobalData.MinDirDelayedCloseCount = 6;
83  break;
84  case MmSmallSystem:
85  default:
86  SizeOfObjectNameZone = (2 * SizeOfZone * UDFQuadAlign(sizeof(UDFObjectName))) + sizeof(ZONE_SEGMENT_HEADER);
87  SizeOfCCBZone = (2 * SizeOfZone * UDFQuadAlign(sizeof(UDFCCB))) + sizeof(ZONE_SEGMENT_HEADER);
88  SizeOfIrpContextZone = (2 * SizeOfZone * UDFQuadAlign(sizeof(UDFIrpContext))) + sizeof(ZONE_SEGMENT_HEADER);
89  UDFGlobalData.MaxDelayedCloseCount = 8;
90  UDFGlobalData.MinDelayedCloseCount = 2;
91  UDFGlobalData.MaxDirDelayedCloseCount = 6;
92  UDFGlobalData.MinDirDelayedCloseCount = 1;
97  }
98 
99  // typical NT methodology (at least until *someone* exposed the "difference" between a server and workstation ;-)
100  if (MmIsThisAnNtAsSystem()) {
101  SizeOfObjectNameZone *= UDF_NTAS_MULTIPLE;
102  SizeOfCCBZone *= UDF_NTAS_MULTIPLE;
103  SizeOfIrpContextZone *= UDF_NTAS_MULTIPLE;
104  }
105 
106  // allocate memory for each of the zones and initialize the zones ...
107  if (!(UDFGlobalData.ObjectNameZone = DbgAllocatePool(NonPagedPool, SizeOfObjectNameZone))) {
109  try_return(RC);
110  }
111 
112  if (!(UDFGlobalData.CCBZone = DbgAllocatePool(NonPagedPool, SizeOfCCBZone))) {
114  try_return(RC);
115  }
116 
117  if (!(UDFGlobalData.IrpContextZone = DbgAllocatePool(NonPagedPool, SizeOfIrpContextZone))) {
119  try_return(RC);
120  }
121 
122  // initialize each of the zone headers ...
123  if (!NT_SUCCESS(RC = ExInitializeZone(&(UDFGlobalData.ObjectNameZoneHeader),
124  UDFQuadAlign(sizeof(UDFObjectName)),
125  UDFGlobalData.ObjectNameZone, SizeOfObjectNameZone))) {
126  // failed the initialization, leave ...
127  try_return(RC);
128  }
129 
130  if (!NT_SUCCESS(RC = ExInitializeZone(&(UDFGlobalData.CCBZoneHeader),
131  UDFQuadAlign(sizeof(UDFCCB)),
132  UDFGlobalData.CCBZone,
133  SizeOfCCBZone))) {
134  // failed the initialization, leave ...
135  try_return(RC);
136  }
137 
138  if (!NT_SUCCESS(RC = ExInitializeZone(&(UDFGlobalData.IrpContextZoneHeader),
139  UDFQuadAlign(sizeof(UDFIrpContext)),
140  UDFGlobalData.IrpContextZone,
141  SizeOfIrpContextZone))) {
142  // failed the initialization, leave ...
143  try_return(RC);
144  }
145 
146 try_exit: NOTHING;
147 
148  } _SEH2_FINALLY {
149  if (!NT_SUCCESS(RC)) {
150  // invoke the destroy routine now ...
151  UDFDestroyZones();
152  } else {
153  // mark the fact that we have allocated zones ...
155  }
156  } _SEH2_END;
157 
158  return(RC);
159 }
160 
161 
162 /*************************************************************************
163 *
164 * Function: UDFDestroyZones()
165 *
166 * Description:
167 * Free up the previously allocated memory. NEVER do this once the
168 * driver has been successfully loaded.
169 *
170 * Expected Interrupt Level (for execution) :
171 *
172 * IRQL_PASSIVE_LEVEL
173 *
174 * Return Value: None
175 *
176 *************************************************************************/
178 {
179 // BrutePoint();
180 
181  _SEH2_TRY {
182  // free up each of the pools
183  if(UDFGlobalData.ObjectNameZone) {
184  DbgFreePool(UDFGlobalData.ObjectNameZone);
185  UDFGlobalData.ObjectNameZone = NULL;
186  }
187  if(UDFGlobalData.CCBZone) {
188  DbgFreePool(UDFGlobalData.CCBZone);
189  UDFGlobalData.CCBZone = NULL;
190  }
191  if(UDFGlobalData.IrpContextZone) {
192  DbgFreePool(UDFGlobalData.IrpContextZone);
193  UDFGlobalData.IrpContextZone = NULL;
194  }
195 
196 //try_exit: NOTHING;
197 
198  } _SEH2_FINALLY {
200  } _SEH2_END;
201 
202  return;
203 }
204 
205 
206 /*************************************************************************
207 *
208 * Function: UDFIsIrpTopLevel()
209 *
210 * Description:
211 * Helps the FSD determine who the "top level" caller is for this
212 * request. A request can originate directly from a user process
213 * (in which case, the "top level" will be NULL when this routine
214 * is invoked), OR the user may have originated either from the NT
215 * Cache Manager/VMM ("top level" may be set), or this could be a
216 * recursion into our code in which we would have set the "top level"
217 * field the last time around.
218 *
219 * Expected Interrupt Level (for execution) :
220 *
221 * whatever level a particular dispatch routine is invoked at.
222 *
223 * Return Value: TRUE/FALSE (TRUE if top level was NULL when routine invoked)
224 *
225 *************************************************************************/
226 BOOLEAN
229  PIRP Irp) // the IRP sent to our dispatch routine
230 {
231  if(!IoGetTopLevelIrp()) {
232  // OK, so we can set ourselves to become the "top level" component
234  return TRUE;
235  }
236  return FALSE;
237 }
238 
239 
240 /*************************************************************************
241 *
242 * Function: UDFExceptionFilter()
243 *
244 * Description:
245 * This routines allows the driver to determine whether the exception
246 * is an "allowed" exception i.e. one we should not-so-quietly consume
247 * ourselves, or one which should be propagated onwards in which case
248 * we will most likely bring down the machine.
249 *
250 * This routine employs the services of FsRtlIsNtstatusExpected(). This
251 * routine returns a BOOLEAN result. A RC of FALSE will cause us to return
252 * EXCEPTION_CONTINUE_SEARCH which will probably cause a panic.
253 * The FsRtl.. routine returns FALSE iff exception values are (currently) :
254 * STATUS_DATATYPE_MISALIGNMENT || STATUS_ACCESS_VIOLATION ||
255 * STATUS_ILLEGAL_INSTRUCTION || STATUS_INSTRUCTION_MISALIGNMENT
256 *
257 * Expected Interrupt Level (for execution) :
258 *
259 * ?
260 *
261 * Return Value: EXCEPTION_EXECUTE_HANDLER/EXECEPTION_CONTINUE_SEARCH
262 *
263 *************************************************************************/
264 long
266  PtrUDFIrpContext PtrIrpContext,
267  PEXCEPTION_POINTERS PtrExceptionPointers
268  )
269 {
270  long ReturnCode = EXCEPTION_EXECUTE_HANDLER;
272 #if defined UDF_DBG || defined PRINT_ALWAYS
273  ULONG i;
274 
275  UDFPrint(("UDFExceptionFilter\n"));
276  UDFPrint((" Ex. Code: %x\n",PtrExceptionPointers->ExceptionRecord->ExceptionCode));
277  UDFPrint((" Ex. Addr: %x\n",PtrExceptionPointers->ExceptionRecord->ExceptionAddress));
278  UDFPrint((" Ex. Flag: %x\n",PtrExceptionPointers->ExceptionRecord->ExceptionFlags));
279  UDFPrint((" Ex. Pnum: %x\n",PtrExceptionPointers->ExceptionRecord->NumberParameters));
280  for(i=0;i<PtrExceptionPointers->ExceptionRecord->NumberParameters;i++) {
281  UDFPrint((" %x\n",PtrExceptionPointers->ExceptionRecord->ExceptionInformation[i]));
282  }
283 #ifdef _X86_
284  UDFPrint(("Exception context:\n"));
285  if(PtrExceptionPointers->ContextRecord->ContextFlags & CONTEXT_INTEGER) {
286  UDFPrint(("EAX=%8.8x ",PtrExceptionPointers->ContextRecord->Eax));
287  UDFPrint(("EBX=%8.8x ",PtrExceptionPointers->ContextRecord->Ebx));
288  UDFPrint(("ECX=%8.8x ",PtrExceptionPointers->ContextRecord->Ecx));
289  UDFPrint(("EDX=%8.8x\n",PtrExceptionPointers->ContextRecord->Edx));
290 
291  UDFPrint(("ESI=%8.8x ",PtrExceptionPointers->ContextRecord->Esi));
292  UDFPrint(("EDI=%8.8x ",PtrExceptionPointers->ContextRecord->Edi));
293  }
294  if(PtrExceptionPointers->ContextRecord->ContextFlags & CONTEXT_CONTROL) {
295  UDFPrint(("EBP=%8.8x ",PtrExceptionPointers->ContextRecord->Esp));
296  UDFPrint(("ESP=%8.8x\n",PtrExceptionPointers->ContextRecord->Ebp));
297 
298  UDFPrint(("EIP=%8.8x\n",PtrExceptionPointers->ContextRecord->Eip));
299  }
300 // UDFPrint(("Flags: %s %s ",PtrExceptionPointers->ContextRecord->Eip));
301 #endif //_X86_
302 
303 #endif // UDF_DBG
304 
305  // figure out the exception code
306  ExceptionCode = PtrExceptionPointers->ExceptionRecord->ExceptionCode;
307 
308  if ((ExceptionCode == STATUS_IN_PAGE_ERROR) && (PtrExceptionPointers->ExceptionRecord->NumberParameters >= 3)) {
309  ExceptionCode = PtrExceptionPointers->ExceptionRecord->ExceptionInformation[2];
310  }
311 
312  if (PtrIrpContext) {
313  PtrIrpContext->SavedExceptionCode = ExceptionCode;
315  }
316 
317  // check if we should propagate this exception or not
319 
320  // better free up the IrpContext now ...
321  if (PtrIrpContext) {
322  UDFPrint((" UDF Driver internal error\n"));
323  BrutePoint();
324  } else {
325  // we are not ok, propagate this exception.
326  // NOTE: we will bring down the machine ...
327  ReturnCode = EXCEPTION_CONTINUE_SEARCH;
328  }
329  }
330 
331 
332  // return the appropriate code
333  return(ReturnCode);
334 } // end UDFExceptionFilter()
335 
336 
337 /*************************************************************************
338 *
339 * Function: UDFExceptionHandler()
340 *
341 * Description:
342 * One of the routines in the FSD or in the modules we invoked encountered
343 * an exception. We have decided that we will "handle" the exception.
344 * Therefore we will prevent the machine from a panic ...
345 * You can do pretty much anything you choose to in your commercial
346 * driver at this point to ensure a graceful exit. In the UDF
347 * driver, We shall simply free up the IrpContext (if any), set the
348 * error code in the IRP and complete the IRP at this time ...
349 *
350 * Expected Interrupt Level (for execution) :
351 *
352 * ?
353 *
354 * Return Value: Error code
355 *
356 *************************************************************************/
357 NTSTATUS
359  PtrUDFIrpContext PtrIrpContext,
360  PIRP Irp
361  )
362 {
363 // NTSTATUS RC;
366  PVPB Vpb;
368 
369  UDFPrint(("UDFExceptionHandler \n"));
370 
371 // ASSERT(Irp);
372 
373  if (!Irp) {
374  UDFPrint((" !Irp, return\n"));
375  ASSERT(!PtrIrpContext);
376  return ExceptionCode;
377  }
378  // If it was a queued close (or something like this) then we need not
379  // completing it because of MUST_SUCCEED requirement.
380 
381  if (PtrIrpContext) {
382  ExceptionCode = PtrIrpContext->SavedExceptionCode;
383  // Free irp context here
384 // UDFReleaseIrpContext(PtrIrpContext);
385  } else {
386  UDFPrint((" complete Irp and return\n"));
387  // must be insufficient resources ...?
389  Irp->IoStatus.Status = ExceptionCode;
390  Irp->IoStatus.Information = 0;
391  // complete the IRP
393 
394  return ExceptionCode;
395  }
396 
397  // Check if we are posting this request. One of the following must be true
398  // if we are to post a request.
399  //
400  // - Status code is STATUS_CANT_WAIT and the request is asynchronous
401  // or we are forcing this to be posted.
402  //
403  // - Status code is STATUS_VERIFY_REQUIRED and we are at APC level
404  // or higher. Can't wait for IO in the verify path in this case.
405  //
406  // Set the MORE_PROCESSING flag in the IrpContext to keep if from being
407  // deleted if this is a retryable condition.
408 
410  if (KeGetCurrentIrql() >= APC_LEVEL) {
411  UDFPrint((" use UDFPostRequest()\n"));
412  ExceptionCode = UDFPostRequest( PtrIrpContext, Irp );
413  }
414  }
415 
416  // If we posted the request or our caller will retry then just return here.
417  if ((ExceptionCode == STATUS_PENDING) ||
419 
420  UDFPrint((" STATUS_PENDING/STATUS_CANT_WAIT, return\n"));
421  return ExceptionCode;
422  }
423 
424  // Store this error into the Irp for posting back to the Io system.
425  Irp->IoStatus.Status = ExceptionCode;
427 
428  // Check for the various error conditions that can be caused by,
429  // and possibly resolved my the user.
431 
432  // Now we are at the top level file system entry point.
433  //
434  // If we have already posted this request then the device to
435  // verify is in the original thread. Find this via the Irp.
436  Device = IoGetDeviceToVerify( Irp->Tail.Overlay.Thread );
437  IoSetDeviceToVerify( Irp->Tail.Overlay.Thread, NULL );
438 
439  // If there is no device in that location then check in the
440  // current thread.
441  if (Device == NULL) {
442 
445 
446  ASSERT( Device != NULL );
447 
448  // Let's not BugCheck just because the driver screwed up.
449  if (Device == NULL) {
450 
451  UDFPrint((" Device == NULL, return\n"));
453  Irp->IoStatus.Status = ExceptionCode;
454  Irp->IoStatus.Information = 0;
455  // complete the IRP
457 
458  UDFReleaseIrpContext(PtrIrpContext);
459 
460  return ExceptionCode;
461  }
462  }
463 
464  UDFPrint((" use UDFPerformVerify()\n"));
465  // UDFPerformVerify() will do the right thing with the Irp.
466  // If we return STATUS_CANT_WAIT then the current thread
467  // can retry the request.
468  return UDFPerformVerify( PtrIrpContext, Irp, Device );
469  }
470 
471  //
472  // The other user induced conditions generate an error unless
473  // they have been disabled for this request.
474  //
475 
477 
478  UDFPrint((" DISABLE_POPUPS, complete Irp and return\n"));
479  Irp->IoStatus.Status = ExceptionCode;
480  Irp->IoStatus.Information = 0;
481  // complete the IRP
483 
484  UDFReleaseIrpContext(PtrIrpContext);
485  return ExceptionCode;
486  } else {
487 
488  // Generate a pop-up
490 
492  } else {
493 
494  Vpb = NULL;
495  }
496  // The device to verify is either in my thread local storage
497  // or that of the thread that owns the Irp.
498  Thread = Irp->Tail.Overlay.Thread;
500 
501  if (Device == NULL) {
502 
505  ASSERT( Device != NULL );
506 
507  // Let's not BugCheck just because the driver screwed up.
508  if (Device == NULL) {
509  UDFPrint((" Device == NULL, return(2)\n"));
510  Irp->IoStatus.Status = ExceptionCode;
511  Irp->IoStatus.Information = 0;
512  // complete the IRP
514 
515  UDFReleaseIrpContext(PtrIrpContext);
516 
517  return ExceptionCode;
518  }
519  }
520 
521  // This routine actually causes the pop-up. It usually
522  // does this by queuing an APC to the callers thread,
523  // but in some cases it will complete the request immediately,
524  // so it is very important to IoMarkIrpPending() first.
527 
528  // We will be handing control back to the caller here, so
529  // reset the saved device object.
530 
531  UDFPrint((" use IoSetDeviceToVerify()\n"));
533  // The Irp will be completed by Io or resubmitted. In either
534  // case we must clean up the IrpContext here.
535 
536  UDFReleaseIrpContext(PtrIrpContext);
537  return STATUS_PENDING;
538  }
539  }
540 
541  // If it was a normal request from IOManager then complete it
542  if (Irp) {
543  UDFPrint((" complete Irp\n"));
544  // set the error code in the IRP
545  Irp->IoStatus.Status = ExceptionCode;
546  Irp->IoStatus.Information = 0;
547 
548  // complete the IRP
550 
551  UDFReleaseIrpContext(PtrIrpContext);
552  }
553 
554  UDFPrint((" return from exception handler with code %x\n", ExceptionCode));
555  return(ExceptionCode);
556 } // end UDFExceptionHandler()
557 
558 /*************************************************************************
559 *
560 * Function: UDFLogEvent()
561 *
562 * Description:
563 * Log a message in the NT Event Log. This is a rather simplistic log
564 * methodology since we can potentially utilize the event log to
565 * provide a lot of information to the user (and you should too!)
566 *
567 * Expected Interrupt Level (for execution) :
568 *
569 * IRQL_PASSIVE_LEVEL
570 *
571 * Return Value: None
572 *
573 *************************************************************************/
574 VOID
576  NTSTATUS UDFEventLogId, // the UDF private message id
577  NTSTATUS RC) // any NT error code we wish to log ...
578 {
579  _SEH2_TRY {
580 
581  // Implement a call to IoAllocateErrorLogEntry() followed by a call
582  // to IoWriteErrorLogEntry(). You should note that the call to IoWriteErrorLogEntry()
583  // will free memory for the entry once the write completes (which in actuality
584  // is an asynchronous operation).
585 
587  // nothing really we can do here, just do not wish to crash ...
588  NOTHING;
589  } _SEH2_END;
590 
591  return;
592 } // end UDFLogEvent()
593 
594 
595 /*************************************************************************
596 *
597 * Function: UDFAllocateObjectName()
598 *
599 * Description:
600 * Allocate a new ObjectName structure to represent an open on-disk object.
601 * Also initialize the ObjectName structure to NULL.
602 *
603 * Expected Interrupt Level (for execution) :
604 *
605 * IRQL_PASSIVE_LEVEL
606 *
607 * Return Value: A pointer to the ObjectName structure OR NULL.
608 *
609 *************************************************************************/
612 {
613  PtrUDFObjectName PtrObjectName = NULL;
614  BOOLEAN AllocatedFromZone = TRUE;
615  KIRQL CurrentIrql;
616 
617  // first, __try to allocate out of the zone
618  KeAcquireSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), &CurrentIrql);
619  if (!ExIsFullZone(&(UDFGlobalData.ObjectNameZoneHeader))) {
620  // we have enough memory
621  PtrObjectName = (PtrUDFObjectName)ExAllocateFromZone(&(UDFGlobalData.ObjectNameZoneHeader));
622 
623  // release the spinlock
624  KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
625  } else {
626  // release the spinlock
627  KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
628 
629  // if we failed to obtain from the zone, get it directly from the VMM
631  AllocatedFromZone = FALSE;
632  }
633 
634  if (!PtrObjectName) {
635  return NULL;
636  }
637 
638  // zero out the allocated memory block
639  RtlZeroMemory(PtrObjectName, UDFQuadAlign(sizeof(UDFObjectName)));
640 
641  // set up some fields ...
643  PtrObjectName->NodeIdentifier.NodeSize = UDFQuadAlign(sizeof(UDFObjectName));
644 
645 
646  if (!AllocatedFromZone) {
648  }
649 
650  return(PtrObjectName);
651 } // end UDFAllocateObjectName()
652 
653 
654 /*************************************************************************
655 *
656 * Function: UDFReleaseObjectName()
657 *
658 * Description:
659 * Deallocate a previously allocated structure.
660 *
661 * Expected Interrupt Level (for execution) :
662 *
663 * IRQL_PASSIVE_LEVEL
664 *
665 * Return Value: None
666 *
667 *************************************************************************/
668 VOID
669 __fastcall
671  PtrUDFObjectName PtrObjectName)
672 {
673  KIRQL CurrentIrql;
674 
675  ASSERT(PtrObjectName);
676 
677  // give back memory either to the zone or to the VMM
678  if (!(PtrObjectName->ObjectNameFlags & UDF_OBJ_NAME_NOT_FROM_ZONE)) {
679  // back to the zone
680  KeAcquireSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), &CurrentIrql);
681  ExFreeToZone(&(UDFGlobalData.ObjectNameZoneHeader), PtrObjectName);
682  KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
683  } else {
684  MyFreePool__(PtrObjectName);
685  }
686 
687  return;
688 } // end UDFReleaseObjectName()
689 
690 
691 /*************************************************************************
692 *
693 * Function: UDFAllocateCCB()
694 *
695 * Description:
696 * Allocate a new CCB structure to represent an open on-disk object.
697 * Also initialize the CCB structure to NULL.
698 *
699 * Expected Interrupt Level (for execution) :
700 *
701 * IRQL_PASSIVE_LEVEL
702 *
703 * Return Value: A pointer to the CCB structure OR NULL.
704 *
705 *************************************************************************/
706 PtrUDFCCB
708 {
709  PtrUDFCCB Ccb = NULL;
710  BOOLEAN AllocatedFromZone = TRUE;
711  KIRQL CurrentIrql;
712 
713  // first, __try to allocate out of the zone
714  KeAcquireSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), &CurrentIrql);
715  if (!ExIsFullZone(&(UDFGlobalData.CCBZoneHeader))) {
716  // we have enough memory
717  Ccb = (PtrUDFCCB)ExAllocateFromZone(&(UDFGlobalData.CCBZoneHeader));
718 
719  // release the spinlock
720  KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
721  } else {
722  // release the spinlock
723  KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
724 
725  // if we failed to obtain from the zone, get it directly from the VMM
727  AllocatedFromZone = FALSE;
728 // UDFPrint((" CCB allocated @%x\n",Ccb));
729  }
730 
731  if (!Ccb) {
732  return NULL;
733  }
734 
735  // zero out the allocated memory block
737 
738  // set up some fields ...
739  Ccb->NodeIdentifier.NodeType = UDF_NODE_TYPE_CCB;
740  Ccb->NodeIdentifier.NodeSize = UDFQuadAlign(sizeof(UDFCCB));
741 
742 
743  if (!AllocatedFromZone) {
745  }
746 
747  UDFPrint(("UDFAllocateCCB: %x\n", Ccb));
748  return(Ccb);
749 } // end UDFAllocateCCB()
750 
751 
752 /*************************************************************************
753 *
754 * Function: UDFReleaseCCB()
755 *
756 * Description:
757 * Deallocate a previously allocated structure.
758 *
759 * Expected Interrupt Level (for execution) :
760 *
761 * IRQL_PASSIVE_LEVEL
762 *
763 * Return Value: None
764 *
765 *************************************************************************/
766 VOID
767 __fastcall
769  PtrUDFCCB Ccb
770  )
771 {
772  KIRQL CurrentIrql;
773 
774  ASSERT(Ccb);
775 
776  UDFPrint(("UDFReleaseCCB: %x\n", Ccb));
777  // give back memory either to the zone or to the VMM
778  if(!(Ccb->CCBFlags & UDF_CCB_NOT_FROM_ZONE)) {
779  // back to the zone
780  KeAcquireSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), &CurrentIrql);
781  ExFreeToZone(&(UDFGlobalData.CCBZoneHeader), Ccb);
782  KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
783  } else {
784  MyFreePool__(Ccb);
785  }
786 
787  return;
788 } // end UDFReleaseCCB()
789 
790 /*
791  Function: UDFCleanupCCB()
792 
793  Description:
794  Cleanup and deallocate a previously allocated structure.
795 
796  Expected Interrupt Level (for execution) :
797 
798  IRQL_PASSIVE_LEVEL
799 
800  Return Value: None
801 
802 */
803 VOID
804 __fastcall
806  PtrUDFCCB Ccb)
807 {
808 // ASSERT(Ccb);
809  if(!Ccb) return; // probably, we havn't allocated it...
810  ASSERT(Ccb->NodeIdentifier.NodeType == UDF_NODE_TYPE_CCB);
811 
812  _SEH2_TRY {
813  if(Ccb->Fcb) {
814  UDFTouch(&(Ccb->Fcb->CcbListResource));
815  UDFAcquireResourceExclusive(&(Ccb->Fcb->CcbListResource),TRUE);
816  RemoveEntryList(&(Ccb->NextCCB));
817  UDFReleaseResource(&(Ccb->Fcb->CcbListResource));
818  } else {
819  BrutePoint();
820  }
821 
822  if (Ccb->DirectorySearchPattern) {
823  if (Ccb->DirectorySearchPattern->Buffer) {
824  MyFreePool__(Ccb->DirectorySearchPattern->Buffer);
825  Ccb->DirectorySearchPattern->Buffer = NULL;
826  }
827 
828  MyFreePool__(Ccb->DirectorySearchPattern);
829  Ccb->DirectorySearchPattern = NULL;
830  }
831 
834  BrutePoint();
835  } _SEH2_END;
836 } // end UDFCleanUpCCB()
837 
838 /*************************************************************************
839 *
840 * Function: UDFAllocateFCB()
841 *
842 * Description:
843 * Allocate a new FCB structure to represent an open on-disk object.
844 * Also initialize the FCB structure to NULL.
845 *
846 * Expected Interrupt Level (for execution) :
847 *
848 * IRQL_PASSIVE_LEVEL
849 *
850 * Return Value: A pointer to the FCB structure OR NULL.
851 *
852 *************************************************************************/
853 PtrUDFFCB
855 {
856  PtrUDFFCB Fcb = NULL;
857 
859 
860  if (!Fcb) {
861  return NULL;
862  }
863 
864  // zero out the allocated memory block
866 
867  // set up some fields ...
868  Fcb->NodeIdentifier.NodeType = UDF_NODE_TYPE_FCB;
869  Fcb->NodeIdentifier.NodeSize = UDFQuadAlign(sizeof(UDFFCB));
870 
871  UDFPrint(("UDFAllocateFCB: %x\n", Fcb));
872  return(Fcb);
873 } // end UDFAllocateFCB()
874 
875 
876 /*************************************************************************
877 *
878 * Function: UDFReleaseFCB()
879 *
880 * Description:
881 * Deallocate a previously allocated structure.
882 *
883 * Expected Interrupt Level (for execution) :
884 *
885 * IRQL_PASSIVE_LEVEL
886 *
887 * Return Value: None
888 *
889 *************************************************************************/
890 /*VOID
891 UDFReleaseFCB(
892  PtrUDFFCB Fcb
893  )
894 {
895  ASSERT(Fcb);
896 
897  MyFreePool__(Fcb);
898 
899  return;
900 }*/
901 
902 /*************************************************************************
903 *
904 *
905 *************************************************************************/
906 VOID
907 __fastcall
909  PtrUDFFCB Fcb
910  )
911 {
912  UDFPrint(("UDFCleanUpFCB: %x\n", Fcb));
913  if(!Fcb) return;
914 
915  ASSERT(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_FCB);
916 
917  _SEH2_TRY {
918  // Deinitialize FCBName field
919  if (Fcb->FCBName) {
920  if(Fcb->FCBName->ObjectName.Buffer) {
921  MyFreePool__(Fcb->FCBName->ObjectName.Buffer);
922  Fcb->FCBName->ObjectName.Buffer = NULL;
923 #ifdef UDF_DBG
924  Fcb->FCBName->ObjectName.Length =
925  Fcb->FCBName->ObjectName.MaximumLength = 0;
926 #endif
927  }
928 #ifdef UDF_DBG
929  else {
930  UDFPrint(("UDF: Fcb has invalid FCBName Buffer\n"));
931  BrutePoint();
932  }
933 #endif
934  UDFReleaseObjectName(Fcb->FCBName);
935  Fcb->FCBName = NULL;
936  }
937 #ifdef UDF_DBG
938  else {
939  UDFPrint(("UDF: Fcb has invalid FCBName field\n"));
940  BrutePoint();
941  }
942 #endif
943 
944 
945  // begin transaction {
946  UDFTouch(&(Fcb->Vcb->FcbListResource));
947  UDFAcquireResourceExclusive(&(Fcb->Vcb->FcbListResource), TRUE);
948  // Remove this FCB from list of all FCB in VCB
949  RemoveEntryList(&(Fcb->NextFCB));
950  UDFReleaseResource(&(Fcb->Vcb->FcbListResource));
951  // } end transaction
952 
954  UDFDeleteResource(&(Fcb->CcbListResource));
955 
956  // Free memory
959  BrutePoint();
960  } _SEH2_END;
961 } // end UDFCleanUpFCB()
962 
963 #ifdef UDF_DBG
964 ULONG IrpContextCounter = 0;
965 #endif //UDF_DBG
966 
967 /*************************************************************************
968 *
969 * Function: UDFAllocateIrpContext()
970 *
971 * Description:
972 * The UDF FSD creates an IRP context for each request received. This
973 * routine simply allocates (and initializes to NULL) a UDFIrpContext
974 * structure.
975 * Most of the fields in the context structure are then initialized here.
976 *
977 * Expected Interrupt Level (for execution) :
978 *
979 * IRQL_PASSIVE_LEVEL
980 *
981 * Return Value: A pointer to the IrpContext structure OR NULL.
982 *
983 *************************************************************************/
986  PIRP Irp,
987  PDEVICE_OBJECT PtrTargetDeviceObject
988  )
989 {
990  PtrUDFIrpContext PtrIrpContext = NULL;
991  BOOLEAN AllocatedFromZone = TRUE;
992  KIRQL CurrentIrql;
994 
995  // first, __try to allocate out of the zone
996  KeAcquireSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), &CurrentIrql);
997  if (!ExIsFullZone(&(UDFGlobalData.IrpContextZoneHeader))) {
998  // we have enough memory
999  PtrIrpContext = (PtrUDFIrpContext)ExAllocateFromZone(&(UDFGlobalData.IrpContextZoneHeader));
1000 
1001  // release the spinlock
1002  KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
1003  } else {
1004  // release the spinlock
1005  KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
1006 
1007  // if we failed to obtain from the zone, get it directly from the VMM
1009  AllocatedFromZone = FALSE;
1010  }
1011 
1012  // if we could not obtain the required memory, bug-check.
1013  // Do NOT do this in your commercial driver, instead handle the error gracefully ...
1014  if (!PtrIrpContext) {
1015  return NULL;
1016  }
1017 
1018 #ifdef UDF_DBG
1019  IrpContextCounter++;
1020 #endif //UDF_DBG
1021 
1022  // zero out the allocated memory block
1023  RtlZeroMemory(PtrIrpContext, UDFQuadAlign(sizeof(UDFIrpContext)));
1024 
1025  // set up some fields ...
1027  PtrIrpContext->NodeIdentifier.NodeSize = UDFQuadAlign(sizeof(UDFIrpContext));
1028 
1029 
1030  PtrIrpContext->Irp = Irp;
1031  PtrIrpContext->TargetDeviceObject = PtrTargetDeviceObject;
1032 
1033  // copy over some fields from the IRP and set appropriate flag values
1034  if (Irp) {
1036  ASSERT(IrpSp);
1037 
1038  PtrIrpContext->MajorFunction = IrpSp->MajorFunction;
1039  PtrIrpContext->MinorFunction = IrpSp->MinorFunction;
1040 
1041  // Often, a FSD cannot honor a request for asynchronous processing
1042  // of certain critical requests. For example, a "close" request on
1043  // a file object can typically never be deferred. Therefore, do not
1044  // be surprised if sometimes our FSD (just like all other FSD
1045  // implementations on the Windows NT system) has to override the flag
1046  // below.
1047  if (IrpSp->FileObject == NULL) {
1048  PtrIrpContext->IrpContextFlags |= UDF_IRP_CONTEXT_CAN_BLOCK;
1049  } else {
1051  PtrIrpContext->IrpContextFlags |= UDF_IRP_CONTEXT_CAN_BLOCK;
1052  }
1053  }
1054  }
1055 
1056  if (!AllocatedFromZone) {
1058  }
1059 
1060  // Are we top-level ? This information is used by the dispatching code
1061  // later (and also by the FSD dispatch routine)
1062  if (IoGetTopLevelIrp() != Irp) {
1063  // We are not top-level. Note this fact in the context structure
1065  }
1066 
1067  return(PtrIrpContext);
1068 } // end UDFAllocateIrpContext()
1069 
1070 
1071 /*************************************************************************
1072 *
1073 * Function: UDFReleaseIrpContext()
1074 *
1075 * Description:
1076 * Deallocate a previously allocated structure.
1077 *
1078 * Expected Interrupt Level (for execution) :
1079 *
1080 * IRQL_PASSIVE_LEVEL
1081 *
1082 * Return Value: None
1083 *
1084 *************************************************************************/
1085 VOID
1087  PtrUDFIrpContext PtrIrpContext)
1088 {
1089  if(!PtrIrpContext) return;
1090 // ASSERT(PtrIrpContext);
1091 
1092 #ifdef UDF_DBG
1093  IrpContextCounter--;
1094 #endif //UDF_DBG
1095 
1096  // give back memory either to the zone or to the VMM
1097  if (!(PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_NOT_FROM_ZONE)) {
1098  // back to the zone
1099  KIRQL CurrentIrql;
1100 
1101  KeAcquireSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), &CurrentIrql);
1102  ExFreeToZone(&(UDFGlobalData.IrpContextZoneHeader), PtrIrpContext);
1103  KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
1104  } else {
1105  MyFreePool__(PtrIrpContext);
1106  }
1107 
1108  return;
1109 } // end UDFReleaseIrpContext()
1110 
1111 
1112 /*************************************************************************
1113 *
1114 * Function: UDFPostRequest()
1115 *
1116 * Description:
1117 * Queue up a request for deferred processing (in the context of a system
1118 * worker thread). The caller must have locked the user buffer (if required)
1119 *
1120 * Expected Interrupt Level (for execution) :
1121 *
1122 * IRQL_PASSIVE_LEVEL
1123 *
1124 * Return Value: STATUS_PENDING
1125 *
1126 *************************************************************************/
1127 NTSTATUS
1129  IN PtrUDFIrpContext PtrIrpContext,
1130  IN PIRP Irp
1131  )
1132 {
1133  KIRQL SavedIrql;
1134 // PIO_STACK_LOCATION IrpSp;
1135  PVCB Vcb;
1136 
1137 // IrpSp = IoGetCurrentIrpStackLocation(Irp);
1138 
1139 /*
1140  if(Vcb->StopOverflowQueue) {
1141  if(Irp) {
1142  Irp->IoStatus.Status = STATUS_WRONG_VOLUME;
1143  Irp->IoStatus.Information = 0;
1144  IoCompleteRequest(Irp, IO_DISK_INCREMENT);
1145  }
1146  UDFReleaseIrpContext(PtrIrpContext);
1147  return STATUS_WRONG_VOLUME;
1148  }
1149 */
1150  // mark the IRP pending if this is not double post
1151  if(Irp)
1153 
1154  Vcb = (PVCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension);
1155  KeAcquireSpinLock(&(Vcb->OverflowQueueSpinLock), &SavedIrql);
1156 
1157  if ( Vcb->PostedRequestCount > FSP_PER_DEVICE_THRESHOLD) {
1158 
1159  // We cannot currently respond to this IRP so we'll just enqueue it
1160  // to the overflow queue on the volume.
1161  // Note: we just reuse LIST_ITEM field inside WorkQueueItem, this
1162  // doesn't matter to regular processing of WorkItems.
1163  InsertTailList( &(Vcb->OverflowQueue),
1164  &(PtrIrpContext->WorkQueueItem.List) );
1165  Vcb->OverflowQueueCount++;
1166  KeReleaseSpinLock( &(Vcb->OverflowQueueSpinLock), SavedIrql );
1167 
1168  } else {
1169 
1170  // We are going to send this Irp to an ex worker thread so up
1171  // the count.
1172  Vcb->PostedRequestCount++;
1173 
1174  KeReleaseSpinLock( &(Vcb->OverflowQueueSpinLock), SavedIrql );
1175 
1176  // queue up the request
1177  ExInitializeWorkItem(&(PtrIrpContext->WorkQueueItem), UDFCommonDispatch, PtrIrpContext);
1178 
1179  ExQueueWorkItem(&(PtrIrpContext->WorkQueueItem), CriticalWorkQueue);
1180  // ExQueueWorkItem(&(PtrIrpContext->WorkQueueItem), DelayedWorkQueue);
1181 
1182  }
1183 
1184  // return status pending
1185  return STATUS_PENDING;
1186 } // end UDFPostRequest()
1187 
1188 
1189 /*************************************************************************
1190 *
1191 * Function: UDFCommonDispatch()
1192 *
1193 * Description:
1194 * The common dispatch routine invoked in the context of a system worker
1195 * thread. All we do here is pretty much case off the major function
1196 * code and invoke the appropriate FSD dispatch routine for further
1197 * processing.
1198 *
1199 * Expected Interrupt Level (for execution) :
1200 *
1201 * IRQL PASSIVE_LEVEL
1202 *
1203 * Return Value: None
1204 *
1205 *************************************************************************/
1206 VOID
1207 NTAPI
1209  IN PVOID Context // actually is a pointer to IRPContext structure
1210  )
1211 {
1212  NTSTATUS RC = STATUS_SUCCESS;
1213  PtrUDFIrpContext PtrIrpContext = NULL;
1214  PIRP Irp = NULL;
1215  PVCB Vcb;
1216  KIRQL SavedIrql;
1219 
1220  // The context must be a pointer to an IrpContext structure
1221  PtrIrpContext = (PtrUDFIrpContext)Context;
1222 
1223  // Assert that the Context is legitimate
1224  if ( !PtrIrpContext ||
1225  (PtrIrpContext->NodeIdentifier.NodeType != UDF_NODE_TYPE_IRP_CONTEXT) ||
1226  (PtrIrpContext->NodeIdentifier.NodeSize != UDFQuadAlign(sizeof(UDFIrpContext))) /*||
1227  !(PtrIrpContext->Irp)*/) {
1228  UDFPrint((" Invalid Context\n"));
1229  BrutePoint();
1230  return;
1231  }
1232 
1233  Vcb = (PVCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension);
1234  ASSERT(Vcb);
1235 
1236  UDFPrint((" *** Thr: %x ThCnt: %x QCnt: %x Started!\n", PsGetCurrentThread(), Vcb->PostedRequestCount, Vcb->OverflowQueueCount));
1237 
1238  while(TRUE) {
1239 
1240  UDFPrint((" Next IRP\n"));
1242 
1243  // Get a pointer to the IRP structure
1244  // in some cases we can get Zero pointer to Irp
1245  Irp = PtrIrpContext->Irp;
1246  // Now, check if the FSD was top level when the IRP was originally invoked
1247  // and set the thread context (for the worker thread) appropriately
1248  if (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_NOT_TOP_LEVEL) {
1249  // The FSD is not top level for the original request
1250  // Set a constant value in TLS to reflect this fact
1252  } else {
1254  }
1255 
1256  // Since the FSD routine will now be invoked in the context of this worker
1257  // thread, we should inform the FSD that it is perfectly OK to block in
1258  // the context of this thread
1259  PtrIrpContext->IrpContextFlags |= UDF_IRP_CONTEXT_CAN_BLOCK;
1260 
1261  _SEH2_TRY {
1262 
1263  // Pre-processing has been completed; check the Major Function code value
1264  // either in the IrpContext (copied from the IRP), or directly from the
1265  // IRP itself (we will need a pointer to the stack location to do that),
1266  // Then, switch based on the value on the Major Function code
1267  UDFPrint((" *** MJ: %x, Thr: %x\n", PtrIrpContext->MajorFunction, PsGetCurrentThread()));
1268  switch (PtrIrpContext->MajorFunction) {
1269  case IRP_MJ_CREATE:
1270  // Invoke the common create routine
1271  RC = UDFCommonCreate(PtrIrpContext, Irp);
1272  break;
1273  case IRP_MJ_READ:
1274  // Invoke the common read routine
1275  RC = UDFCommonRead(PtrIrpContext, Irp);
1276  break;
1277 #ifndef UDF_READ_ONLY_BUILD
1278  case IRP_MJ_WRITE:
1279  // Invoke the common write routine
1280  RC = UDFCommonWrite(PtrIrpContext, Irp);
1281  break;
1282 #endif //UDF_READ_ONLY_BUILD
1283  case IRP_MJ_CLEANUP:
1284  // Invoke the common cleanup routine
1285  RC = UDFCommonCleanup(PtrIrpContext, Irp);
1286  break;
1287  case IRP_MJ_CLOSE:
1288  // Invoke the common close routine
1289  RC = UDFCommonClose(PtrIrpContext, Irp);
1290  break;
1292  // Invoke the common directory control routine
1293  RC = UDFCommonDirControl(PtrIrpContext, Irp);
1294  break;
1296 #ifndef UDF_READ_ONLY_BUILD
1298 #endif //UDF_READ_ONLY_BUILD
1299  // Invoke the common query/set information routine
1300  RC = UDFCommonFileInfo(PtrIrpContext, Irp);
1301  break;
1303  // Invoke the common query volume routine
1304  RC = UDFCommonQueryVolInfo(PtrIrpContext, Irp);
1305  break;
1306 #ifndef UDF_READ_ONLY_BUILD
1308  // Invoke the common query volume routine
1309  RC = UDFCommonSetVolInfo(PtrIrpContext, Irp);
1310  break;
1311 #endif //UDF_READ_ONLY_BUILD
1312 #ifdef UDF_HANDLE_EAS
1313 /* case IRP_MJ_QUERY_EA:
1314  // Invoke the common query EAs routine
1315  RC = UDFCommonGetExtendedAttr(PtrIrpContext, Irp);
1316  break;
1317  case IRP_MJ_SET_EA:
1318  // Invoke the common set EAs routine
1319  RC = UDFCommonSetExtendedAttr(PtrIrpContext, Irp);
1320  break;*/
1321 #endif // UDF_HANDLE_EAS
1322 #ifdef UDF_ENABLE_SECURITY
1323  case IRP_MJ_QUERY_SECURITY:
1324  // Invoke the common query Security routine
1325  RC = UDFCommonGetSecurity(PtrIrpContext, Irp);
1326  break;
1327 #ifndef UDF_READ_ONLY_BUILD
1328  case IRP_MJ_SET_SECURITY:
1329  // Invoke the common set Security routine
1330  RC = UDFCommonSetSecurity(PtrIrpContext, Irp);
1331  break;
1332 #endif //UDF_READ_ONLY_BUILD
1333 #endif // UDF_ENABLE_SECURITY
1334  // Continue with the remaining possible dispatch routines below ...
1335  default:
1336  UDFPrint((" unhandled *** MJ: %x, Thr: %x\n", PtrIrpContext->MajorFunction, PsGetCurrentThread()));
1337  // This is the case where we have an invalid major function
1338  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
1339  Irp->IoStatus.Information = 0;
1340 
1342  // Free up the Irp Context
1343  UDFReleaseIrpContext(PtrIrpContext);
1344  break;
1345  }
1346 
1347  // Note: PtrIrpContext is invalid here
1348  UDFPrint((" *** Thr: %x Done!\n", PsGetCurrentThread()));
1349 
1351 
1352  RC = UDFExceptionHandler(PtrIrpContext, Irp);
1353 
1355  } _SEH2_END;
1356 
1357  // Enable preemption
1359 
1360  // Ensure that the "top-level" field is cleared
1362 
1363  // If there are any entries on this volume's overflow queue, service
1364  // them.
1365  if(!Vcb) {
1366  BrutePoint();
1367  break;
1368  }
1369 
1370  KeAcquireSpinLock(&(Vcb->OverflowQueueSpinLock), &SavedIrql);
1371  SpinLock = TRUE;
1372  if(!Vcb->OverflowQueueCount)
1373  break;
1374 
1375  Vcb->OverflowQueueCount--;
1376  Entry = RemoveHeadList(&Vcb->OverflowQueue);
1377  KeReleaseSpinLock(&(Vcb->OverflowQueueSpinLock), SavedIrql);
1378  SpinLock = FALSE;
1379 
1380  PtrIrpContext = CONTAINING_RECORD( Entry,
1381  UDFIrpContext,
1382  WorkQueueItem.List );
1383  }
1384 
1385  if(!SpinLock)
1386  KeAcquireSpinLock(&(Vcb->OverflowQueueSpinLock), &SavedIrql);
1387  Vcb->PostedRequestCount--;
1388  KeReleaseSpinLock(&(Vcb->OverflowQueueSpinLock), SavedIrql);
1389 
1390  UDFPrint((" *** Thr: %x ThCnt: %x QCnt: %x Terminated!\n", PsGetCurrentThread(), Vcb->PostedRequestCount, Vcb->OverflowQueueCount));
1391 
1392  return;
1393 } // end UDFCommonDispatch()
1394 
1395 
1396 /*************************************************************************
1397 *
1398 * Function: UDFInitializeVCB()
1399 *
1400 * Description:
1401 * Perform the initialization for a VCB structure.
1402 *
1403 * Expected Interrupt Level (for execution) :
1404 *
1405 * IRQL PASSIVE_LEVEL
1406 *
1407 * Return Value: status
1408 *
1409 *************************************************************************/
1410 NTSTATUS
1412  IN PDEVICE_OBJECT PtrVolumeDeviceObject,
1413  IN PDEVICE_OBJECT PtrTargetDeviceObject,
1414  IN PVPB PtrVPB
1415  )
1416 {
1417  NTSTATUS RC = STATUS_SUCCESS;
1418  PVCB Vcb = NULL;
1419  SHORT i;
1420 
1421  BOOLEAN VCBResourceInit = FALSE;
1422  BOOLEAN BitMapResource1Init = FALSE;
1423  BOOLEAN FcbListResourceInit = FALSE;
1424  BOOLEAN FileIdResourceInit = FALSE;
1425  BOOLEAN DlocResourceInit = FALSE;
1426  BOOLEAN DlocResource2Init = FALSE;
1427  BOOLEAN FlushResourceInit = FALSE;
1428  BOOLEAN PreallocResourceInit= FALSE;
1429  BOOLEAN IoResourceInit = FALSE;
1430 
1431  Vcb = (PVCB)(PtrVolumeDeviceObject->DeviceExtension);
1432 
1433  _SEH2_TRY {
1434  // Zero it out (typically this has already been done by the I/O
1435  // Manager but it does not hurt to do it again)!
1436  RtlZeroMemory(Vcb, sizeof(VCB));
1437 
1438  // Initialize the signature fields
1439  Vcb->NodeIdentifier.NodeType = UDF_NODE_TYPE_VCB;
1440  Vcb->NodeIdentifier.NodeSize = sizeof(VCB);
1441 
1442  // Initialize the ERESOURCE object.
1443  RC = UDFInitializeResourceLite(&(Vcb->VCBResource));
1444  if(!NT_SUCCESS(RC))
1445  try_return(RC);
1446  VCBResourceInit = TRUE;
1447 
1448  RC = UDFInitializeResourceLite(&(Vcb->BitMapResource1));
1449  if(!NT_SUCCESS(RC))
1450  try_return(RC);
1451  BitMapResource1Init = TRUE;
1452 
1453  RC = UDFInitializeResourceLite(&(Vcb->FcbListResource));
1454  if(!NT_SUCCESS(RC))
1455  try_return(RC);
1456  FcbListResourceInit = TRUE;
1457 
1458  RC = UDFInitializeResourceLite(&(Vcb->FileIdResource));
1459  if(!NT_SUCCESS(RC))
1460  try_return(RC);
1461  FileIdResourceInit = TRUE;
1462 
1463  RC = UDFInitializeResourceLite(&(Vcb->DlocResource));
1464  if(!NT_SUCCESS(RC))
1465  try_return(RC);
1466  DlocResourceInit = TRUE;
1467 
1468  RC = UDFInitializeResourceLite(&(Vcb->DlocResource2));
1469  if(!NT_SUCCESS(RC))
1470  try_return(RC);
1471  DlocResource2Init = TRUE;
1472 
1473  RC = UDFInitializeResourceLite(&(Vcb->FlushResource));
1474  if(!NT_SUCCESS(RC))
1475  try_return(RC);
1476  FlushResourceInit = TRUE;
1477 
1478  RC = UDFInitializeResourceLite(&(Vcb->PreallocResource));
1479  if(!NT_SUCCESS(RC))
1480  try_return(RC);
1481  PreallocResourceInit = TRUE;
1482 
1483  RC = UDFInitializeResourceLite(&(Vcb->IoResource));
1484  if(!NT_SUCCESS(RC))
1485  try_return(RC);
1486  IoResourceInit = TRUE;
1487 
1488 // RC = UDFInitializeResourceLite(&(Vcb->DelayedCloseResource));
1489 // ASSERT(NT_SUCCESS(RC));
1490 
1491  // Allocate buffer for statistics
1493  if(!Vcb->Statistics)
1495  RtlZeroMemory( Vcb->Statistics, sizeof(FILE_SYSTEM_STATISTICS) * KeNumberProcessors );
1496  for (i=0; i < (KeNumberProcessors); i++) {
1497  Vcb->Statistics[i].Common.FileSystemType = FILESYSTEM_STATISTICS_TYPE_NTFS;
1498  Vcb->Statistics[i].Common.Version = 1;
1499  Vcb->Statistics[i].Common.SizeOfCompleteStructure =
1500  sizeof(FILE_SYSTEM_STATISTICS);
1501  }
1502 
1503  // We know the target device object.
1504  // Note that this is not neccessarily a pointer to the actual
1505  // physical/virtual device on which the logical volume should
1506  // be mounted. This is actually a pointer to either the actual
1507  // (real) device or to any device object that may have been
1508  // attached to it. Any IRPs that we send down should be sent to this
1509  // device object. However, the "real" physical/virtual device object
1510  // on which we perform our mount operation can be determined from the
1511  // RealDevice field in the VPB sent to us.
1512  Vcb->TargetDeviceObject = PtrTargetDeviceObject;
1513 
1514  // We also have a pointer to the newly created device object representing
1515  // this logical volume (remember that this VCB structure is simply an
1516  // extension of the created device object).
1517  Vcb->VCBDeviceObject = PtrVolumeDeviceObject;
1518 
1519  // We also have the VPB pointer. This was obtained from the
1520  // Parameters.MountVolume.Vpb field in the current I/O stack location
1521  // for the mount IRP.
1522  Vcb->Vpb = PtrVPB;
1523  // Target Vcb field in Vcb onto itself. This required for check in
1524  // open/lock/unlock volume dispatch poits
1525  Vcb->Vcb=Vcb;
1526 
1527  // Set the removable media flag based on the real device's
1528  // characteristics
1529  if (PtrVPB->RealDevice->Characteristics & FILE_REMOVABLE_MEDIA) {
1530  Vcb->VCBFlags |= UDF_VCB_FLAGS_REMOVABLE_MEDIA;
1531  }
1532 
1533  // Initialize the list anchor (head) for some lists in this VCB.
1534  InitializeListHead(&(Vcb->NextFCB));
1535  InitializeListHead(&(Vcb->NextNotifyIRP));
1536  InitializeListHead(&(Vcb->VolumeOpenListHead));
1537 
1538  // Initialize the overflow queue for the volume
1539  Vcb->OverflowQueueCount = 0;
1540  InitializeListHead(&(Vcb->OverflowQueue));
1541 
1542  Vcb->PostedRequestCount = 0;
1543  KeInitializeSpinLock(&(Vcb->OverflowQueueSpinLock));
1544 
1545  // Initialize the notify IRP list mutex
1546  FsRtlNotifyInitializeSync(&(Vcb->NotifyIRPMutex));
1547 
1548  // Intilize NtRequiredFCB for this VCB
1550  if(!Vcb->NTRequiredFCB)
1552  RtlZeroMemory(Vcb->NTRequiredFCB, UDFQuadAlign(sizeof(UDFNTRequiredFCB)));
1553 
1554  // Set the initial file size values appropriately. Note that our FSD may
1555  // wish to guess at the initial amount of information we would like to
1556  // read from the disk until we have really determined that this a valid
1557  // logical volume (on disk) that we wish to mount.
1558  // Vcb->FileSize = Vcb->AllocationSize = ??
1559 
1560  // We do not want to bother with valid data length callbacks
1561  // from the Cache Manager for the file stream opened for volume metadata
1562  // information
1563  Vcb->NTRequiredFCB->CommonFCBHeader.ValidDataLength.QuadPart = 0x7FFFFFFFFFFFFFFFULL;
1564 
1565  Vcb->VolumeLockPID = -1;
1566 
1567  Vcb->VCBOpenCount = 1;
1568 
1569  Vcb->WCacheMaxBlocks = UDFGlobalData.WCacheMaxBlocks;
1570  Vcb->WCacheMaxFrames = UDFGlobalData.WCacheMaxFrames;
1571  Vcb->WCacheBlocksPerFrameSh = UDFGlobalData.WCacheBlocksPerFrameSh;
1572  Vcb->WCacheFramesToKeepFree = UDFGlobalData.WCacheFramesToKeepFree;
1573 
1574  // Create a stream file object for this volume.
1575  //Vcb->PtrStreamFileObject = IoCreateStreamFileObject(NULL,
1576  // Vcb->Vpb->RealDevice);
1577  //ASSERT(Vcb->PtrStreamFileObject);
1578 
1579  // Initialize some important fields in the newly created file object.
1580  //Vcb->PtrStreamFileObject->FsContext = (PVOID)Vcb;
1581  //Vcb->PtrStreamFileObject->FsContext2 = NULL;
1582  //Vcb->PtrStreamFileObject->SectionObjectPointer = &(Vcb->SectionObject);
1583 
1584  //Vcb->PtrStreamFileObject->Vpb = PtrVPB;
1585 
1586  // Link this chap onto the global linked list of all VCB structures.
1587  // We consider that GlobalDataResource was acquired in past
1588  UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
1589  InsertTailList(&(UDFGlobalData.VCBQueue), &(Vcb->NextVCB));
1590 
1591  Vcb->TargetDevName.Buffer = (PWCHAR)MyAllocatePool__(NonPagedPool, sizeof(MOUNTDEV_NAME));
1592  if(!Vcb->TargetDevName.Buffer)
1594 
1595  RC = UDFPhSendIOCTL(IOCTL_CDRW_GET_DEVICE_NAME /*IOCTL_MOUNTDEV_QUERY_DEVICE_NAME*/, Vcb->TargetDeviceObject,
1596  NULL,0,
1597  (PVOID)(Vcb->TargetDevName.Buffer),sizeof(MOUNTDEV_NAME),
1598  FALSE, NULL);
1599  if(!NT_SUCCESS(RC)) {
1600 
1601  if(RC == STATUS_BUFFER_OVERFLOW) {
1602  if(!MyReallocPool__((PCHAR)(Vcb->TargetDevName.Buffer), sizeof(MOUNTDEV_NAME),
1603  (PCHAR*)&(Vcb->TargetDevName.Buffer), Vcb->TargetDevName.Buffer[0]+sizeof(MOUNTDEV_NAME)) ) {
1604  goto Kill_DevName_buffer;
1605  }
1606 
1607  RC = UDFPhSendIOCTL(IOCTL_CDRW_GET_DEVICE_NAME /*IOCTL_MOUNTDEV_QUERY_DEVICE_NAME*/, Vcb->TargetDeviceObject,
1608  NULL,0,
1609  (PVOID)(Vcb->TargetDevName.Buffer), Vcb->TargetDevName.Buffer[0]+sizeof(MOUNTDEV_NAME),
1610  FALSE, NULL);
1611  if(!NT_SUCCESS(RC))
1612  goto Kill_DevName_buffer;
1613 
1614  } else {
1615 Kill_DevName_buffer:
1616  if(!MyReallocPool__((PCHAR)Vcb->TargetDevName.Buffer, sizeof(MOUNTDEV_NAME),
1617  (PCHAR*)&(Vcb->TargetDevName.Buffer), sizeof(REG_NAMELESS_DEV)))
1619  RtlCopyMemory(Vcb->TargetDevName.Buffer, REG_NAMELESS_DEV, sizeof(REG_NAMELESS_DEV));
1620  Vcb->TargetDevName.Length = sizeof(REG_NAMELESS_DEV)-sizeof(WCHAR);
1621  Vcb->TargetDevName.MaximumLength = sizeof(REG_NAMELESS_DEV);
1622  goto read_reg;
1623  }
1624  }
1625 
1626  Vcb->TargetDevName.MaximumLength =
1627  (Vcb->TargetDevName.Length = Vcb->TargetDevName.Buffer[0]) + sizeof(WCHAR);
1628  RtlMoveMemory((PVOID)(Vcb->TargetDevName.Buffer), (PVOID)(Vcb->TargetDevName.Buffer+1), Vcb->TargetDevName.Buffer[0]);
1629  Vcb->TargetDevName.Buffer[i = (SHORT)(Vcb->TargetDevName.Length/sizeof(WCHAR))] = 0;
1630 
1631  for(;i>=0;i--) {
1632  if(Vcb->TargetDevName.Buffer[i] == L'\\') {
1633 
1634  Vcb->TargetDevName.Length -= i*sizeof(WCHAR);
1635  RtlMoveMemory((PVOID)(Vcb->TargetDevName.Buffer), (PVOID)(Vcb->TargetDevName.Buffer+i), Vcb->TargetDevName.Length);
1636  Vcb->TargetDevName.Buffer[Vcb->TargetDevName.Length/sizeof(WCHAR)] = 0;
1637  break;
1638  }
1639  }
1640 
1641  UDFPrint((" TargetDevName: %S\n", Vcb->TargetDevName.Buffer));
1642 
1643  // Initialize caching for the stream file object.
1644  //CcInitializeCacheMap(Vcb->PtrStreamFileObject, (PCC_FILE_SIZES)(&(Vcb->AllocationSize)),
1645  // TRUE, // We will use pinned access.
1646  // &(UDFGlobalData.CacheMgrCallBacks), Vcb);
1647 
1648 read_reg:
1649 
1650  UDFReleaseResource(&(UDFGlobalData.GlobalDataResource));
1651 
1652  // Mark the fact that this VCB structure is initialized.
1653  Vcb->VCBFlags |= UDF_VCB_FLAGS_VCB_INITIALIZED;
1654 
1655  RC = STATUS_SUCCESS;
1656 
1657 try_exit: NOTHING;
1658 
1659  } _SEH2_FINALLY {
1660 
1661  if(!NT_SUCCESS(RC)) {
1662  if(Vcb->TargetDevName.Buffer)
1663  MyFreePool__(Vcb->TargetDevName.Buffer);
1664  if(Vcb->NTRequiredFCB)
1665  MyFreePool__(Vcb->NTRequiredFCB);
1666  if(Vcb->Statistics)
1667  MyFreePool__(Vcb->Statistics);
1668 
1669  if(VCBResourceInit)
1670  UDFDeleteResource(&(Vcb->VCBResource));
1671  if(BitMapResource1Init)
1672  UDFDeleteResource(&(Vcb->BitMapResource1));
1673  if(FcbListResourceInit)
1674  UDFDeleteResource(&(Vcb->FcbListResource));
1675  if(FileIdResourceInit)
1676  UDFDeleteResource(&(Vcb->FileIdResource));
1677  if(DlocResourceInit)
1678  UDFDeleteResource(&(Vcb->DlocResource));
1679  if(DlocResource2Init)
1680  UDFDeleteResource(&(Vcb->DlocResource2));
1681  if(FlushResourceInit)
1682  UDFDeleteResource(&(Vcb->FlushResource));
1683  if(PreallocResourceInit)
1684  UDFDeleteResource(&(Vcb->PreallocResource));
1685  if(IoResourceInit)
1686  UDFDeleteResource(&(Vcb->IoResource));
1687  }
1688  } _SEH2_END;
1689 
1690  return RC;
1691 } // end UDFInitializeVCB()
1692 
1695  PVCB Vcb
1696  )
1697 {
1698  switch(Vcb->FsDeviceType) {
1700  if(Vcb->VCBFlags & (UDF_VCB_FLAGS_VOLUME_READ_ONLY |
1702  return MediaCdrom;
1703  if(Vcb->CDR_Mode)
1704  return MediaCdr;
1705  if((Vcb->MediaType >= MediaType_UnknownSize_CDR) &&
1706  (Vcb->MediaType < MediaType_UnknownSize_CDRW)) {
1707  return MediaCdr;
1708  }
1709  if((Vcb->MediaType >= MediaType_UnknownSize_CDRW) &&
1710  (Vcb->MediaType < MediaType_UnknownSize_Unknown)) {
1711  return MediaCdrw;
1712  }
1713  if(Vcb->MediaClassEx == CdMediaClass_CDR) {
1714  return MediaCdr;
1715  }
1716  if(Vcb->MediaClassEx == CdMediaClass_DVDR ||
1717  Vcb->MediaClassEx == CdMediaClass_DVDpR ||
1718  Vcb->MediaClassEx == CdMediaClass_HD_DVDR ||
1719  Vcb->MediaClassEx == CdMediaClass_BDR) {
1720  return MediaDvdr;
1721  }
1722  if(Vcb->MediaClassEx == CdMediaClass_CDRW) {
1723  return MediaCdrw;
1724  }
1725  if(Vcb->MediaClassEx == CdMediaClass_DVDRW ||
1726  Vcb->MediaClassEx == CdMediaClass_DVDpRW ||
1727  Vcb->MediaClassEx == CdMediaClass_DVDRAM ||
1728  Vcb->MediaClassEx == CdMediaClass_HD_DVDRW ||
1729  Vcb->MediaClassEx == CdMediaClass_HD_DVDRAM ||
1730  Vcb->MediaClassEx == CdMediaClass_BDRE) {
1731  return MediaDvdrw;
1732  }
1733  //
1734  if(Vcb->MediaClassEx == CdMediaClass_CDROM ||
1735  Vcb->MediaClassEx == CdMediaClass_DVDROM ||
1736  Vcb->MediaClassEx == CdMediaClass_HD_DVDROM ||
1737  Vcb->MediaClassEx == CdMediaClass_BDROM) {
1738  return MediaCdrom;
1739  }
1740  return MediaCdrom;
1741 #ifdef UDF_HDD_SUPPORT
1743  if(Vcb->TargetDeviceObject->Characteristics & FILE_FLOPPY_DISKETTE)
1744  return MediaFloppy;
1745  if(Vcb->TargetDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
1746  return MediaZip;
1747  return MediaHdd;
1748 #endif //UDF_HDD_SUPPORT
1749  }
1750  return MediaUnknown;
1751 } // end UDFGetMediaClass()
1752 
1753 typedef ULONG
1755  IN PVCB Vcb,
1756  IN PCWSTR Name,
1757  IN ULONG DefValue
1758  );
1759 
1760 VOID
1762  PVCB Vcb,
1763  BOOLEAN Update,
1764  BOOLEAN UseCfg,
1765  PCWSTR Name,
1766  ULONG Flag,
1768  )
1769 {
1770  ptrUDFGetParameter UDFGetParameter = UseCfg ? UDFGetCfgParameter : UDFGetRegParameter;
1771 
1772  if(UDFGetParameter(Vcb, Name, Update ? ((Vcb->CompatFlags & Flag) ? TRUE : FALSE) : Default)) {
1773  Vcb->CompatFlags |= Flag;
1774  } else {
1775  Vcb->CompatFlags &= ~Flag;
1776  }
1777 } // end UDFUpdateCompatOption()
1778 
1779 VOID
1781  PVCB Vcb,
1782  BOOLEAN Update,
1783  BOOLEAN UseCfg
1784  )
1785 {
1786  ULONG mult = 1;
1787  ptrUDFGetParameter UDFGetParameter = UseCfg ? UDFGetCfgParameter : UDFGetRegParameter;
1788 
1789  Vcb->DefaultRegName = UDFMediaClassName[(ULONG)UDFGetMediaClass(Vcb)].ClassName;
1790 
1791  // Should we use Extended FE by default ?
1792  Vcb->UseExtendedFE = (UCHAR)UDFGetParameter(Vcb, REG_USEEXTENDEDFE_NAME,
1793  Update ? Vcb->UseExtendedFE : FALSE);
1794  if(Vcb->UseExtendedFE != TRUE) Vcb->UseExtendedFE = FALSE;
1795  // What type of AllocDescs should we use
1796  Vcb->DefaultAllocMode = (USHORT)UDFGetParameter(Vcb, REG_DEFALLOCMODE_NAME,
1797  Update ? Vcb->DefaultAllocMode : ICB_FLAG_AD_SHORT);
1798  if(Vcb->DefaultAllocMode > ICB_FLAG_AD_LONG) Vcb->DefaultAllocMode = ICB_FLAG_AD_SHORT;
1799  // Default UID & GID to be set on newly created files
1800  Vcb->DefaultUID = UDFGetParameter(Vcb, UDF_DEFAULT_UID_NAME, Update ? Vcb->DefaultUID : -1);
1801  Vcb->DefaultGID = UDFGetParameter(Vcb, UDF_DEFAULT_GID_NAME, Update ? Vcb->DefaultGID : -1);
1802  // FE allocation charge for plain Dirs
1803  Vcb->FECharge = UDFGetParameter(Vcb, UDF_FE_CHARGE_NAME, Update ? Vcb->FECharge : 0);
1804  if(!Vcb->FECharge)
1805  Vcb->FECharge = UDF_DEFAULT_FE_CHARGE;
1806  // FE allocation charge for Stream Dirs (SDir)
1807  Vcb->FEChargeSDir = UDFGetParameter(Vcb, UDF_FE_CHARGE_SDIR_NAME,
1808  Update ? Vcb->FEChargeSDir : 0);
1809  if(!Vcb->FEChargeSDir)
1810  Vcb->FEChargeSDir = UDF_DEFAULT_FE_CHARGE_SDIR;
1811  // How many Deleted entries should contain Directory to make us
1812  // start packing it.
1813  Vcb->PackDirThreshold = UDFGetParameter(Vcb, UDF_DIR_PACK_THRESHOLD_NAME,
1814  Update ? Vcb->PackDirThreshold : 0);
1815  if(Vcb->PackDirThreshold == 0xffffffff)
1816  Vcb->PackDirThreshold = UDF_DEFAULT_DIR_PACK_THRESHOLD;
1817  // The binary exponent for the number of Pages to be read-ahead'ed
1818  // This information would be sent to System Cache Manager
1819  if(!Update) {
1820  Vcb->SystemCacheGran = (1 << UDFGetParameter(Vcb, UDF_READAHEAD_GRAN_NAME, 0)) * PAGE_SIZE;
1821  if(!Vcb->SystemCacheGran)
1822  Vcb->SystemCacheGran = UDF_DEFAULT_READAHEAD_GRAN;
1823  }
1824  // Timeouts for FreeSpaceBitMap & TheWholeDirTree flushes
1825  Vcb->BM_FlushPriod = UDFGetParameter(Vcb, UDF_BM_FLUSH_PERIOD_NAME,
1826  Update ? Vcb->BM_FlushPriod : 0);
1827  if(!Vcb->BM_FlushPriod) {
1828  Vcb->BM_FlushPriod = UDF_DEFAULT_BM_FLUSH_TIMEOUT;
1829  } else
1830  if(Vcb->BM_FlushPriod == (ULONG)-1) {
1831  Vcb->BM_FlushPriod = 0;
1832  }
1833  Vcb->Tree_FlushPriod = UDFGetParameter(Vcb, UDF_TREE_FLUSH_PERIOD_NAME,
1834  Update ? Vcb->Tree_FlushPriod : 0);
1835  if(!Vcb->Tree_FlushPriod) {
1836  Vcb->Tree_FlushPriod = UDF_DEFAULT_TREE_FLUSH_TIMEOUT;
1837  } else
1838  if(Vcb->Tree_FlushPriod == (ULONG)-1) {
1839  Vcb->Tree_FlushPriod = 0;
1840  }
1841  Vcb->SkipCountLimit = UDFGetParameter(Vcb, UDF_NO_UPDATE_PERIOD_NAME,
1842  Update ? Vcb->SkipCountLimit : 0);
1843  if(!Vcb->SkipCountLimit)
1844  Vcb->SkipCountLimit = -1;
1845 
1846  Vcb->SkipEjectCountLimit = UDFGetParameter(Vcb, UDF_NO_EJECT_PERIOD_NAME,
1847  Update ? Vcb->SkipEjectCountLimit : 3);
1848 
1849  if(!Update) {
1850  // How many threads are allowed to sodomize Disc simultaneously on each CPU
1851  Vcb->ThreadsPerCpu = UDFGetParameter(Vcb, UDF_FSP_THREAD_PER_CPU_NAME,
1852  Update ? Vcb->ThreadsPerCpu : 2);
1853  if(Vcb->ThreadsPerCpu < 2)
1854  Vcb->ThreadsPerCpu = UDF_DEFAULT_FSP_THREAD_PER_CPU;
1855  }
1856  // The mimimum FileSize increment when we'll decide not to allocate
1857  // on-disk space.
1858  Vcb->SparseThreshold = UDFGetParameter(Vcb, UDF_SPARSE_THRESHOLD_NAME,
1859  Update ? Vcb->SparseThreshold : 0);
1860  if(!Vcb->SparseThreshold)
1861  Vcb->SparseThreshold = UDF_DEFAULT_SPARSE_THRESHOLD;
1862  // This option is used to VERIFY all the data written. It decreases performance
1863  Vcb->VerifyOnWrite = UDFGetParameter(Vcb, UDF_VERIFY_ON_WRITE_NAME,
1864  Update ? Vcb->VerifyOnWrite : FALSE) ? TRUE : FALSE;
1865 
1866 #ifndef UDF_READ_ONLY_BUILD
1867  // Should we update AttrFileTime on Attr changes
1869  // Should we update ModifyFileTime on Writes changes
1870  // It also affects ARCHIVE bit setting on write operations
1872  // Should we update AccessFileTime on Exec & so on.
1874  // Should we update Archive bit
1876  // Should we update Dir's Times & Attrs on Modify
1878  // Should we update Dir's Times & Attrs on Access
1880  // Should we allow user to write into Read-Only Directory
1882  // Should we allow user to change Access Time for unchanged Directory
1884 #endif //UDF_READ_ONLY_BUILD
1885  // Should we record Allocation Descriptors in W2k-compatible form
1887  // Should we read LONG_ADs with invalid PartitionReferenceNumber (generated by Nero Instant Burner)
1889  // Should we make a copy of VolumeLabel in LVD
1890  // usually only PVD is updated
1892  // Should we handle or ignore HW_RO flag
1894  // Should we handle or ignore SOFT_RO flag
1896 
1897  // Check if we should generate UDF-style or OS-style DOS-names
1899 #ifndef UDF_READ_ONLY_BUILD
1900  // should we force FO_WRITE_THROUGH on removable media
1902  (Vcb->TargetDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) ? TRUE : FALSE
1903  );
1904 #endif //UDF_READ_ONLY_BUILD
1905  // Should we ignore FO_SEQUENTIAL_ONLY
1907 // Force Read-only mounts
1908 #ifndef UDF_READ_ONLY_BUILD
1910 #else //UDF_READ_ONLY_BUILD
1911  Vcb->CompatFlags |= UDF_VCB_IC_FORCE_HW_RO;
1912 #endif //UDF_READ_ONLY_BUILD
1913  // Check if we should send FLUSH request for File/Dir down to
1914  // underlaying driver
1915  if(UDFGetParameter(Vcb, UDF_FLUSH_MEDIA,Update ? Vcb->FlushMedia : FALSE)) {
1916  Vcb->FlushMedia = TRUE;
1917  } else {
1918  Vcb->FlushMedia = FALSE;
1919  }
1920  // compare data from packet with data to be writen there
1921  // before physical writing
1922  if(!UDFGetParameter(Vcb, UDF_COMPARE_BEFORE_WRITE, Update ? Vcb->DoNotCompareBeforeWrite : FALSE)) {
1923  Vcb->DoNotCompareBeforeWrite = TRUE;
1924  } else {
1925  Vcb->DoNotCompareBeforeWrite = FALSE;
1926  }
1927  if(!Update) {
1928  if(UDFGetParameter(Vcb, UDF_CHAINED_IO, TRUE)) {
1929  Vcb->CacheChainedIo = TRUE;
1930  }
1931 
1932  if(UDFGetParameter(Vcb, UDF_FORCE_MOUNT_ALL, FALSE)) {
1933  Vcb->VCBFlags |= UDF_VCB_FLAGS_RAW_DISK;
1934  }
1935  // Should we show Blank.Cd file on damaged/unformatted,
1936  // but UDF-compatible disks
1937  Vcb->ShowBlankCd = (UCHAR)UDFGetParameter(Vcb, UDF_SHOW_BLANK_CD, FALSE);
1938  if(Vcb->ShowBlankCd) {
1939  Vcb->CompatFlags |= UDF_VCB_IC_SHOW_BLANK_CD;
1940  if(Vcb->ShowBlankCd > 2) {
1941  Vcb->ShowBlankCd = 2;
1942  }
1943  }
1944  // Should we wait util CD device return from
1945  // Becoming Ready state
1946  if(UDFGetParameter(Vcb, UDF_WAIT_CD_SPINUP, TRUE)) {
1947  Vcb->CompatFlags |= UDF_VCB_IC_WAIT_CD_SPINUP;
1948  }
1949  // Should we remenber bad VDS locations during mount
1950  // Caching will improve mount performance on bad disks, but
1951  // will degrade mauntability of unreliable discs
1952  if(UDFGetParameter(Vcb, UDF_CACHE_BAD_VDS, TRUE)) {
1953  Vcb->CompatFlags |= UDF_VCB_IC_CACHE_BAD_VDS;
1954  }
1955 
1956  // Set partitially damaged volume mount mode
1957  Vcb->PartitialDamagedVolumeAction = (UCHAR)UDFGetParameter(Vcb, UDF_PART_DAMAGED_BEHAVIOR, UDF_PART_DAMAGED_RW);
1958  if(Vcb->PartitialDamagedVolumeAction > 2) {
1959  Vcb->PartitialDamagedVolumeAction = UDF_PART_DAMAGED_RW;
1960  }
1961 
1962  // Set partitially damaged volume mount mode
1963  Vcb->NoFreeRelocationSpaceVolumeAction = (UCHAR)UDFGetParameter(Vcb, UDF_NO_SPARE_BEHAVIOR, UDF_PART_DAMAGED_RW);
1964  if(Vcb->NoFreeRelocationSpaceVolumeAction > 1) {
1965  Vcb->NoFreeRelocationSpaceVolumeAction = UDF_PART_DAMAGED_RW;
1966  }
1967 
1968  // Set dirty volume mount mode
1969  if(UDFGetParameter(Vcb, UDF_DIRTY_VOLUME_BEHAVIOR, UDF_PART_DAMAGED_RO)) {
1970  Vcb->CompatFlags |= UDF_VCB_IC_DIRTY_RO;
1971  }
1972 
1973  mult = UDFGetParameter(Vcb, UDF_CACHE_SIZE_MULTIPLIER, 1);
1974  if(!mult) mult = 1;
1975  Vcb->WCacheMaxBlocks *= mult;
1976  Vcb->WCacheMaxFrames *= mult;
1977 
1978  if(UDFGetParameter(Vcb, UDF_USE_EJECT_BUTTON, TRUE)) {
1979  Vcb->UseEvent = TRUE;
1980  }
1981  }
1982  return;
1983 } // end UDFReadRegKeys()
1984 
1985 ULONG
1987  IN PVCB Vcb,
1988  IN PCWSTR Name,
1989  IN ULONG DefValue
1990  )
1991 {
1993  Name,
1994  Vcb ? &(Vcb->TargetDevName) : NULL,
1995  Vcb ? Vcb->DefaultRegName : NULL,
1996  DefValue);
1997 } // end UDFGetRegParameter()
1998 
1999 ULONG
2001  IN PVCB Vcb,
2002  IN PCWSTR Name,
2003  IN ULONG DefValue
2004  )
2005 {
2006  ULONG len;
2007  CHAR NameA[128];
2008  ULONG ret_val=0;
2009  CHAR a;
2010  BOOLEAN wait_name=TRUE;
2011  BOOLEAN wait_val=FALSE;
2012  BOOLEAN wait_nl=FALSE;
2013  ULONG radix=10;
2014  ULONG i;
2015 
2016  PUCHAR Cfg = Vcb->Cfg;
2017  ULONG Length = Vcb->CfgLength;
2018 
2019  if(!Cfg || !Length)
2020  return DefValue;
2021 
2022  len = wcslen(Name);
2023  if(len >= sizeof(NameA))
2024  return DefValue;
2025  sprintf(NameA, "%S", Name);
2026 
2027  for(i=0; i<Length; i++) {
2028  a=Cfg[i];
2029  switch(a) {
2030  case '\n':
2031  case '\r':
2032  case ',':
2033  if(wait_val)
2034  return DefValue;
2035  continue;
2036  case ';':
2037  case '#':
2038  case '[': // ignore sections for now, treat as comment
2039  if(!wait_name)
2040  return DefValue;
2041  wait_nl = TRUE;
2042  continue;
2043  case '=':
2044  if(!wait_val)
2045  return DefValue;
2046  continue;
2047  case ' ':
2048  case '\t':
2049  continue;
2050  default:
2051  if(wait_nl)
2052  continue;
2053  }
2054  if(wait_name) {
2055  if(i+len+2 > Length)
2056  return DefValue;
2057  if(RtlCompareMemory(Cfg+i, NameA, len) == len) {
2058  a=Cfg[i+len];
2059  switch(a) {
2060  case '\n':
2061  case '\r':
2062  case ',':
2063  case ';':
2064  case '#':
2065  return DefValue;
2066  case '=':
2067  case ' ':
2068  case '\t':
2069  break;
2070  default:
2071  wait_nl = TRUE;
2072  wait_val = FALSE;
2073  i+=len;
2074  continue;
2075  }
2076  wait_name = FALSE;
2077  wait_nl = FALSE;
2078  wait_val = TRUE;
2079  i+=len;
2080 
2081  } else {
2082  wait_nl = TRUE;
2083  }
2084  continue;
2085  }
2086  if(wait_val) {
2087  if(i+3 > Length) {
2088  if(a=='0' && Cfg[i+1]=='x') {
2089  i+=2;
2090  radix=16;
2091  }
2092  }
2093  if(i >= Length) {
2094  return DefValue;
2095  }
2096  while(i<Length) {
2097  a=Cfg[i];
2098  switch(a) {
2099  case '\n':
2100  case '\r':
2101  case ' ':
2102  case '\t':
2103  case ',':
2104  case ';':
2105  case '#':
2106  if(wait_val)
2107  return DefValue;
2108  return ret_val;
2109  }
2110  if(a >= '0' && a <= '9') {
2111  a -= '0';
2112  } else {
2113  if(radix != 16)
2114  return DefValue;
2115  if(a >= 'a' && a <= 'f') {
2116  a -= 'a';
2117  } else
2118  if(a >= 'A' && a <= 'F') {
2119  a -= 'A';
2120  } else {
2121  return DefValue;
2122  }
2123  a += 0x0a;
2124  }
2125  ret_val = ret_val*radix + a;
2126  wait_val = FALSE;
2127  i++;
2128  }
2129  return ret_val;
2130  }
2131  }
2132  return DefValue;
2133 
2134 } // end UDFGetCfgParameter()
2135 
2136 VOID
2138  PVCB Vcb
2139  )
2140 {
2142  UDFPrint(("UDFReleaseVCB\n"));
2143 
2144  delay.QuadPart = -500000; // 0.05 sec
2145  while(Vcb->PostedRequestCount) {
2146  UDFPrint(("UDFReleaseVCB: PostedRequestCount = %d\n", Vcb->PostedRequestCount));
2147  // spin until all queues IRPs are processed
2149  delay.QuadPart -= 500000; // grow delay 0.05 sec
2150  }
2151 
2152  _SEH2_TRY {
2153  UDFPrint(("UDF: Flushing buffers\n"));
2154  UDFVRelease(Vcb);
2155  WCacheFlushAll__(&(Vcb->FastCache),Vcb);
2156  WCacheRelease__(&(Vcb->FastCache));
2157 
2159  BrutePoint();
2160  } _SEH2_END;
2161 
2162 #ifdef UDF_DBG
2163  _SEH2_TRY {
2164  if (!ExIsResourceAcquiredShared(&UDFGlobalData.GlobalDataResource)) {
2165  UDFPrint(("UDF: attempt to access to not protected data\n"));
2166  UDFPrint(("UDF: UDFGlobalData\n"));
2167  BrutePoint();
2168  }
2170  BrutePoint();
2171  } _SEH2_END;
2172 #endif
2173 
2174  _SEH2_TRY {
2175  RemoveEntryList(&(Vcb->NextVCB));
2177  BrutePoint();
2178  } _SEH2_END;
2179 
2180 /* _SEH2_TRY {
2181  if(Vcb->VCBFlags & UDF_VCB_FLAGS_STOP_WAITER_EVENT)
2182  KeWaitForSingleObject(&(Vcb->WaiterStopped), Executive, KernelMode, FALSE, NULL);
2183  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_STOP_WAITER_EVENT;
2184  } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
2185  BrutePoint();
2186  }*/
2187 
2188  _SEH2_TRY {
2189  UDFPrint(("UDF: Delete resources\n"));
2190  UDFDeleteResource(&(Vcb->VCBResource));
2191  UDFDeleteResource(&(Vcb->BitMapResource1));
2192  UDFDeleteResource(&(Vcb->FcbListResource));
2193  UDFDeleteResource(&(Vcb->FileIdResource));
2194  UDFDeleteResource(&(Vcb->DlocResource));
2195  UDFDeleteResource(&(Vcb->DlocResource2));
2196  UDFDeleteResource(&(Vcb->FlushResource));
2197  UDFDeleteResource(&(Vcb->PreallocResource));
2198  UDFDeleteResource(&(Vcb->IoResource));
2200  BrutePoint();
2201  } _SEH2_END;
2202 
2203  _SEH2_TRY {
2204  UDFPrint(("UDF: Cleanup VCB\n"));
2205  ASSERT(IsListEmpty(&(Vcb->NextNotifyIRP)));
2206  FsRtlNotifyUninitializeSync(&(Vcb->NotifyIRPMutex));
2207  UDFCleanupVCB(Vcb);
2209  BrutePoint();
2210  } _SEH2_END;
2211 
2212  _SEH2_TRY {
2213  UDFPrint(("UDF: Delete DO\n"));
2214  IoDeleteDevice(Vcb->VCBDeviceObject);
2216  BrutePoint();
2217  } _SEH2_END;
2218 
2219 } // end UDFReleaseVCB()
2220 
2221 /*
2222  Read DWORD from Registry
2223 */
2224 ULONG
2227  IN PCWSTR Name,
2228  IN PUNICODE_STRING PtrVolumePath,
2229  IN PCWSTR DefaultPath,
2230  IN ULONG DefValue
2231  )
2232 {
2233  NTSTATUS status;
2234 
2235  ULONG val = DefValue;
2236 
2237  UNICODE_STRING paramStr;
2238  UNICODE_STRING defaultParamStr;
2239  UNICODE_STRING paramPathUnknownStr;
2240 
2241  UNICODE_STRING paramSuffix;
2242  UNICODE_STRING paramPath;
2243  UNICODE_STRING paramPathUnknown;
2244  UNICODE_STRING paramDevPath;
2245  UNICODE_STRING defaultParamPath;
2246 
2247  _SEH2_TRY {
2248 
2249  paramPath.Buffer = NULL;
2250  paramDevPath.Buffer = NULL;
2251  paramPathUnknown.Buffer = NULL;
2252  defaultParamPath.Buffer = NULL;
2253 
2254  // First append \Parameters to the passed in registry path
2255  // Note, RtlInitUnicodeString doesn't allocate memory
2256  RtlInitUnicodeString(&paramStr, L"\\Parameters");
2257  RtlInitUnicodeString(&paramPath, NULL);
2258 
2259  RtlInitUnicodeString(&paramPathUnknownStr, REG_DEFAULT_UNKNOWN);
2260  RtlInitUnicodeString(&paramPathUnknown, NULL);
2261 
2262  paramPathUnknown.MaximumLength = RegistryPath->Length + paramPathUnknownStr.Length + paramStr.Length + sizeof(WCHAR);
2263  paramPath.MaximumLength = RegistryPath->Length + paramStr.Length + sizeof(WCHAR);
2264 
2265  paramPath.Buffer = (PWCH)MyAllocatePool__(PagedPool, paramPath.MaximumLength);
2266  if(!paramPath.Buffer) {
2267  UDFPrint(("UDFCheckRegValue: couldn't allocate paramPath\n"));
2268  try_return(val = DefValue);
2269  }
2270  paramPathUnknown.Buffer = (PWCH)MyAllocatePool__(PagedPool, paramPathUnknown.MaximumLength);
2271  if(!paramPathUnknown.Buffer) {
2272  UDFPrint(("UDFCheckRegValue: couldn't allocate paramPathUnknown\n"));
2273  try_return(val = DefValue);
2274  }
2275 
2276  RtlZeroMemory(paramPath.Buffer, paramPath.MaximumLength);
2278  if(!NT_SUCCESS(status)) {
2279  try_return(val = DefValue);
2280  }
2281  status = RtlAppendUnicodeToString(&paramPath, paramStr.Buffer);
2282  if(!NT_SUCCESS(status)) {
2283  try_return(val = DefValue);
2284  }
2285  UDFPrint(("UDFCheckRegValue: (1) |%S|\n", paramPath.Buffer));
2286 
2287  RtlZeroMemory(paramPathUnknown.Buffer, paramPathUnknown.MaximumLength);
2288  status = RtlAppendUnicodeToString(&paramPathUnknown, RegistryPath->Buffer);
2289  if(!NT_SUCCESS(status)) {
2290  try_return(val = DefValue);
2291  }
2292  status = RtlAppendUnicodeToString(&paramPathUnknown, paramStr.Buffer);
2293  if(!NT_SUCCESS(status)) {
2294  try_return(val = DefValue);
2295  }
2296  status = RtlAppendUnicodeToString(&paramPathUnknown, paramPathUnknownStr.Buffer);
2297  if(!NT_SUCCESS(status)) {
2298  try_return(val = DefValue);
2299  }
2300  UDFPrint(("UDFCheckRegValue: (2) |%S|\n", paramPathUnknown.Buffer));
2301 
2302  // First append \Parameters\Default_XXX to the passed in registry path
2303  if(DefaultPath) {
2304  RtlInitUnicodeString(&defaultParamStr, DefaultPath);
2305  RtlInitUnicodeString(&defaultParamPath, NULL);
2306  defaultParamPath.MaximumLength = paramPath.Length + defaultParamStr.Length + sizeof(WCHAR);
2307  defaultParamPath.Buffer = (PWCH)MyAllocatePool__(PagedPool, defaultParamPath.MaximumLength);
2308  if(!defaultParamPath.Buffer) {
2309  UDFPrint(("UDFCheckRegValue: couldn't allocate defaultParamPath\n"));
2310  try_return(val = DefValue);
2311  }
2312 
2313  RtlZeroMemory(defaultParamPath.Buffer, defaultParamPath.MaximumLength);
2314  status = RtlAppendUnicodeToString(&defaultParamPath, paramPath.Buffer);
2315  if(!NT_SUCCESS(status)) {
2316  try_return(val = DefValue);
2317  }
2318  status = RtlAppendUnicodeToString(&defaultParamPath, defaultParamStr.Buffer);
2319  if(!NT_SUCCESS(status)) {
2320  try_return(val = DefValue);
2321  }
2322  UDFPrint(("UDFCheckRegValue: (3) |%S|\n", defaultParamPath.Buffer));
2323  }
2324 
2325  if(PtrVolumePath) {
2326  paramSuffix = *PtrVolumePath;
2327  } else {
2328  RtlInitUnicodeString(&paramSuffix, NULL);
2329  }
2330 
2331  RtlInitUnicodeString(&paramDevPath, NULL);
2332  // now build the device specific path
2333  paramDevPath.MaximumLength = paramPath.Length + paramSuffix.Length + sizeof(WCHAR);
2334  paramDevPath.Buffer = (PWCH)MyAllocatePool__(PagedPool, paramDevPath.MaximumLength);
2335  if(!paramDevPath.Buffer) {
2336  try_return(val = DefValue);
2337  }
2338 
2339  RtlZeroMemory(paramDevPath.Buffer, paramDevPath.MaximumLength);
2340  status = RtlAppendUnicodeToString(&paramDevPath, paramPath.Buffer);
2341  if(!NT_SUCCESS(status)) {
2342  try_return(val = DefValue);
2343  }
2344  if(paramSuffix.Buffer) {
2345  status = RtlAppendUnicodeToString(&paramDevPath, paramSuffix.Buffer);
2346  if(!NT_SUCCESS(status)) {
2347  try_return(val = DefValue);
2348  }
2349  }
2350 
2351  UDFPrint(( " Parameter = %ws\n", Name));
2352 
2353  {
2354  HKEY hk = NULL;
2356  if(NT_SUCCESS(status)) {
2357  RegTCloseKeyHandle(hk);
2358  }
2359  }
2360 
2361 
2362  // *** Read GLOBAL_DEFAULTS from
2363  // "\DwUdf\Parameters_Unknown\"
2364 
2365  status = RegTGetDwordValue(NULL, paramPath.Buffer, Name, &val);
2366 
2367  // *** Read DEV_CLASS_SPEC_DEFAULTS (if any) from
2368  // "\DwUdf\Parameters_%DevClass%\"
2369 
2370  if(DefaultPath) {
2371  status = RegTGetDwordValue(NULL, defaultParamPath.Buffer, Name, &val);
2372  }
2373 
2374  // *** Read DEV_SPEC_PARAMS from (if device supports GetDevName)
2375  // "\DwUdf\Parameters\%DevName%\"
2376 
2377  status = RegTGetDwordValue(NULL, paramDevPath.Buffer, Name, &val);
2378 
2379 try_exit: NOTHING;
2380 
2381  } _SEH2_FINALLY {
2382 
2383  if(DefaultPath && defaultParamPath.Buffer) {
2384  MyFreePool__(defaultParamPath.Buffer);
2385  }
2386  if(paramPath.Buffer) {
2387  MyFreePool__(paramPath.Buffer);
2388  }
2389  if(paramDevPath.Buffer) {
2390  MyFreePool__(paramDevPath.Buffer);
2391  }
2392  if(paramPathUnknown.Buffer) {
2393  MyFreePool__(paramPathUnknown.Buffer);
2394  }
2395  } _SEH2_END;
2396 
2397  UDFPrint(( "UDFCheckRegValue: %ws for drive %s is %x\n\n", Name, PtrVolumePath, val));
2398  return val;
2399 } // end UDFRegCheckParameterValue()
2400 
2401 /*
2402 Routine Description:
2403  This routine is called to initialize an IrpContext for the current
2404  UDFFS request. The IrpContext is on the stack and we need to initialize
2405  it for the current request. The request is a close operation.
2406 
2407 Arguments:
2408 
2409  IrpContext - IrpContext to initialize.
2410 
2411  IrpContextLite - source for initialization
2412 
2413 Return Value:
2414 
2415  None
2416 
2417 */
2418 VOID
2420  OUT PtrUDFIrpContext *IrpContext,
2421  IN PtrUDFIrpContextLite IrpContextLite
2422  )
2423 {
2424  (*IrpContext) = UDFAllocateIrpContext(NULL, IrpContextLite->RealDevice);
2425  // Zero and then initialize the structure.
2426 
2427  // Major/Minor Function codes
2428  (*IrpContext)->MajorFunction = IRP_MJ_CLOSE;
2429  (*IrpContext)->Fcb = IrpContextLite->Fcb;
2430  (*IrpContext)->TreeLength = IrpContextLite->TreeLength;
2431  (*IrpContext)->IrpContextFlags |= (IrpContextLite->IrpContextFlags & ~UDF_IRP_CONTEXT_NOT_FROM_ZONE);
2432 
2433  // Set the wait parameter
2434  UDFSetFlag( (*IrpContext)->IrpContextFlags, UDF_IRP_CONTEXT_CAN_BLOCK );
2435 
2436  return;
2437 } // end UDFInitializeIrpContextFromLite()
2438 
2439 /*
2440 Routine Description:
2441  This routine is called to initialize an IrpContext for the current
2442  UDFFS request. The IrpContext is on the stack and we need to initialize
2443  it for the current request. The request is a close operation.
2444 
2445 Arguments:
2446 
2447  IrpContext - IrpContext to initialize.
2448 
2449  IrpContextLite - source for initialization
2450 
2451 Return Value:
2452 
2453  None
2454 
2455 */
2456 NTSTATUS
2458  OUT PtrUDFIrpContextLite *IrpContextLite,
2459  IN PtrUDFIrpContext IrpContext,
2460  IN PtrUDFFCB Fcb
2461  )
2462 {
2464  if(!LocalIrpContextLite)
2466  // Zero and then initialize the structure.
2467  RtlZeroMemory( LocalIrpContextLite, sizeof( UDFIrpContextLite ));
2468 
2470  LocalIrpContextLite->NodeIdentifier.NodeSize = sizeof(UDFIrpContextLite);
2471 
2472  LocalIrpContextLite->Fcb = Fcb;
2473  LocalIrpContextLite->TreeLength = IrpContext->TreeLength;
2474  // Copy RealDevice for workque algorithms.
2475  LocalIrpContextLite->RealDevice = IrpContext->TargetDeviceObject;
2476  LocalIrpContextLite->IrpContextFlags = IrpContext->IrpContextFlags;
2477  *IrpContextLite = LocalIrpContextLite;
2478 
2479  return STATUS_SUCCESS;
2480 } // end UDFInitializeIrpContextLite()
2481 
2482 NTSTATUS
2483 NTAPI
2485  PDEVICE_OBJECT DeviceObject, // the logical volume device object
2486  PIRP Irp // I/O Request Packet
2487  )
2488 {
2489  NTSTATUS RC = STATUS_SUCCESS;
2490 // PtrUDFIrpContext PtrIrpContext = NULL;
2491  BOOLEAN AreWeTopLevel = FALSE;
2492 
2493  UDFPrint(("UDFQuerySetEA: \n"));
2494 
2497  ASSERT(Irp);
2498 
2499  // set the top level context
2500  AreWeTopLevel = UDFIsIrpTopLevel(Irp);
2501 
2503  Irp->IoStatus.Status = RC;
2504  Irp->IoStatus.Information = 0;
2505  // complete the IRP
2507 
2508  if(AreWeTopLevel) {
2510  }
2511 
2513 
2514  return(RC);
2515 } // end UDFQuerySetEA()
2516 
2517 ULONG
2520  )
2521 {
2522  ULONG ReAcqRes =
2525  return ReAcqRes;
2526 } // end UDFIsResourceAcquired()
2527 
2528 BOOLEAN
2531  )
2532 {
2533  ULONG ReAcqRes =
2536  if(ReAcqRes) {
2537  UDFPrint(("UDFAcquireResourceExclusiveWithCheck: ReAcqRes, %x\n", ReAcqRes));
2538  } else {
2539 // BrutePoint();
2540  }
2541 
2542  if(ReAcqRes == 1) {
2543  // OK
2544  } else
2545  if(ReAcqRes == 2) {
2546  UDFPrint(("UDFAcquireResourceExclusiveWithCheck: !!! Shared !!!\n"));
2547  //BrutePoint();
2548  } else {
2550  return TRUE;
2551  }
2552  return FALSE;
2553 } // end UDFAcquireResourceExclusiveWithCheck()
2554 
2555 BOOLEAN
2558  )
2559 {
2560  ULONG ReAcqRes =
2563  if(ReAcqRes) {
2564  UDFPrint(("UDFAcquireResourceSharedWithCheck: ReAcqRes, %x\n", ReAcqRes));
2565 /* } else {
2566  BrutePoint();*/
2567  }
2568 
2569  if(ReAcqRes == 2) {
2570  // OK
2571  } else
2572  if(ReAcqRes == 1) {
2573  UDFPrint(("UDFAcquireResourceSharedWithCheck: Exclusive\n"));
2574  //BrutePoint();
2575  } else {
2577  return TRUE;
2578  }
2579  return FALSE;
2580 } // end UDFAcquireResourceSharedWithCheck()
2581 
2582 NTSTATUS
2584  IN PVOID Context,
2585  IN PWCACHE_ERROR_CONTEXT ErrorInfo
2586  )
2587 {
2588  InterlockedIncrement((PLONG)&(((PVCB)Context)->IoErrorCounter));
2589  return ErrorInfo->Status;
2590 }
2591 
2592 #include "Include/misc_common.cpp"
2593 #include "Include/regtools.cpp"
2594 
#define UDF_VCB_IC_CACHE_BAD_VDS
Definition: udf_common.h:518
#define UDF_VCB_IC_SHOW_BLANK_CD
Definition: udf_common.h:520
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID UDFVRelease(IN PVCB Vcb)
Definition: remap.cpp:132
#define UDF_DEFAULT_FE_CHARGE_SDIR
Definition: udf_rel.h:501
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
signed char * PCHAR
Definition: retypes.h:7
#define DbgAllocatePool
Definition: env_spec_w32.h:332
#define STATUS_EAS_NOT_SUPPORTED
Definition: ntstatus.h:301
#define UDF_FORCE_MOUNT_ALL
Definition: udf_reg.h:191
#define UDF_VCB_FLAGS_MEDIA_READ_ONLY
Definition: udf_common.h:481
#define UDF_VCB_IC_WRITE_IN_RO_DIR
Definition: udf_common.h:499
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
PtrUDFIrpContext UDFAllocateIrpContext(PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
Definition: misc.cpp:985
#define CdMediaClass_BDROM
Definition: cdrw_usr.h:755
ZONE_SEGMENT_HEADER
Definition: extypes.h:285
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1782
#define CdMediaClass_DVDRAM
Definition: cdrw_usr.h:747
#define UDF_UPDATE_TIMES_ACCS
Definition: udf_reg.h:155
#define UDF_UPDATE_DIR_TIMES_ATTR_W
Definition: udf_reg.h:161
VOID __fastcall UDFReleaseObjectName(PtrUDFObjectName PtrObjectName)
Definition: misc.cpp:670
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define UDF_DEFAULT_BM_FLUSH_TIMEOUT
Definition: udffs.h:95
#define IN
Definition: typedefs.h:38
#define UDF_NODE_TYPE_OBJECT_NAME
Definition: struct.h:58
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
#define UDFInitializeResourceLite(Resource)
Definition: env_spec_w32.h:667
#define UDF_VCB_IC_HW_RO
Definition: udf_common.h:502
#define UDF_CCB_NOT_FROM_ZONE
Definition: struct.h:175
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _UDFContextControlBlock * PtrUDFCCB
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
NTSTATUS NTAPI UDFPhSendIOCTL(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN OverrideVerify, OUT PIO_STATUS_BLOCK Iosb OPTIONAL)
Definition: env_spec.cpp:511
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define CdMediaClass_DVDpR
Definition: cdrw_usr.h:750
#define FsRtlEnterFileSystem
ULONG Esp
Definition: nt_native.h:1479
#define UDF_DIRTY_VOLUME_BEHAVIOR
Definition: udf_reg.h:221
VOID WCacheRelease__(IN PW_CACHE Cache)
#define CdMediaClass_DVDR
Definition: cdrw_usr.h:748
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
#define UDF_DEFAULT_TREE_FLUSH_TIMEOUT
Definition: udffs.h:96
ULONG Eip
Definition: nt_native.h:1476
#define IRP_MJ_QUERY_SECURITY
struct _Entry Entry
Definition: kefuncs.h:640
struct _UDFObjectName * PtrUDFObjectName
#define UDF_IRP_CONTEXT_NOT_TOP_LEVEL
Definition: struct.h:390
#define UDF_ALLOW_UPDATE_TIMES_ACCS_UCHG_DIR
Definition: udf_reg.h:170
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define UDF_DEFAULT_READAHEAD_GRAN
Definition: udffs.h:55
#define FsRtlExitFileSystem
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define MediaType_UnknownSize_CDRW
Definition: cdrw_hw.h:2485
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
#define UDF_ALLOW_WRITE_IN_RO_DIR
Definition: udf_reg.h:167
_In_ PIRP Irp
Definition: csq.h:116
#define __fastcall
Definition: sync.c:41
#define UDFSetFlag(Flag, Value)
Definition: udffs.h:191
BOOLEAN RegTGetDwordValue(IN HKEY hRootKey, IN PCWSTR RegistryPath, IN PCWSTR Name, IN PULONG pUlong)
Definition: regtools.cpp:99
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
NTSTATUS UDFCommonSetSecurity(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
unsigned int uint32
Definition: types.h:32
#define IRP_MJ_SET_SECURITY
unsigned char * PUCHAR
Definition: retypes.h:3
VOID __fastcall UDFReleaseCCB(PtrUDFCCB Ccb)
Definition: misc.cpp:768
#define UDF_NODE_TYPE_FCB
Definition: struct.h:60
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
char CHAR
Definition: xmlstorage.h:175
ULONG Ecx
Definition: nt_native.h:1467
#define UDF_IRP_CONTEXT_NOT_FROM_ZONE
Definition: struct.h:399
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
LONG NTSTATUS
Definition: precomp.h:26
ULONG MyReallocPool__(PCHAR addr, ULONG len, PCHAR *pnewaddr, ULONG newlen)
Definition: mem_tools.h:224
#define ICB_FLAG_AD_LONG
Definition: ecma_167.h:494
#define UDF_FCB_MT
Definition: struct.h:241
#define IOCTL_CDRW_GET_DEVICE_NAME
Definition: cdrw_usr.h:121
#define CdMediaClass_DVDRW
Definition: cdrw_usr.h:749
uint32 IrpContextFlags
Definition: struct.h:416
ULONG WCacheBlocksPerFrameSh
Definition: udf_common.h:623
#define UDF_VCB_IC_IGNORE_SEQUENTIAL_IO
Definition: udf_common.h:506
#define IRP_MJ_SET_VOLUME_INFORMATION
#define UDF_UPDATE_TIMES_ATTR
Definition: udf_reg.h:149
VOID UDFReadRegKeys(PVCB Vcb, BOOLEAN Update, BOOLEAN UseCfg)
Definition: misc.cpp:1780
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define UDF_INSTANT_COMPAT_ALLOC_DESCS
Definition: udf_reg.h:179
#define UDF_FCB_INITIALIZED_CCB_LIST_RESOURCE
Definition: struct.h:316
#define UDF_VCB_IC_UPDATE_UCHG_DIR_ACCESS_TIME
Definition: udf_common.h:500
#define ExIsFullZone(Zone)
Definition: exfuncs.h:329
enum _UDFFSD_MEDIA_TYPE UDFFSD_MEDIA_TYPE
Definition: cdstruc.h:504
VOID UDFReleaseVCB(PVCB Vcb)
Definition: misc.cpp:2137
ULONG WCacheFramesToKeepFree
Definition: udf_common.h:624
#define UDF_DIR_PACK_THRESHOLD_NAME
Definition: udf_reg.h:110
#define UDF_USE_EJECT_BUTTON
Definition: udf_reg.h:236
#define UDF_VCB_IC_UPDATE_DIR_READ
Definition: udf_common.h:498
PDEVICE_OBJECT NTAPI IoGetDeviceToVerify(IN PETHREAD Thread)
Definition: util.c:328
NTSTATUS NTAPI UDFCommonDirControl(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: dircntrl.cpp:127
#define UDF_IRP_CONTEXT_FLAG_DISABLE_POPUPS
Definition: struct.h:391
uint16_t * PWCHAR
Definition: typedefs.h:54
#define UDF_CACHE_SIZE_MULTIPLIER
Definition: udf_reg.h:197
PDEVICE_OBJECT TargetDeviceObject
Definition: struct.h:374
BOOLEAN NTAPI IoIsOperationSynchronous(IN PIRP Irp)
Definition: irp.c:1882
PtrUDFCCB UDFAllocateCCB(VOID)
Definition: misc.cpp:707
#define InsertTailList(ListHead, Entry)
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
NTSTATUS UDFCommonSetVolInfo(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: volinfo.cpp:663
#define REG_USEEXTENDEDFE_NAME
Definition: udf_reg.h:98
#define UDF_IRP_CONTEXT_CAN_BLOCK
Definition: struct.h:385
#define UDF_DEFAULT_SPARSE_THRESHOLD
Definition: udffs.h:56
#define UDF_FE_CHARGE_SDIR_NAME
Definition: udf_reg.h:116
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define UDF_VCB_FLAGS_REMOVABLE_MEDIA
Definition: udf_common.h:468
#define UDF_PART_DAMAGED_RO
Definition: udfpubl.h:121
PVOID ExceptionAddress
Definition: compat.h:199
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
_SEH2_TRY
Definition: create.c:4250
#define UDF_W2K_COMPAT_ALLOC_DESCS
Definition: udf_reg.h:173
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK SpinLock
Definition: iofuncs.h:798
ULONG UDFRegCheckParameterValue(IN PUNICODE_STRING RegistryPath, IN PCWSTR Name, IN PUNICODE_STRING PtrVolumePath, IN PCWSTR DefaultPath, IN ULONG DefValue)
Definition: misc.cpp:2225
#define UDF_DEFAULT_FE_CHARGE
Definition: udf_rel.h:500
ULONG UDFGetRegParameter(IN PVCB Vcb, IN PCWSTR Name, IN ULONG DefValue)
Definition: misc.cpp:1986
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
VOID WCacheFlushAll__(IN PW_CACHE Cache, IN PVOID Context)
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD ExceptionCode
Definition: compat.h:196
#define UDF_W2K_COMPAT_VLABEL
Definition: udf_reg.h:176
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define UDF_VCB_IC_DIRTY_RO
Definition: udf_common.h:516
#define UDF_VCB_FLAGS_VOLUME_READ_ONLY
Definition: udf_common.h:463
#define UDF_BM_FLUSH_PERIOD_NAME
Definition: udf_reg.h:119
#define UDF_NO_SPARE_BEHAVIOR
Definition: udf_reg.h:218
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define UDF_VCB_IC_W2K_COMPAT_VLABEL
Definition: udf_common.h:517
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
__inline VOID UDFReleaseFCB(PtrUDFFCB Fcb)
Definition: protos.h:620
struct _UDFFileControlBlock * PtrUDFFCB
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
NTSTATUS UDFCommonRead(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: read.cpp:229
#define IO_DISK_INCREMENT
Definition: iotypes.h:567
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UDF_PART_DAMAGED_BEHAVIOR
Definition: udf_reg.h:215
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
#define UDF_VCB_FLAGS_VCB_INITIALIZED
Definition: udf_common.h:465
struct _VCB VCB
#define FILESYSTEM_STATISTICS_TYPE_NTFS
Definition: winioctl.h:672
#define UDF_DEFAULT_DIR_PACK_THRESHOLD
Definition: udffs.h:50
UDFFSD_MEDIA_TYPE UDFGetMediaClass(PVCB Vcb)
Definition: misc.cpp:1694
#define a
Definition: ke_i.h:78
struct _FCB::@684::@687 Fcb
short SHORT
Definition: pedump.c:59
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define CdMediaClass_DVDROM
Definition: cdrw_usr.h:746
ULONG Esi
Definition: nt_native.h:1464
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
struct NameRec_ * Name
Definition: cdprocs.h:464
ULONG(* ptrUDFGetParameter)(IN PVCB Vcb, IN PCWSTR Name, IN ULONG DefValue)
Definition: misc.cpp:1754
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
NTSTATUS UDFWCacheErrorHandler(IN PVOID Context, IN PWCACHE_ERROR_CONTEXT ErrorInfo)
Definition: misc.cpp:2583
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
#define UDF_PART_DAMAGED_RW
Definition: udfpubl.h:120
struct UDF_MEDIA_CLASS_NAMES UDFMediaClassName[]
Definition: udfinit.cpp:29
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define ICB_FLAG_AD_SHORT
Definition: ecma_167.h:493
smooth NULL
Definition: ftsmooth.c:416
ULONG Edx
Definition: nt_native.h:1466
NTSTATUS UDFInitializeIrpContextLite(OUT PtrUDFIrpContextLite *IrpContextLite, IN PtrUDFIrpContext IrpContext, IN PtrUDFFCB Fcb)
Definition: misc.cpp:2457
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1619
#define IoCompleteRequest
Definition: irp.c:1240
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
BOOLEAN UDFAcquireResourceSharedWithCheck(IN PERESOURCE Resource)
Definition: misc.cpp:2556
#define UDF_CHAINED_IO
Definition: udf_reg.h:200
WCHAR * ObjectName
Definition: ntfs.h:508
#define MediaType_UnknownSize_CDR
Definition: cdrw_hw.h:2475
ULONG Ebx
Definition: nt_native.h:1465
uint32 IrpContextFlags
Definition: struct.h:364
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
NTSTATUS SavedExceptionCode
Definition: struct.h:376
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define UDF_VCB_IC_UPDATE_ACCESS_TIME
Definition: udf_common.h:493
uint32 NodeType
Definition: struct.h:75
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define ULL(a, b)
Definition: format_msg.c:27
#define UDF_IGNORE_SEQUENTIAL_IO
Definition: udf_reg.h:212
ULONG ContextFlags
Definition: compat.h:331
GLuint GLfloat * val
Definition: glext.h:7180
NTSTATUS UDFInitializeVCB(IN PDEVICE_OBJECT PtrVolumeDeviceObject, IN PDEVICE_OBJECT PtrTargetDeviceObject, IN PVPB PtrVPB)
Definition: misc.cpp:1411
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
#define DbgFreePool
Definition: env_spec_w32.h:334
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:113
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define UDF_VCB_IC_FORCE_HW_RO
Definition: udf_common.h:505
#define ExIsResourceAcquiredShared
Definition: exfuncs.h:348
NTSTATUS NTAPI ExInitializeZone(PZONE_HEADER Zone, ULONG BlockSize, PVOID InitialSegment, ULONG InitialSegmentSize)
Definition: zone.c:105
NTSTATUS UDFInitializeZones(VOID)
Definition: misc.cpp:41
#define UDF_VCB_IC_OS_NATIVE_DOS_NAME
Definition: udf_common.h:503
#define UDF_HANDLE_HW_RO
Definition: udf_reg.h:182
#define CdMediaClass_HD_DVDROM
Definition: cdrw_usr.h:758
#define CdMediaClass_CDRW
Definition: cdrw_usr.h:745
PCONTEXT ContextRecord
Definition: rtltypes.h:197
#define UDF_VCB_IC_UPDATE_MODIFY_TIME
Definition: udf_common.h:494
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
VOID UDFCleanupVCB(IN PVCB Vcb)
Definition: fscntrl.cpp:1428
#define UDFTouch(a)
Definition: env_spec_w32.h:303
#define CONTEXT_CONTROL
Definition: compat.h:265
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:201
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
BOOLEAN NTAPI MmIsThisAnNtAsSystem(VOID)
Definition: mmsup.c:246
#define CdMediaClass_HD_DVDRAM
Definition: cdrw_usr.h:759
#define UDF_VCB_IC_SOFT_RO
Definition: udf_common.h:514
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define try_return(S)
Definition: cdprocs.h:2189
#define UDF_DEFAULT_FSP_THREAD_PER_CPU
Definition: udffs.h:98
#define UDF_SHOW_BLANK_CD
Definition: udf_reg.h:224
#define UDF_VCB_IC_UPDATE_ARCH_BIT
Definition: udf_common.h:496
#define Vcb
Definition: cdprocs.h:1425
#define UDF_NODE_TYPE_CCB
Definition: struct.h:59
#define UDFDeleteResource(Resource)
Definition: env_spec_w32.h:663
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define UDF_NO_EJECT_PERIOD_NAME
Definition: udf_reg.h:128
MM_SYSTEMSIZE NTAPI MmQuerySystemSize(VOID)
Definition: mmsup.c:257
#define MyFreePool__(addr)
Definition: mem_tools.h:152
Definition: xml2sdb.h:79
#define UDF_FE_CHARGE_NAME
Definition: udf_reg.h:113
#define UDF_VCB_IC_W2K_COMPAT_ALLOC_DESCS
Definition: udf_common.h:501
#define BrutePoint()
Definition: env_spec_w32.h:504
ULONG UDFGetCfgParameter(IN PVCB Vcb, IN PCWSTR Name, IN ULONG DefValue)
Definition: misc.cpp:2000
#define UDF_VCB_IC_INSTANT_COMPAT_ALLOC_DESCS
Definition: udf_common.h:513
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
NTSTATUS UDFCommonFileInfo(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: fileinfo.cpp:114
NTSTATUS UDFCommonCleanup(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: cleanup.cpp:126
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define UDF_COMPARE_BEFORE_WRITE
Definition: udf_reg.h:194
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
NTSTATUS UDFCommonClose(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: close.cpp:137
#define UDF_DEFAULT_UID_NAME
Definition: udf_reg.h:104
BOOLEAN __fastcall UDFIsIrpTopLevel(PIRP Irp)
Definition: misc.cpp:228
#define REG_DEFALLOCMODE_NAME
Definition: udf_reg.h:101
#define CdMediaClass_CDR
Definition: cdrw_usr.h:744
#define UDF_DATA_FLAGS_ZONES_INITIALIZED
Definition: udf_common.h:635
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID RegTCloseKeyHandle(IN HKEY hKey)
Definition: regtools.cpp:86
WCHAR * PWCH
Definition: ntbasedef.h:417
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
ULONG WCacheMaxBlocks
Definition: udf_common.h:622
UDFIdentifier NodeIdentifier
Definition: struct.h:91
VOID NTAPI UDFCommonDispatch(IN PVOID Context)
Definition: misc.cpp:1208
unsigned char UCHAR
Definition: xmlstorage.h:181
#define REG_DEFAULT_UNKNOWN
Definition: udf_reg.h:75
ULONG WCacheMaxFrames
Definition: udf_common.h:621
#define UDF_VERIFY_ON_WRITE_NAME
Definition: udf_reg.h:146
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
static __inline PVOID ExFreeToZone(IN PZONE_HEADER Zone, IN PVOID Block)
Definition: exfuncs.h:297
struct _UDFIrpContext * PtrUDFIrpContext
static const WCHAR L[]
Definition: oid.c:1250
void delay(unsigned msec)
Definition: i386rtl.c:32
#define UDF_UPDATE_DIR_TIMES_ATTR_R
Definition: udf_reg.h:164
UDFData UDFGlobalData
Definition: udfinit.cpp:25
NTSTATUS UDFPerformVerify(IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN PDEVICE_OBJECT DeviceToVerify)
Definition: verfysup.cpp:472
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
#define UDF_VCB_IC_WAIT_CD_SPINUP
Definition: udf_common.h:519
#define UDF_VCB_IC_FORCE_WRITE_THROUGH
Definition: udf_common.h:504
GLenum GLsizei len
Definition: glext.h:6722
uint32 NodeSize
Definition: struct.h:76
#define UDF_VCB_IC_UPDATE_ATTR_TIME
Definition: udf_common.h:495
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define NOTHING
Definition: env_spec_w32.h:461
struct _VCB * PVCB
Definition: fatstruc.h:553
Definition: typedefs.h:117
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
ULONG Eax
Definition: nt_native.h:1468
#define UDFQuadAlign(Value)
Definition: udffs.h:196
UNICODE_STRING SavedRegPath
Definition: udf_common.h:615
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
#define UDF_DEFAULT_GID_NAME
Definition: udf_reg.h:107
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
struct _UDFIrpContextLite UDFIrpContextLite
#define UDF_HANDLE_SOFT_RO
Definition: udf_reg.h:185
UDFIdentifier NodeIdentifier
Definition: struct.h:363
PtrUDFObjectName UDFAllocateObjectName(VOID)
Definition: misc.cpp:611
uint8 MinorFunction
Definition: struct.h:368
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1250
NTSTATUS UDFPostRequest(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: misc.cpp:1128
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
#define UDF_FSP_THREAD_PER_CPU_NAME
Definition: udf_reg.h:131
_SEH2_END
Definition: create.c:4424
uint32 ObjectNameFlags
Definition: struct.h:92
#define CdMediaClass_HD_DVDR
Definition: cdrw_usr.h:760
#define InterlockedIncrement
Definition: armddk.h:53
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
NTSTATUS UDFCommonCreate(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: create.cpp:186
unsigned short USHORT
Definition: pedump.c:61
uint32 UDFFlags
Definition: udf_common.h:627
PDEVICE_OBJECT RealDevice
Definition: struct.h:414
VOID __fastcall UDFCleanUpCCB(PtrUDFCCB Ccb)
Definition: misc.cpp:805
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define CdMediaClass_CDROM
Definition: cdrw_usr.h:743
#define UDF_FORCE_WRITE_THROUGH_NAME
Definition: udf_reg.h:206
_SEH2_FINALLY
Definition: create.c:4395
VOID UDFInitializeIrpContextFromLite(OUT PtrUDFIrpContext *IrpContext, IN PtrUDFIrpContextLite IrpContextLite)
Definition: misc.cpp:2419
UDFIdentifier NodeIdentifier
Definition: struct.h:406
#define CdMediaClass_BDR
Definition: cdrw_usr.h:757
#define REG_NAMELESS_DEV
Definition: udf_reg.h:85
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
NTSTATUS UDFCommonWrite(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: write.cpp:112
VOID __fastcall UDFCleanUpFCB(PtrUDFFCB Fcb)
Definition: misc.cpp:908
VOID UDFUpdateCompatOption(PVCB Vcb, BOOLEAN Update, BOOLEAN UseCfg, PCWSTR Name, ULONG Flag, BOOLEAN Default)
Definition: misc.cpp:1761
PtrUDFFCB UDFAllocateFCB(VOID)
Definition: misc.cpp:854
#define CdMediaClass_BDRE
Definition: cdrw_usr.h:756
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define CdMediaClass_DVDpRW
Definition: cdrw_usr.h:751
#define UDF_READAHEAD_GRAN_NAME
Definition: udf_reg.h:134
ULONG TreeLength
Definition: struct.h:415
#define IRP_MJ_CLEANUP
VOID NTAPI FsRtlNotifyInitializeSync(IN PNOTIFY_SYNC *NotifySync)
Definition: notify.c:1561
Definition: iotypes.h:166
#define OUT
Definition: typedefs.h:39
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:108
#define MediaType_UnknownSize_Unknown
Definition: cdrw_hw.h:2495
FILE_SYSTEM_STATISTICS * PFILE_SYSTEM_STATISTICS
Definition: fatstruc.h:608
#define UDF_NTAS_MULTIPLE
Definition: struct.h:437
_UDFFileControlBlock * Fcb
Definition: struct.h:408
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
ULONG NTAPI ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1658
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define UDF_SPARSE_THRESHOLD_NAME
Definition: udf_reg.h:143
DWORD ExceptionFlags
Definition: compat.h:197
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
PVCB Vcb
Definition: cdstruc.h:939
#define UDF_FORCE_HW_RO
Definition: udf_reg.h:209
BOOLEAN UDFAcquireResourceExclusiveWithCheck(IN PERESOURCE Resource)
Definition: misc.cpp:2529
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define UDF_OS_NATIVE_DOS_NAME
Definition: udf_reg.h:203
#define UDF_FLUSH_MEDIA
Definition: udf_reg.h:188
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
VOID NTAPI IoRaiseHardError(IN PIRP Irp, IN PVPB Vpb, IN PDEVICE_OBJECT RealDeviceObject)
Definition: error.c:656
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:196
VOID NTAPI FsRtlNotifyUninitializeSync(IN PNOTIFY_SYNC *NotifySync)
Definition: notify.c:1639
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define UDF_UPDATE_ATTR_ARCH
Definition: udf_reg.h:158
#define UDF_NODE_TYPE_IRP_CONTEXT
Definition: struct.h:62
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:229
struct _FILE_SYSTEM_STATISTICS FILE_SYSTEM_STATISTICS
#define UDF_UPDATE_TIMES_MOD
Definition: udf_reg.h:152
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define UDF_TREE_FLUSH_PERIOD_NAME
Definition: udf_reg.h:122
NTSTATUS UDFCommonQueryVolInfo(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: volinfo.cpp:149
DWORD NumberParameters
Definition: compat.h:200
_In_ PFCB Fcb
Definition: cdprocs.h:151
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
VOID UDFDestroyZones(VOID)
Definition: misc.cpp:177
#define UDF_IRP_CONTEXT_EXCEPTION
Definition: struct.h:387
NTSTATUS NTAPI UDFQuerySetEA(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: misc.cpp:2484
NTSTATUS RegTGetKeyHandle(IN HKEY hRootKey, IN PWCHAR KeyName, OUT HKEY *hKey)
Definition: regtools.cpp:59
return STATUS_SUCCESS
Definition: btrfs.c:2725
#define UDF_WAIT_CD_SPINUP
Definition: udf_reg.h:227
IoMarkIrpPending(Irp)
uint8 MajorFunction
Definition: struct.h:366
signed int * PLONG
Definition: retypes.h:5
static SERVICE_STATUS status
Definition: service.c:31
#define UDF_NODE_TYPE_IRP_CONTEXT_LITE
Definition: struct.h:66
NTSTATUS UDFCommonGetSecurity(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
#define APC_LEVEL
Definition: env_spec_w32.h:695
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define UDF_NO_UPDATE_PERIOD_NAME
Definition: udf_reg.h:125
struct _UDFNTRequiredFCB * PtrUDFNTRequiredFCB
#define FSP_PER_DEVICE_THRESHOLD
Definition: workque.c:30
ULONG Ebp
Definition: nt_native.h:1475
base of all file and directory entries
Definition: entries.h:82
#define UDF_OBJ_NAME_NOT_FROM_ZONE
Definition: struct.h:97
#define CONTEXT_INTEGER
Definition: compat.h:266
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1664
VOID NTAPI IoSetDeviceToVerify(IN PETHREAD Thread, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:304
struct _UDFIrpContextLite * PtrUDFIrpContextLite
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define CdMediaClass_HD_DVDRW
Definition: cdrw_usr.h:761
#define UDF_CACHE_BAD_VDS
Definition: udf_reg.h:233
ULONG Edi
Definition: nt_native.h:1463
#define STATUS_CANT_WAIT
Definition: ntstatus.h:438
#define UDF_VCB_IC_UPDATE_DIR_WRITE
Definition: udf_common.h:497
ULONG UDFIsResourceAcquired(IN PERESOURCE Resource)
Definition: misc.cpp:2518
Definition: ps.c:97