Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

udfdata.c File Reference

#include "UdfProcs.h"

Go to the source code of this file.

Defines

#define BugCheckFileId   (UDFS_BUG_CHECK_UDFDATA)
#define Dbg   (UDFS_DEBUG_LEVEL_UDFDATA)

Functions

NTSTATUS UdfFsdDispatch (IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject, IN PIRP Irp)
LONG UdfExceptionFilter (IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
NTSTATUS UdfProcessException (IN PIRP_CONTEXT IrpContext OPTIONAL, IN PIRP Irp, IN NTSTATUS ExceptionCode)
VOID UdfCompleteRequest (IN PIRP_CONTEXT IrpContext OPTIONAL, IN PIRP Irp OPTIONAL, IN NTSTATUS Status)
VOID UdfSetThreadContext (IN PIRP_CONTEXT IrpContext, IN PTHREAD_CONTEXT ThreadContext)
BOOLEAN UdfFastIoCheckIfPossible (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN BOOLEAN CheckForReadOperation, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
ULONG UdfSerial32 (IN PCHAR Buffer, IN ULONG ByteCount)
VOID UdfInitializeCrc16 (ULONG Polynomial)
USHORT UdfComputeCrc16 (PUCHAR Buffer, ULONG ByteCount)
USHORT UdfComputeCrc16Uni (PWCHAR Buffer, ULONG CharCount)
ULONG UdfHighBit (ULONG Word)

Variables

UDF_DATA UdfData
FAST_IO_DISPATCH UdfFastIoDispatch
WCHAR UdfUnicodeSelfArray [] = { L'.' }
WCHAR UdfUnicodeParentArray [] = { L'.', L'.' }
UNICODE_STRING UdfUnicodeDirectoryNames []
CHAR UdfCS0IdentifierArray []
STRING UdfCS0Identifier
CHAR UdfDomainIdentifierArray []
STRING UdfDomainIdentifier
CHAR UdfVirtualPartitionDomainIdentifierArray []
STRING UdfVirtualPartitionDomainIdentifier
CHAR UdfVatTableIdentifierArray []
STRING UdfVatTableIdentifier
CHAR UdfSparablePartitionDomainIdentifierArray []
STRING UdfSparablePartitionDomainIdentifier
CHAR UdfSparingTableIdentifierArray []
STRING UdfSparingTableIdentifier
CHAR UdfNSR02IdentifierArray [] = NSR_PART_CONTID_NSR02
STRING UdfNSR02Identifier
PARSE_KEYVALUE VsdIdentParseTable []
PARSE_KEYVALUE NsrPartContIdParseTable []
NPAGED_LOOKASIDE_LIST UdfFcbNonPagedLookasideList
NPAGED_LOOKASIDE_LIST UdfIrpContextLookasideList
PAGED_LOOKASIDE_LIST UdfCcbLookasideList
PAGED_LOOKASIDE_LIST UdfFcbIndexLookasideList
PAGED_LOOKASIDE_LIST UdfFcbDataLookasideList
PAGED_LOOKASIDE_LIST UdfLcbLookasideList
PUSHORT UdfCrcTable


Define Documentation

#define BugCheckFileId   (UDFS_BUG_CHECK_UDFDATA)
 

Definition at line 30 of file udfdata.c.

#define Dbg   (UDFS_DEBUG_LEVEL_UDFDATA)
 

Definition at line 36 of file udfdata.c.


Function Documentation

VOID UdfCompleteRequest IN PIRP_CONTEXT IrpContext  OPTIONAL,
IN PIRP Irp  OPTIONAL,
IN NTSTATUS  Status
 

Definition at line 809 of file udfdata.c.

References ASSERT_OPTIONAL_IRP, ASSERT_OPTIONAL_IRP_CONTEXT, FALSE, FlagOn, _IRP::Flags, IO_CD_ROM_INCREMENT, IoCompleteRequest, _IRP::IoStatus, Irp, IRP_INPUT_OPERATION, NT_ERROR, Status, and UdfCleanupIrpContext().

Referenced by UdfCommonCleanup(), UdfCommonClose(), UdfCommonCreate(), UdfCommonDevControl(), UdfCommonDirControl(), UdfCommonFsControl(), UdfCommonLockControl(), UdfCommonPnp(), UdfCommonQueryInfo(), UdfCommonQueryVolInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfCompleteMdl(), UdfDismountVolume(), UdfDvdReadStructure(), UdfDvdTransferKey(), UdfFsdDispatch(), UdfFspClose(), UdfFspDispatch(), UdfInvalidateVolumes(), UdfIsPathnameValid(), UdfIsVolumeDirty(), UdfIsVolumeMounted(), UdfLockVolume(), UdfMountVolume(), UdfNotifyChangeDirectory(), UdfOplockComplete(), UdfOplockRequest(), UdfPerformVerify(), UdfPnpCancelRemove(), UdfPnpQueryRemove(), UdfPnpRemove(), UdfPnpSurpriseRemove(), UdfProcessException(), UdfQueryDirectory(), UdfQueueClose(), UdfUnlockVolume(), UdfUserFsctl(), and UdfVerifyVolume().

00817 : 00818 00819 This routine completes a Irp and cleans up the IrpContext. Either or 00820 both of these may not be specified. 00821 00822 Arguments: 00823 00824 Irp - Supplies the Irp being processed. 00825 00826 Status - Supplies the status to complete the Irp with 00827 00828 Return Value: 00829 00830 None. 00831 00832 --*/ 00833 00834 { 00835 ASSERT_OPTIONAL_IRP_CONTEXT( IrpContext ); 00836 ASSERT_OPTIONAL_IRP( Irp ); 00837 00838 // 00839 // Cleanup the IrpContext if passed in here. 00840 // 00841 00842 if (ARGUMENT_PRESENT( IrpContext )) { 00843 00844 UdfCleanupIrpContext( IrpContext, FALSE ); 00845 } 00846 00847 // 00848 // If we have an Irp then complete the irp. 00849 // 00850 00851 if (ARGUMENT_PRESENT( Irp )) { 00852 00853 // 00854 // Clear the information field in case we have used this Irp 00855 // internally. 00856 // 00857 00858 if (NT_ERROR( Status ) && 00859 FlagOn( Irp->Flags, IRP_INPUT_OPERATION )) { 00860 00861 Irp->IoStatus.Information = 0; 00862 } 00863 00864 Irp->IoStatus.Status = Status; 00865 IoCompleteRequest( Irp, IO_CD_ROM_INCREMENT ); 00866 } 00867 00868 return; 00869 }

USHORT UdfComputeCrc16 PUCHAR  Buffer,
ULONG  ByteCount
 

Definition at line 1146 of file udfdata.c.

References Buffer, UdfCrcTable, and USHORT.

01153 : 01154 01155 This routine generates a 16 bit CRC of the input buffer in accordance 01156 with the precomputed CRC table. 01157 01158 Arguments: 01159 01160 Buffer - Pointer to the buffer to generate the CRC for. 01161 01162 ByteCount - Number of bytes in the buffer. 01163 01164 Return Value: 01165 01166 USHORT - The 16bit CRC 01167 01168 --*/ 01169 01170 { 01171 USHORT Crc = 0; 01172 01173 // 01174 // All CRC code was devised by Don P. Mitchell of AT&T Bell Laboratories 01175 // and Ned W. Rhodes of Software Systems Group. It has been published in 01176 // "Design and Validation of Computer Protocols", Prentice Hall, Englewood 01177 // Cliffs, NJ, 1991, Chapter 3, ISBN 0-13-539925-4. 01178 // 01179 // Copyright is held by AT&T. 01180 // 01181 // AT&T gives permission for the free use of the source code. 01182 // 01183 01184 while (ByteCount-- > 0) { 01185 01186 Crc = UdfCrcTable[((Crc >> 8) ^ *Buffer++) & 0xff] ^ (Crc << 8); 01187 } 01188 01189 return Crc; 01190 }

USHORT UdfComputeCrc16Uni PWCHAR  Buffer,
ULONG  CharCount
 

Definition at line 1194 of file udfdata.c.

References Buffer, UdfCrcTable, and USHORT.

Referenced by UdfGenerate8dot3Name(), and UdfRenderNameToLegalUnicode().

01201 : 01202 01203 This routine generates a 16 bit CRC of the input buffer in accordance 01204 with the precomputed CRC table. 01205 01206 It performs a byte-order independent crc (hi then lo). This is a bit 01207 suspect, but is called for in the specification. 01208 01209 Arguments: 01210 01211 Buffer - Pointer to the buffer to generate the CRC for. 01212 01213 ShortCount - Number of wide characters in the buffer. 01214 01215 Return Value: 01216 01217 USHORT - The 16bit CRC 01218 01219 --*/ 01220 01221 { 01222 USHORT Crc = 0; 01223 01224 // 01225 // Byte order independent CRC, hi byte to low byte per character. 01226 // 01227 01228 while (CharCount-- > 0) { 01229 01230 Crc = UdfCrcTable[((Crc >> 8) ^ (*Buffer >> 8)) & 0xff] ^ (Crc << 8); 01231 Crc = UdfCrcTable[((Crc >> 8) ^ (*Buffer++ & 0xff)) & 0xff] ^ (Crc << 8); 01232 } 01233 01234 return Crc; 01235 }

LONG UdfExceptionFilter IN PIRP_CONTEXT  IrpContext,
IN PEXCEPTION_POINTERS  ExceptionPointer
 

Definition at line 448 of file udfdata.c.

References ASSERT_OPTIONAL_IRP_CONTEXT, Dbg, DebugTrace, EXCEPTION_EXECUTE_HANDLER, FALSE, FsRtlIsNtstatusExpected(), NTSTATUS(), TRUE, and UdfBugCheck.

Referenced by UdfFindFileSetDescriptor(), UdfFsdDispatch(), UdfFspDispatch(), UdfOpenObjectByFileId(), UdfPerformVerify(), and UdfProcessException().

00455 : 00456 00457 This routine is used to decide whether we will handle a raised exception 00458 status. If UDFS explicitly raised an error then this status is already 00459 in the IrpContext. We choose which is the correct status code and 00460 either indicate that we will handle the exception or bug-check the system. 00461 00462 Arguments: 00463 00464 ExceptionCode - Supplies the exception code to being checked. 00465 00466 Return Value: 00467 00468 ULONG - returns EXCEPTION_EXECUTE_HANDLER or bugchecks 00469 00470 --*/ 00471 00472 { 00473 NTSTATUS ExceptionCode; 00474 BOOLEAN TestStatus = TRUE; 00475 00476 ASSERT_OPTIONAL_IRP_CONTEXT( IrpContext ); 00477 00478 ExceptionCode = ExceptionPointer->ExceptionRecord->ExceptionCode; 00479 00480 DebugTrace(( 0, Dbg, 00481 "UdfExceptionFilter: %08x (exr %08x cxr %08x)\n", 00482 ExceptionCode, 00483 ExceptionPointer->ExceptionRecord, 00484 ExceptionPointer->ContextRecord )); 00485 00486 00487 // 00488 // If the exception is STATUS_IN_PAGE_ERROR, get the I/O error code 00489 // from the exception record. 00490 // 00491 00492 if ((ExceptionCode == STATUS_IN_PAGE_ERROR) && 00493 (ExceptionPointer->ExceptionRecord->NumberParameters >= 3)) { 00494 00495 ExceptionCode = (NTSTATUS) ExceptionPointer->ExceptionRecord->ExceptionInformation[2]; 00496 } 00497 00498 // 00499 // If there is an Irp context then check which status code to use. 00500 // 00501 00502 if (ARGUMENT_PRESENT( IrpContext )) { 00503 00504 if (IrpContext->ExceptionStatus == STATUS_SUCCESS) { 00505 00506 // 00507 // Store the real status into the IrpContext. 00508 // 00509 00510 IrpContext->ExceptionStatus = ExceptionCode; 00511 00512 } else { 00513 00514 // 00515 // No need to test the status code if we raised it ourselves. 00516 // 00517 00518 TestStatus = FALSE; 00519 } 00520 } 00521 00522 // 00523 // Bug check if this status is not supported. 00524 // 00525 00526 if (TestStatus && !FsRtlIsNtstatusExpected( ExceptionCode )) { 00527 00528 UdfBugCheck( (ULONG_PTR) ExceptionPointer->ExceptionRecord, 00529 (ULONG_PTR) ExceptionPointer->ContextRecord, 00530 (ULONG_PTR) ExceptionPointer->ExceptionRecord->ExceptionAddress ); 00531 00532 } 00533 00534 return EXCEPTION_EXECUTE_HANDLER; 00535 }

BOOLEAN UdfFastIoCheckIfPossible IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN BOOLEAN  Wait,
IN ULONG  LockKey,
IN BOOLEAN  CheckForReadOperation,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject
 

Definition at line 972 of file udfdata.c.

References PAGED_CODE, and TRUE.

Referenced by UdfInitializeGlobalData().

00985 : 00986 00987 This routine checks if fast i/o is possible for a read/write operation 00988 00989 Arguments: 00990 00991 FileObject - Supplies the file object used in the query 00992 00993 FileOffset - Supplies the starting byte offset for the read/write operation 00994 00995 Length - Supplies the length, in bytes, of the read/write operation 00996 00997 Wait - Indicates if we can wait 00998 00999 LockKey - Supplies the lock key 01000 01001 CheckForReadOperation - Indicates if this is a check for a read or write 01002 operation 01003 01004 IoStatus - Receives the status of the operation if our return value is 01005 FastIoReturnError 01006 01007 Return Value: 01008 01009 BOOLEAN - TRUE if fast I/O is possible and FALSE if the caller needs 01010 to take the long route. 01011 01012 --*/ 01013 01014 { 01015 PAGED_CODE(); 01016 01017 return TRUE; 01018 }

NTSTATUS UdfFsdDispatch IN PVOLUME_DEVICE_OBJECT  VolumeDeviceObject,
IN PIRP  Irp
 

Definition at line 218 of file udfdata.c.

References ASSERT, ASSERT_OPTIONAL_IRP, CanFsdWait, FALSE, FlagOn, _IRP_CONTEXT::Flags, FsRtlEnterFileSystem, FsRtlExitFileSystem, IoGetCurrentIrpStackLocation, IoGetTopLevelIrp(), Irp, IRP_CONTEXT_FLAG_MORE_PROCESSING, IRP_MJ_CLEANUP, IRP_MJ_CLOSE, IRP_MJ_CREATE, IRP_MJ_DEVICE_CONTROL, IRP_MJ_DIRECTORY_CONTROL, IRP_MJ_FILE_SYSTEM_CONTROL, IRP_MJ_LOCK_CONTROL, IRP_MJ_PNP, IRP_MJ_QUERY_INFORMATION, IRP_MJ_QUERY_VOLUME_INFORMATION, IRP_MJ_READ, IRP_MJ_SET_INFORMATION, IRP_MN_COMPLETE, _IRP_CONTEXT::MajorFunction, _IRP_CONTEXT::MinorFunction, NTSTATUS(), NULL, SafeNodeType, SetFlag, Status, THREAD_CONTEXT, ThreadContext, _IRP_CONTEXT::TopLevel, TRUE, UdfCleanupIrpContext(), UdfCommonCleanup(), UdfCommonClose(), UdfCommonCreate(), UdfCommonDevControl(), UdfCommonDirControl(), UdfCommonFsControl(), UdfCommonLockControl(), UdfCommonPnp(), UdfCommonQueryInfo(), UdfCommonQueryVolInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfCompleteMdl(), UdfCompleteRequest(), UdfCreateIrpContext(), UdfExceptionFilter(), UdfProcessException(), UDFS_NTC_IRP_CONTEXT, and UdfSetThreadContext().

00225 : 00226 00227 This is the driver entry to all of the Fsd dispatch points. 00228 00229 Conceptually the Io routine will call this routine on all requests 00230 to the file system. We case on the type of request and invoke the 00231 correct handler for this type of request. There is an exception filter 00232 to catch any exceptions in the UDFS code as well as the UDFS process 00233 exception routine. 00234 00235 This routine allocates and initializes the IrpContext for this request as 00236 well as updating the top-level thread context as necessary. We may loop 00237 in this routine if we need to retry the request for any reason. The 00238 status code STATUS_CANT_WAIT is used to indicate this. Suppose the disk 00239 in the drive has changed. An Fsd request will proceed normally until it 00240 recognizes this condition. STATUS_VERIFY_REQUIRED is raised at that point 00241 and the exception code will handle the verify and either return 00242 STATUS_CANT_WAIT or STATUS_PENDING depending on whether the request was 00243 posted. 00244 00245 Arguments: 00246 00247 VolumeDeviceObject - Supplies the volume device object for this request 00248 00249 Irp - Supplies the Irp being processed 00250 00251 Return Value: 00252 00253 NTSTATUS - The FSD status for the IRP 00254 00255 --*/ 00256 00257 { 00258 THREAD_CONTEXT ThreadContext; 00259 PIRP_CONTEXT IrpContext = NULL; 00260 BOOLEAN Wait; 00261 00262 #ifdef UDF_SANITY 00263 PVOID PreviousTopLevel; 00264 #endif 00265 00266 NTSTATUS Status; 00267 00268 KIRQL SaveIrql = KeGetCurrentIrql(); 00269 00270 ASSERT_OPTIONAL_IRP( Irp ); 00271 00272 FsRtlEnterFileSystem(); 00273 00274 #ifdef UDF_SANITY 00275 PreviousTopLevel = IoGetTopLevelIrp(); 00276 #endif 00277 00278 // 00279 // Loop until this request has been completed or posted. 00280 // 00281 00282 do { 00283 00284 // 00285 // Use a try-except to handle the exception cases. 00286 // 00287 00288 try { 00289 00290 // 00291 // If the IrpContext is NULL then this is the first pass through 00292 // this loop. 00293 // 00294 00295 if (IrpContext == NULL) { 00296 00297 // 00298 // Decide if this request is waitable an allocate the IrpContext. 00299 // If the file object in the stack location is NULL then this 00300 // is a mount which is always waitable. Otherwise we look at 00301 // the file object flags. 00302 // 00303 00304 if (IoGetCurrentIrpStackLocation( Irp )->FileObject == NULL) { 00305 00306 Wait = TRUE; 00307 00308 } else { 00309 00310 Wait = CanFsdWait( Irp ); 00311 } 00312 00313 IrpContext = UdfCreateIrpContext( Irp, Wait ); 00314 00315 // 00316 // Update the thread context information. 00317 // 00318 00319 UdfSetThreadContext( IrpContext, &ThreadContext ); 00320 00321 #ifdef UDF_SANITY 00322 ASSERT( !UdfTestTopLevel || 00323 SafeNodeType( IrpContext->TopLevel ) == UDFS_NTC_IRP_CONTEXT ); 00324 #endif 00325 00326 // 00327 // Otherwise cleanup the IrpContext for the retry. 00328 // 00329 00330 } else { 00331 00332 // 00333 // Set the MORE_PROCESSING flag to make sure the IrpContext 00334 // isn't inadvertently deleted here. Then cleanup the 00335 // IrpContext to perform the retry. 00336 // 00337 00338 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); 00339 UdfCleanupIrpContext( IrpContext, FALSE ); 00340 } 00341 00342 // 00343 // Case on the major irp code. 00344 // 00345 00346 switch (IrpContext->MajorFunction) { 00347 00348 case IRP_MJ_CLEANUP : 00349 00350 Status = UdfCommonCleanup( IrpContext, Irp ); 00351 break; 00352 00353 case IRP_MJ_CLOSE : 00354 00355 Status = UdfCommonClose( IrpContext, Irp ); 00356 break; 00357 00358 case IRP_MJ_CREATE : 00359 00360 Status = UdfCommonCreate( IrpContext, Irp ); 00361 break; 00362 00363 case IRP_MJ_DEVICE_CONTROL : 00364 00365 Status = UdfCommonDevControl( IrpContext, Irp ); 00366 break; 00367 00368 case IRP_MJ_DIRECTORY_CONTROL : 00369 00370 Status = UdfCommonDirControl( IrpContext, Irp ); 00371 break; 00372 00373 case IRP_MJ_FILE_SYSTEM_CONTROL : 00374 00375 Status = UdfCommonFsControl( IrpContext, Irp ); 00376 break; 00377 00378 case IRP_MJ_LOCK_CONTROL : 00379 00380 Status = UdfCommonLockControl( IrpContext, Irp ); 00381 break; 00382 00383 case IRP_MJ_PNP : 00384 00385 Status = UdfCommonPnp( IrpContext, Irp ); 00386 break; 00387 00388 case IRP_MJ_QUERY_INFORMATION : 00389 00390 Status = UdfCommonQueryInfo( IrpContext, Irp ); 00391 break; 00392 00393 case IRP_MJ_QUERY_VOLUME_INFORMATION : 00394 00395 Status = UdfCommonQueryVolInfo( IrpContext, Irp ); 00396 break; 00397 00398 case IRP_MJ_READ : 00399 00400 // 00401 // If this is an Mdl complete request, don't go through 00402 // common read. 00403 // 00404 00405 if (FlagOn( IrpContext->MinorFunction, IRP_MN_COMPLETE )) { 00406 00407 Status = UdfCompleteMdl( IrpContext, Irp ); 00408 00409 } else { 00410 00411 Status = UdfCommonRead( IrpContext, Irp ); 00412 } 00413 00414 break; 00415 00416 case IRP_MJ_SET_INFORMATION : 00417 00418 Status = UdfCommonSetInfo( IrpContext, Irp ); 00419 break; 00420 00421 default : 00422 00423 Status = STATUS_INVALID_DEVICE_REQUEST; 00424 UdfCompleteRequest( IrpContext, Irp, Status ); 00425 } 00426 00427 } except( UdfExceptionFilter( IrpContext, GetExceptionInformation() )) { 00428 00429 Status = UdfProcessException( IrpContext, Irp, GetExceptionCode() ); 00430 } 00431 00432 } while (Status == STATUS_CANT_WAIT); 00433 00434 #ifdef UDF_SANITY 00435 ASSERT( !UdfTestTopLevel || 00436 (PreviousTopLevel == IoGetTopLevelIrp()) ); 00437 #endif 00438 00439 FsRtlExitFileSystem(); 00440 00441 ASSERT( SaveIrql == KeGetCurrentIrql( )); 00442 00443 return Status; 00444 }

ULONG UdfHighBit ULONG  Word  ) 
 

Definition at line 1239 of file udfdata.c.

References Offset.

Referenced by UdfInitializeVcb(), and UdfMountVolume().

01245 : 01246 01247 This routine discovers the highest set bit of the input word. It is 01248 equivalent to the integer logarithim base 2. 01249 01250 Arguments: 01251 01252 Word - word to check 01253 01254 Return Value: 01255 01256 Bit offset of highest set bit. If no bit is set, return is zero. 01257 01258 --*/ 01259 01260 { 01261 ULONG Offset = 31; 01262 ULONG Mask = (ULONG)(1 << 31); 01263 01264 if (Word == 0) { 01265 01266 return 0; 01267 } 01268 01269 while ((Word & Mask) == 0) { 01270 01271 Offset--; 01272 Mask >>= 1; 01273 } 01274 01275 return Offset; 01276 }

VOID UdfInitializeCrc16 ULONG  Polynomial  ) 
 

Definition at line 1083 of file udfdata.c.

References FsRtlAllocatePoolWithTag, n, PUSHORT, TAG_CRC_TABLE, UdfCrcTable, UdfPagedPool, and USHORT.

Referenced by UdfInitializeGlobalData().

01089 : 01090 01091 This routine generates the 16bit CRC Table to be used in CRC calculation. 01092 01093 Arguments: 01094 01095 Polynomial - Starting seed for the generation 01096 01097 Return Value: 01098 01099 None 01100 01101 --*/ 01102 01103 { 01104 ULONG n, i, Crc; 01105 01106 // 01107 // All CRC code was devised by Don P. Mitchell of AT&T Bell Laboratories 01108 // and Ned W. Rhodes of Software Systems Group. It has been published in 01109 // "Design and Validation of Computer Protocols", Prentice Hall, Englewood 01110 // Cliffs, NJ, 1991, Chapter 3, ISBN 0-13-539925-4. 01111 // 01112 // Copyright is held by AT&T. 01113 // 01114 // AT&T gives permission for the free use of the source code. 01115 // 01116 01117 UdfCrcTable = (PUSHORT) FsRtlAllocatePoolWithTag( UdfPagedPool, 01118 256 * sizeof(USHORT), 01119 TAG_CRC_TABLE ); 01120 01121 for (n = 0; n < 256; n++) { 01122 01123 Crc = n << 8; 01124 01125 for (i = 0; i < 8; i++) { 01126 01127 if(Crc & 0x8000) { 01128 01129 Crc = (Crc << 1) ^ Polynomial; 01130 01131 } else { 01132 01133 Crc <<= 1; 01134 } 01135 01136 Crc &= 0xffff; 01137 } 01138 01139 UdfCrcTable[n] = (USHORT) Crc; 01140 } 01141 }

NTSTATUS UdfProcessException IN PIRP_CONTEXT IrpContext  OPTIONAL,
IN PIRP  Irp,
IN NTSTATUS  ExceptionCode
 

Definition at line 539 of file udfdata.c.

References APC_LEVEL, ASSERT, ASSERT_IRP, ASSERT_OPTIONAL_IRP_CONTEXT, ClearFlag, FlagOn, IoGetCurrentIrpStackLocation, IoGetDeviceToVerify(), IoIsErrorUserInduced, IoMarkIrpPending, IoRaiseHardError(), IoSetDeviceToVerify(), _IRP::IoStatus, Irp, IRP_CONTEXT_FLAG_DISABLE_POPUPS, IRP_CONTEXT_FLAG_FORCE_POST, IRP_CONTEXT_FLAG_MORE_PROCESSING, IRP_CONTEXT_FLAG_TOP_LEVEL, NULL, PsGetCurrentThread, _IRP::Tail, UdfCompleteRequest(), UdfExceptionFilter(), UdfFsdPostRequest(), and UdfPerformVerify().

Referenced by UdfFsdDispatch(), UdfFspDispatch(), and UdfPerformVerify().

00547 : 00548 00549 This routine processes an exception. It either completes the request 00550 with the exception status in the IrpContext, sends this off to the Fsp 00551 workque or causes it to be retried in the current thread if a verification 00552 is needed. 00553 00554 If the volume needs to be verified (STATUS_VERIFY_REQUIRED) and we can 00555 do the work in the current thread we will translate the status code 00556 to STATUS_CANT_WAIT to indicate that we need to retry the request. 00557 00558 Arguments: 00559 00560 Irp - Supplies the Irp being processed 00561 00562 ExceptionCode - Supplies the normalized exception status being handled 00563 00564 Return Value: 00565 00566 NTSTATUS - Returns the results of either posting the Irp or the 00567 saved completion status. 00568 00569 --*/ 00570 00571 { 00572 PDEVICE_OBJECT Device; 00573 PVPB Vpb; 00574 PETHREAD Thread; 00575 00576 ASSERT_OPTIONAL_IRP_CONTEXT( IrpContext ); 00577 ASSERT_IRP( Irp ); 00578 00579 // 00580 // If there is not an irp context, then complete the request with the 00581 // current status code. 00582 // 00583 00584 if (!ARGUMENT_PRESENT( IrpContext )) { 00585 00586 UdfCompleteRequest( NULL, Irp, ExceptionCode ); 00587 return ExceptionCode; 00588 } 00589 00590 // 00591 // Get the real exception status from the IrpContext. 00592 // 00593 00594 ExceptionCode = IrpContext->ExceptionStatus; 00595 00596 // 00597 // If we are not a top level request then we just complete the request 00598 // with the current status code. 00599 // 00600 00601 if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL )) { 00602 00603 UdfCompleteRequest( IrpContext, Irp, ExceptionCode ); 00604 00605 return ExceptionCode; 00606 } 00607 00608 // 00609 // Check if we are posting this request. One of the following must be true 00610 // if we are to post a request. 00611 // 00612 // - Status code is STATUS_CANT_WAIT and the request is asynchronous 00613 // or we are forcing this to be posted. 00614 // 00615 // - Status code is STATUS_VERIFY_REQUIRED and we are at APC level 00616 // or higher. Can't wait for IO in the verify path in this case. 00617 // 00618 // Set the MORE_PROCESSING flag in the IrpContext to keep if from being 00619 // deleted if this is a retryable condition. 00620 // 00621 // Note: Children of UdfFsdPostRequest() can raise. 00622 // 00623 00624 try { 00625 00626 if (ExceptionCode == STATUS_CANT_WAIT) { 00627 00628 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_FORCE_POST )) { 00629 00630 ExceptionCode = UdfFsdPostRequest( IrpContext, Irp ); 00631 } 00632 00633 } else if (ExceptionCode == STATUS_VERIFY_REQUIRED) { 00634 00635 if (KeGetCurrentIrql() >= APC_LEVEL) { 00636 00637 ExceptionCode = UdfFsdPostRequest( IrpContext, Irp ); 00638 } 00639 } 00640 } 00641 except (UdfExceptionFilter( IrpContext, GetExceptionInformation())) { 00642 00643 ExceptionCode = GetExceptionCode(); 00644 } 00645 00646 // 00647 // If we posted the request or our caller will retry then just return here. 00648 // 00649 00650 if ((ExceptionCode == STATUS_PENDING) || 00651 (ExceptionCode == STATUS_CANT_WAIT)) { 00652 00653 return ExceptionCode; 00654 } 00655 00656 ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); 00657 00658 // 00659 // Store this error into the Irp for posting back to the Io system. 00660 // 00661 00662 Irp->IoStatus.Status = ExceptionCode; 00663 00664 if (IoIsErrorUserInduced( ExceptionCode )) { 00665 00666 // 00667 // Check for the various error conditions that can be caused by, 00668 // and possibly resolved my the user. 00669 // 00670 00671 if (ExceptionCode == STATUS_VERIFY_REQUIRED) { 00672 00673 // 00674 // Now we are at the top level file system entry point. 00675 // 00676 // If we have already posted this request then the device to 00677 // verify is in the original thread. Find this via the Irp. 00678 // 00679 00680 Device = IoGetDeviceToVerify( Irp->Tail.Overlay.Thread ); 00681 IoSetDeviceToVerify( Irp->Tail.Overlay.Thread, NULL ); 00682 00683 // 00684 // If there is no device in that location then check in the 00685 // current thread. 00686 // 00687 00688 if (Device == NULL) { 00689 00690 Device = IoGetDeviceToVerify( PsGetCurrentThread() ); 00691 IoSetDeviceToVerify( PsGetCurrentThread(), NULL ); 00692 00693 ASSERT( Device != NULL ); 00694 00695 // 00696 // Let's not BugCheck just because the driver screwed up. 00697 // 00698 00699 if (Device == NULL) { 00700 00701 ExceptionCode = STATUS_DRIVER_INTERNAL_ERROR; 00702 00703 UdfCompleteRequest( IrpContext, Irp, ExceptionCode ); 00704 00705 return ExceptionCode; 00706 } 00707 } 00708 00709 // 00710 // CdPerformVerify() will do the right thing with the Irp. 00711 // If we return STATUS_CANT_WAIT then the current thread 00712 // can retry the request. 00713 // 00714 00715 return UdfPerformVerify( IrpContext, Irp, Device ); 00716 } 00717 00718 // 00719 // The other user induced conditions generate an error unless 00720 // they have been disabled for this request. 00721 // 00722 00723 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS )) { 00724 00725 UdfCompleteRequest( IrpContext, Irp, ExceptionCode ); 00726 00727 return ExceptionCode; 00728 00729 } else { 00730 00731 // 00732 // Generate a pop-up 00733 // 00734 00735 if (IoGetCurrentIrpStackLocation( Irp )->FileObject != NULL) { 00736 00737 Vpb = IoGetCurrentIrpStackLocation( Irp )->FileObject->Vpb; 00738 00739 } else { 00740 00741 Vpb = NULL; 00742 } 00743 00744 // 00745 // The device to verify is either in my thread local storage 00746 // or that of the thread that owns the Irp. 00747 // 00748 00749 Thread = Irp->Tail.Overlay.Thread; 00750 Device = IoGetDeviceToVerify( Thread ); 00751 00752 if (Device == NULL) { 00753 00754 Thread = PsGetCurrentThread(); 00755 Device = IoGetDeviceToVerify( Thread ); 00756 00757 ASSERT( Device != NULL ); 00758 00759 // 00760 // Let's not BugCheck just because the driver screwed up. 00761 // 00762 00763 if (Device == NULL) { 00764 00765 UdfCompleteRequest( IrpContext, Irp, ExceptionCode ); 00766 00767 return ExceptionCode; 00768 } 00769 } 00770 00771 // 00772 // This routine actually causes the pop-up. It usually 00773 // does this by queuing an APC to the callers thread, 00774 // but in some cases it will complete the request immediately, 00775 // so it is very important to IoMarkIrpPending() first. 00776 // 00777 00778 IoMarkIrpPending( Irp ); 00779 IoRaiseHardError( Irp, Vpb, Device ); 00780 00781 // 00782 // We will be handing control back to the caller here, so 00783 // reset the saved device object. 00784 // 00785 00786 IoSetDeviceToVerify( Thread, NULL ); 00787 00788 // 00789 // The Irp will be completed by Io or resubmitted. In either 00790 // case we must clean up the IrpContext here. 00791 // 00792 00793 UdfCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); 00794 return STATUS_PENDING; 00795 } 00796 } 00797 00798 // 00799 // This is just a run of the mill error. 00800 // 00801 00802 UdfCompleteRequest( IrpContext, Irp, ExceptionCode ); 00803 00804 return ExceptionCode; 00805 }

ULONG UdfSerial32 IN PCHAR  Buffer,
IN ULONG  ByteCount
 

Definition at line 1022 of file udfdata.c.

References Buffer, PAGED_CODE, and SerialId.

Referenced by UdfUpdateVolumeSerialNumber().

01029 : 01030 01031 This routine is called to generate a 32 bit serial number. This is 01032 done by doing four separate checksums into an array of bytes and 01033 then treating the bytes as a ULONG. 01034 01035 Arguments: 01036 01037 Buffer - Pointer to the buffer to generate the ID for. 01038 01039 ByteCount - Number of bytes in the buffer. 01040 01041 Return Value: 01042 01043 ULONG - The 32 bit serial number. 01044 01045 --*/ 01046 01047 { 01048 union { 01049 UCHAR Bytes[4]; 01050 ULONG SerialId; 01051 } Checksum; 01052 01053 PAGED_CODE(); 01054 01055 // 01056 // Initialize the serial number. 01057 // 01058 01059 Checksum.SerialId = 0; 01060 01061 // 01062 // Continue while there are more bytes to use. 01063 // 01064 01065 while (ByteCount--) { 01066 01067 // 01068 // Increment this sub-checksum. 01069 // 01070 01071 Checksum.Bytes[ByteCount & 0x3] += *(Buffer++); 01072 } 01073 01074 // 01075 // Return the checksums as a ULONG. 01076 // 01077 01078 return Checksum.SerialId; 01079 }

VOID UdfSetThreadContext IN PIRP_CONTEXT  IrpContext,
IN PTHREAD_CONTEXT  ThreadContext
 

Definition at line 873 of file udfdata.c.

References ASSERT_IRP_CONTEXT, FlagOn, IoGetStackLimits(), IoGetTopLevelIrp(), IoSetTopLevelIrp(), IRP_CONTEXT_FLAG_TOP_LEVEL, IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS, LongOffsetPtr, NULL, PAGED_CODE, PTHREAD_CONTEXT, SetFlag, ThreadContext, _THREAD_CONTEXT::TopLevelIrpContext, _THREAD_CONTEXT::Udfs, and UDFS_SIGNATURE.

Referenced by UdfFsdDispatch(), UdfFspClose(), and UdfFspDispatch().

00880 : 00881 00882 This routine is called at each Fsd/Fsp entry point set up the IrpContext 00883 and thread local storage to track top level requests. If there is 00884 not a Udfs context in the thread local storage then we use the input one. 00885 Otherwise we use the one already there. This routine also updates the 00886 IrpContext based on the state of the top-level context. 00887 00888 If the TOP_LEVEL flag in the IrpContext is already set when we are called 00889 then we force this request to appear top level. 00890 00891 Arguments: 00892 00893 ThreadContext - Address on stack for local storage if not already present. 00894 00895 ForceTopLevel - We force this request to appear top level regardless of 00896 any previous stack value. 00897 00898 Return Value: 00899 00900 None 00901 00902 --*/ 00903 00904 { 00905 PTHREAD_CONTEXT CurrentThreadContext; 00906 ULONG_PTR StackTop; 00907 ULONG_PTR StackBottom; 00908 00909 PAGED_CODE(); 00910 00911 ASSERT_IRP_CONTEXT( IrpContext ); 00912 00913 // 00914 // Get the current top-level irp out of the thread storage. 00915 // If NULL then this is the top-level request. 00916 // 00917 00918 CurrentThreadContext = (PTHREAD_CONTEXT) IoGetTopLevelIrp(); 00919 00920 if (CurrentThreadContext == NULL) { 00921 00922 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL ); 00923 } 00924 00925 // 00926 // Initialize the input context unless we are using the current 00927 // thread context block. We use the new block if our caller 00928 // specified this or the existing block is invalid. 00929 // 00930 // The following must be true for the current to be a valid Udfs context. 00931 // 00932 // Structure must lie within current stack. 00933 // Address must be ULONG aligned. 00934 // Udfs signature must be present. 00935 // 00936 // If this is not a valid Udfs context then use the input thread 00937 // context and store it in the top level context. 00938 // 00939 00940 IoGetStackLimits( &StackTop, &StackBottom); 00941 00942 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL ) || 00943 (((ULONG_PTR) CurrentThreadContext > StackBottom - sizeof( THREAD_CONTEXT )) || 00944 ((ULONG_PTR) CurrentThreadContext <= StackTop) || 00945 LongOffsetPtr( CurrentThreadContext ) || 00946 (CurrentThreadContext->Udfs != UDFS_SIGNATURE))) { 00947 00948 ThreadContext->Udfs = UDFS_SIGNATURE; 00949 ThreadContext->SavedTopLevelIrp = (PIRP) CurrentThreadContext; 00950 ThreadContext->TopLevelIrpContext = IrpContext; 00951 IoSetTopLevelIrp( (PIRP) ThreadContext ); 00952 00953 IrpContext->TopLevel = IrpContext; 00954 IrpContext->ThreadContext = ThreadContext; 00955 00956 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS ); 00957 00958 // 00959 // Otherwise use the IrpContext in the thread context. 00960 // 00961 00962 } else { 00963 00964 IrpContext->TopLevel = CurrentThreadContext->TopLevelIrpContext; 00965 } 00966 00967 return; 00968 }


Variable Documentation

PARSE_KEYVALUE NsrPartContIdParseTable[]
 

Initial value:

Definition at line 176 of file udfdata.c.

PAGED_LOOKASIDE_LIST UdfCcbLookasideList
 

Definition at line 193 of file udfdata.c.

Referenced by UdfInitializeGlobalData().

PUSHORT UdfCrcTable
 

Definition at line 202 of file udfdata.c.

Referenced by UdfComputeCrc16(), UdfComputeCrc16Uni(), and UdfInitializeCrc16().

STRING UdfCS0Identifier
 

Initial value:

Definition at line 94 of file udfdata.c.

Referenced by UdfFindVolumeDescriptors().

CHAR UdfCS0IdentifierArray[]
 

Initial value:

{ 'O', 'S', 'T', 'A', , 'C', 'o', 'm', 'p', 'r', 'e', 's', 's', 'e', 'd', , 'U', 'n', 'i', 'c', 'o', 'd', 'e' }

Definition at line 90 of file udfdata.c.

UDF_DATA UdfData
 

Definition at line 42 of file udfdata.c.

Referenced by UdfCommonRead(), UdfCreateInternalStream(), UdfCreateIrpContext(), UdfFspClose(), UdfInitializeGlobalData(), UdfInitializeVcb(), UdfInvalidateVolumes(), UdfIsRemount(), UdfMountVolume(), UdfQueueClose(), UdfRemoveClose(), and UdfScanForDismountedVcb().

STRING UdfDomainIdentifier
 

Initial value:

Definition at line 104 of file udfdata.c.

Referenced by UdfFindVolumeDescriptors().

CHAR UdfDomainIdentifierArray[]
 

Initial value:

{ '*', 'O', 'S', 'T', 'A', , 'U', 'D', 'F', , 'C', 'o', 'm', 'p', 'l', 'i', 'a', 'n', 't' }

Definition at line 100 of file udfdata.c.

FAST_IO_DISPATCH UdfFastIoDispatch
 

Definition at line 43 of file udfdata.c.

Referenced by UdfInitializeGlobalData().

PAGED_LOOKASIDE_LIST UdfFcbDataLookasideList
 

Definition at line 195 of file udfdata.c.

Referenced by UdfInitializeGlobalData().

PAGED_LOOKASIDE_LIST UdfFcbIndexLookasideList
 

Definition at line 194 of file udfdata.c.

Referenced by UdfInitializeGlobalData().

NPAGED_LOOKASIDE_LIST UdfFcbNonPagedLookasideList
 

Definition at line 190 of file udfdata.c.

Referenced by UdfInitializeGlobalData().

NPAGED_LOOKASIDE_LIST UdfIrpContextLookasideList
 

Definition at line 191 of file udfdata.c.

Referenced by UdfCleanupIrpContext(), UdfCreateIrpContext(), and UdfInitializeGlobalData().

PAGED_LOOKASIDE_LIST UdfLcbLookasideList
 

Definition at line 196 of file udfdata.c.

Referenced by UdfInitializeGlobalData(), UdfInsertPrefix(), and UdfRemovePrefix().

STRING UdfNSR02Identifier
 

Initial value:

Definition at line 153 of file udfdata.c.

Referenced by UdfFindVolumeDescriptors().

CHAR UdfNSR02IdentifierArray[] = NSR_PART_CONTID_NSR02
 

Definition at line 151 of file udfdata.c.

STRING UdfSparablePartitionDomainIdentifier
 

Initial value:

Definition at line 135 of file udfdata.c.

Referenced by UdfInitializePcb().

CHAR UdfSparablePartitionDomainIdentifierArray[]
 

Initial value:

{ '*', 'U', 'D', 'F', , 'S', 'p', 'a', 'r', 'a', 'b', 'l', 'e', , 'P', 'a', 'r', 't', 'i', 't', 'i', 'o', 'n' }

Definition at line 131 of file udfdata.c.

STRING UdfSparingTableIdentifier
 

Initial value:

Definition at line 145 of file udfdata.c.

Referenced by UdfLoadSparingTables().

CHAR UdfSparingTableIdentifierArray[]
 

Initial value:

{ '*', 'U', 'D', 'F', , 'S', 'p', 'a', 'r', 'i', 'n', 'g', , 'T', 'a', 'b', 'l', 'e' }

Definition at line 141 of file udfdata.c.

UNICODE_STRING UdfUnicodeDirectoryNames[]
 

Initial value:

Definition at line 81 of file udfdata.c.

Referenced by UdfInitializeEnumeration(), and UdfUpdateDirNames().

WCHAR UdfUnicodeParentArray[] = { L'.', L'.' }
 

Definition at line 79 of file udfdata.c.

WCHAR UdfUnicodeSelfArray[] = { L'.' }
 

Definition at line 78 of file udfdata.c.

STRING UdfVatTableIdentifier
 

Initial value:

Definition at line 125 of file udfdata.c.

Referenced by UdfUpdateVcbPhase0().

CHAR UdfVatTableIdentifierArray[]
 

Initial value:

{ '*', 'U', 'D', 'F', , 'V', 'i', 'r', 't', 'u', 'a', 'l', , 'A', 'l', 'l', 'o', 'c', , 'T', 'b', 'l' }

Definition at line 120 of file udfdata.c.

STRING UdfVirtualPartitionDomainIdentifier
 

Initial value:

Definition at line 114 of file udfdata.c.

Referenced by UdfInitializePcb().

CHAR UdfVirtualPartitionDomainIdentifierArray[]
 

Initial value:

{ '*', 'U', 'D', 'F', , 'V', 'i', 'r', 't', 'u', 'a', 'l', , 'P', 'a', 'r', 't', 'i', 't', 'i', 'o', 'n' }

Definition at line 110 of file udfdata.c.

PARSE_KEYVALUE VsdIdentParseTable[]
 

Initial value:

Definition at line 163 of file udfdata.c.


Generated on Sat May 15 19:45:50 2004 for test by doxygen 1.3.7