00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include "fs_rec.h"
00027
#include "udfs_rec.h"
00028
00029
00030
00031
00032
00033 #define Dbg (FSREC_DEBUG_LEVEL_UDFS)
00034
00035
00036
00037
00038
00039 PARSE_KEYVALUE VsdIdentParseTable[] = {
00040 {
VSD_IDENT_BEA01,
VsdIdentBEA01 },
00041 {
VSD_IDENT_TEA01,
VsdIdentTEA01 },
00042 {
VSD_IDENT_CDROM,
VsdIdentCDROM },
00043 {
VSD_IDENT_CD001,
VsdIdentCD001 },
00044 {
VSD_IDENT_CDW01,
VsdIdentCDW01 },
00045 {
VSD_IDENT_CDW02,
VsdIdentCDW02 },
00046 {
VSD_IDENT_NSR01,
VsdIdentNSR01 },
00047 {
VSD_IDENT_NSR02,
VsdIdentNSR02 },
00048 {
VSD_IDENT_BOOT2,
VsdIdentBOOT2 },
00049 {
NULL,
VsdIdentBad }
00050 };
00051
00052
#ifdef ALLOC_PRAGMA
00053
#pragma alloc_text(PAGE,IsUdfsVolume)
00054
#pragma alloc_text(PAGE,UdfsFindInParseTable)
00055
#pragma alloc_text(PAGE,UdfsRecFsControl)
00056
#endif // ALLOC_PRAGMA
00057
00058
00059
NTSTATUS
00060 UdfsRecFsControl(
00061 IN
PDEVICE_OBJECT DeviceObject,
00062 IN
PIRP Irp
00063 )
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
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
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
00109
00110
00111
00112
00113
00114
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
00146
00147
00148
00149
Irp->
IoStatus.Status = status;
00150
IoCompleteRequest(
Irp,
IO_NO_INCREMENT );
00151
00152
return status;
00153 }
00154
00155
00156 BOOLEAN
00157 IsUdfsVolume (
00158 IN
PDEVICE_OBJECT DeviceObject,
00159 IN ULONG SectorSize
00160 )
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
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
00214
00215
00216
00217
00218
if (VolumeStructureDescriptor->Type == 0) {
00219
00220
00221
00222
00223
00224
00225
00226
switch (
UdfsFindInParseTable(
VsdIdentParseTable,
00227 VolumeStructureDescriptor->Ident,
00228
VSD_LENGTH_IDENT )) {
00229
case VsdIdentBEA01:
00230
00231
00232
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
00258
00259
00260
DebugTrace(( 0,
Dbg,
"IsUdfsVolume, got a TEA01\n" ));
00261
00262 Resolved =
TRUE;
00263
break;
00264
00265
case VsdIdentNSR02:
00266
00267
00268
00269
00270
00271
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
00299
00300
00301
break;
00302
00303
default:
00304
00305
DebugTrace(( 0,
Dbg,
"IsUdfsVolume, got an invalid 13346 descriptor\n" ));
00306
00307
00308
00309
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
00324
00325
00326
00327
00328
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
00342
00343
00344
break;
00345
00346
default:
00347
00348
DebugTrace(( 0,
Dbg,
"IsUdfsVolume, ... but it looks wacky\n" ));
00349
00350
00351
00352
00353
00354
00355 Resolved =
TRUE;
00356
break;
00357 }
00358
00359 }
else {
00360
00361
00362
00363
00364
00365
DebugTrace(( 0,
Dbg,
"IsUdfsVolume, got an unrecognizeable descriptor, probably not 13346/9660\n" ));
00366
break;
00367 }
00368
00369
00370
00371
00372
00373
Offset +=
SectorAlignN(
SectorSize,
sizeof(
VSD_GENERIC) );
00374 }
00375
00376
DebugTrace(( -1,
Dbg,
"IsUdfsVolume -> %c\n", ( FoundNSR ?
'T' :
'F' )));
00377
00378
00379
00380
00381
00382
if (VolumeStructureDescriptor) {
00383
00384
ExFreePool( VolumeStructureDescriptor );
00385 }
00386
00387
return FoundNSR;
00388 }
00389
00390
00391 ULONG
00392 UdfsFindInParseTable (
00393 IN
PPARSE_KEYVALUE ParseTable,
00394 IN PCHAR Id,
00395 IN ULONG MaxIdLen
00396 )
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
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 }
00434