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

udfs_rec.c File Reference

#include "fs_rec.h"
#include "udfs_rec.h"

Go to the source code of this file.

Defines

#define Dbg   (FSREC_DEBUG_LEVEL_UDFS)

Functions

NTSTATUS UdfsRecFsControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
BOOLEAN IsUdfsVolume (IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize)
ULONG UdfsFindInParseTable (IN PPARSE_KEYVALUE ParseTable, IN PCHAR Id, IN ULONG MaxIdLen)

Variables

PARSE_KEYVALUE VsdIdentParseTable []


Define Documentation

#define Dbg   (FSREC_DEBUG_LEVEL_UDFS)
 

Definition at line 33 of file udfs_rec.c.


Function Documentation

BOOLEAN IsUdfsVolume IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  SectorSize
 

Definition at line 157 of file udfs_rec.c.

References Dbg, DebugTrace, ExFreePool(), FALSE, FsRecReadBlock(), NULL, Offset, PAGED_CODE, PVSD_GENERIC, SectorAlignN, SectorSize, TRUE, UdfsFindInParseTable(), VRA_BOUNDARY_LOCATION, VSD_GENERIC, VSD_LENGTH_IDENT, VsdIdentBEA01, VsdIdentBOOT2, VsdIdentCD001, VsdIdentCDROM, VsdIdentCDW01, VsdIdentCDW02, VsdIdentNSR01, VsdIdentNSR02, VsdIdentParseTable, and VsdIdentTEA01.

Referenced by UdfsRecFsControl().

00164 : 00165 00166 This routine walks the Volume Recognition Sequence to determine 00167 whether this volume contains an NSR02 (ISO 13346 Section 4) image. 00168 00169 Note: this routine is pretty much diked out of UdfsRecognizeVolume 00170 in the real filesystem, modulo fitting it into the fs recognizer. 00171 00172 Arguments: 00173 00174 DeviceObject - device we are checking 00175 00176 SectorSize - size of a physical sector on this device 00177 00178 Return Value: 00179 00180 Boolean TRUE if we found NSR02, FALSE otherwise. 00181 00182 --*/ 00183 00184 { 00185 BOOLEAN FoundNSR = FALSE; 00186 00187 BOOLEAN FoundBEA = FALSE; 00188 BOOLEAN Resolved = FALSE; 00189 00190 PVSD_GENERIC VolumeStructureDescriptor = NULL; 00191 ULONGLONG Offset = SectorAlignN( SectorSize, VRA_BOUNDARY_LOCATION ); 00192 00193 PAGED_CODE(); 00194 00195 DebugTrace(( +1, Dbg, 00196 "IsUdfsVolume, DevObj %08x SectorSize %08x\n", 00197 DeviceObject, 00198 SectorSize )); 00199 00200 while (!Resolved) { 00201 00202 if (!FsRecReadBlock( DeviceObject, 00203 (PLARGE_INTEGER)&Offset, 00204 sizeof(VSD_GENERIC), 00205 SectorSize, 00206 (PVOID) &VolumeStructureDescriptor, 00207 NULL )) { 00208 00209 break; 00210 } 00211 00212 // 00213 // Now check the type of the descriptor. All ISO 13346 VSDs are 00214 // of Type 0, 9660 PVDs are Type 1, 9660 SVDs are Type 2, and 9660 00215 // terminating descriptors are Type 255. 00216 // 00217 00218 if (VolumeStructureDescriptor->Type == 0) { 00219 00220 // 00221 // In order to properly recognize the volume, we must know all of the 00222 // Structure identifiers in ISO 13346 so that we can terminate if a 00223 // badly formatted (or, shockingly, non 13346) volume is presented to us. 00224 // 00225 00226 switch (UdfsFindInParseTable( VsdIdentParseTable, 00227 VolumeStructureDescriptor->Ident, 00228 VSD_LENGTH_IDENT )) { 00229 case VsdIdentBEA01: 00230 00231 // 00232 // Only one BEA may exist and its version must be 1 (2/9.2.3) 00233 // 00234 00235 DebugTrace(( 0, Dbg, "IsUdfsVolume, got a BEA01\n" )); 00236 00237 00238 if ((FoundBEA && 00239 DebugTrace(( 0, Dbg, 00240 "IsUdfsVolume, ... but it is a duplicate!\n" ))) || 00241 00242 (VolumeStructureDescriptor->Version != 1 && 00243 DebugTrace(( 0, Dbg, 00244 "IsUdfsVolume, ... but it has a wacky version number %02x != 1!\n", 00245 VolumeStructureDescriptor->Version )))) { 00246 00247 Resolved = TRUE; 00248 break; 00249 } 00250 00251 FoundBEA = TRUE; 00252 break; 00253 00254 case VsdIdentTEA01: 00255 00256 // 00257 // If we reach the TEA it must be the case that we don't recognize 00258 // 00259 00260 DebugTrace(( 0, Dbg, "IsUdfsVolume, got a TEA01\n" )); 00261 00262 Resolved = TRUE; 00263 break; 00264 00265 case VsdIdentNSR02: 00266 00267 // 00268 // We recognize NSR02 version 1 embedded after a BEA (3/9.1.3). For 00269 // simplicity we will not bother being a complete nitpick and check 00270 // for a bounding TEA, although we will be optimistic in the case where 00271 // we fail to match the version. 00272 // 00273 00274 DebugTrace(( 0, Dbg, "IsUdfsVolume, got an NSR02\n" )); 00275 00276 if ((FoundBEA || 00277 !DebugTrace(( 0, Dbg, "IsUdfsVolume, ... but we haven't seen a BEA01 yet!\n" ))) && 00278 00279 (VolumeStructureDescriptor->Version == 1 || 00280 !DebugTrace(( 0, Dbg, "IsUdfsVolume, ... but it has a wacky version number %02x != 1\n", 00281 VolumeStructureDescriptor->Version )))) { 00282 00283 FoundNSR = Resolved = TRUE; 00284 break; 00285 } 00286 00287 break; 00288 00289 case VsdIdentCD001: 00290 case VsdIdentCDW01: 00291 case VsdIdentNSR01: 00292 case VsdIdentCDW02: 00293 case VsdIdentBOOT2: 00294 00295 DebugTrace(( 0, Dbg, "IsUdfsVolume, got a valid but uninteresting 13346 descriptor\n" )); 00296 00297 // 00298 // Valid but uninteresting (to us) descriptors 00299 // 00300 00301 break; 00302 00303 default: 00304 00305 DebugTrace(( 0, Dbg, "IsUdfsVolume, got an invalid 13346 descriptor\n" )); 00306 00307 // 00308 // Stumbling across something we don't know, it must be that this 00309 // is not a valid 13346 image 00310 // 00311 00312 Resolved = TRUE; 00313 break; 00314 00315 } 00316 00317 } else if (!FoundBEA && (VolumeStructureDescriptor->Type < 3 || 00318 VolumeStructureDescriptor->Type == 255)) { 00319 00320 DebugTrace(( 0, Dbg, "IsUdfsVolume, got a 9660 descriptor\n" )); 00321 00322 // 00323 // Only HSG (CDROM) and 9660 (CD001) are possible, and they are only legal 00324 // before the ISO 13346 BEA/TEA extent. By design, an ISO 13346 VSD precisely 00325 // overlaps a 9660 PVD/SVD in the appropriate fields. 00326 // 00327 // Note that we aren't being strict about the structure of the 9660 descriptors 00328 // since that really isn't very interesting. We care more about the 13346. 00329 // 00330 // 00331 00332 switch (UdfsFindInParseTable( VsdIdentParseTable, 00333 VolumeStructureDescriptor->Ident, 00334 VSD_LENGTH_IDENT )) { 00335 case VsdIdentCDROM: 00336 case VsdIdentCD001: 00337 00338 DebugTrace(( 0, Dbg, "IsUdfsVolume, ... seems we have 9660 here\n" )); 00339 00340 // 00341 // Note to our caller that we seem to have ISO 9660 here 00342 // 00343 00344 break; 00345 00346 default: 00347 00348 DebugTrace(( 0, Dbg, "IsUdfsVolume, ... but it looks wacky\n" )); 00349 00350 // 00351 // This probably was a false alert, but in any case there is nothing 00352 // on this volume for us. 00353 // 00354 00355 Resolved = TRUE; 00356 break; 00357 } 00358 00359 } else { 00360 00361 // 00362 // Something else must be recorded on this volume. 00363 // 00364 00365 DebugTrace(( 0, Dbg, "IsUdfsVolume, got an unrecognizeable descriptor, probably not 13346/9660\n" )); 00366 break; 00367 } 00368 00369 // 00370 // Align our next read with the sector following the current descriptor 00371 // 00372 00373 Offset += SectorAlignN( SectorSize, sizeof(VSD_GENERIC) ); 00374 } 00375 00376 DebugTrace(( -1, Dbg, "IsUdfsVolume -> %c\n", ( FoundNSR ? 'T' : 'F' ))); 00377 00378 // 00379 // Free up our temporary buffer 00380 // 00381 00382 if (VolumeStructureDescriptor) { 00383 00384 ExFreePool( VolumeStructureDescriptor ); 00385 } 00386 00387 return FoundNSR; 00388 }

ULONG UdfsFindInParseTable IN PPARSE_KEYVALUE  ParseTable,
IN PCHAR  Id,
IN ULONG  MaxIdLen
 

Definition at line 392 of file udfs_rec.c.

References NULL, and PAGED_CODE.

Referenced by IsUdfsVolume().

00400 : 00401 00402 This routine walks a table of string key/value information for a match of the 00403 input Id. MaxIdLen can be set to get a prefix match. 00404 00405 Arguments: 00406 00407 Table - This is the table being searched. 00408 00409 Id - Key value. 00410 00411 MaxIdLen - Maximum possible length of Id. 00412 00413 Return Value: 00414 00415 Value of matching entry, or the terminating (NULL) entry's value. 00416 00417 --*/ 00418 00419 { 00420 PAGED_CODE(); 00421 00422 while (ParseTable->Key != NULL) { 00423 00424 if (RtlEqualMemory(ParseTable->Key, Id, MaxIdLen)) { 00425 00426 break; 00427 } 00428 00429 ParseTable++; 00430 } 00431 00432 return ParseTable->Value; 00433 }

NTSTATUS UdfsRecFsControl IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp
 

Definition at line 60 of file udfs_rec.c.

References FsRecGetDeviceSectorSize(), FsRecLoadFileSystem(), IO_NO_INCREMENT, IoCompleteRequest, IoGetCurrentIrpStackLocation, _IRP::IoStatus, Irp, IRP_MN_LOAD_FILE_SYSTEM, IRP_MN_MOUNT_VOLUME, IsUdfsVolume(), L, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), PAGED_CODE, and _IO_STACK_LOCATION::Parameters.

Referenced by FsRecFsControl().

00067 : 00068 00069 This function performs the mount and driver reload functions for this mini- 00070 file system recognizer driver. 00071 00072 Arguments: 00073 00074 DeviceObject - Pointer to this driver's device object. 00075 00076 Irp - Pointer to the I/O Request Packet (IRP) representing the function to 00077 be performed. 00078 00079 Return Value: 00080 00081 The function value is the final status of the operation. 00082 00083 00084 -*/ 00085 00086 { 00087 NTSTATUS status; 00088 PIO_STACK_LOCATION irpSp; 00089 PDEVICE_EXTENSION deviceExtension; 00090 UNICODE_STRING driverName; 00091 ULONG bytesPerSector; 00092 PDEVICE_OBJECT targetDevice; 00093 00094 PAGED_CODE(); 00095 00096 // 00097 // Begin by determining what function that is to be performed. 00098 // 00099 00100 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00101 irpSp = IoGetCurrentIrpStackLocation( Irp ); 00102 00103 switch ( irpSp->MinorFunction ) { 00104 00105 case IRP_MN_MOUNT_VOLUME: 00106 00107 // 00108 // Attempt to mount a volume: There are two different cases here: 00109 // 00110 // 1) The device is being opened for DASD access, that is, no 00111 // file system is required, thus it is OK to allow RAW to 00112 // to open it. 00113 // 00114 // 2) We need to rummage the media to see if this is a UDF volume. 00115 // 00116 00117 status = STATUS_UNRECOGNIZED_VOLUME; 00118 00119 targetDevice = irpSp->Parameters.MountVolume.DeviceObject; 00120 00121 if (FsRecGetDeviceSectorSize( targetDevice, 00122 &bytesPerSector )) { 00123 00124 if (IsUdfsVolume( targetDevice, 00125 bytesPerSector )) { 00126 00127 status = STATUS_FS_DRIVER_REQUIRED; 00128 } 00129 } 00130 00131 break; 00132 00133 case IRP_MN_LOAD_FILE_SYSTEM: 00134 00135 status = FsRecLoadFileSystem( DeviceObject, 00136 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Udfs" ); 00137 break; 00138 00139 default: 00140 status = STATUS_INVALID_DEVICE_REQUEST; 00141 00142 } 00143 00144 // 00145 // Finally, complete the request and return the same status code to the 00146 // caller. 00147 // 00148 00149 Irp->IoStatus.Status = status; 00150 IoCompleteRequest( Irp, IO_NO_INCREMENT ); 00151 00152 return status; 00153 }


Variable Documentation

PARSE_KEYVALUE VsdIdentParseTable[]
 

Initial value:

Definition at line 39 of file udfs_rec.c.

Referenced by IsUdfsVolume(), and UdfRecognizeVolume().


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