Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfsctl.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2002, 2003 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* 00020 * COPYRIGHT: See COPYING in the top level directory 00021 * PROJECT: ReactOS kernel 00022 * FILE: drivers/fs/cdfs/fsctl.c 00023 * PURPOSE: CDROM (ISO 9660) filesystem driver 00024 * PROGRAMMER: Art Yerkes 00025 * Eric Kohl 00026 */ 00027 00028 /* INCLUDES *****************************************************************/ 00029 00030 #include "cdfs.h" 00031 00032 #define NDEBUG 00033 #include <debug.h> 00034 00035 /* FUNCTIONS ****************************************************************/ 00036 00037 static __inline 00038 int msf_to_lba (UCHAR m, UCHAR s, UCHAR f) 00039 { 00040 return (((m * 60) + s) * 75 + f) - 150; 00041 } 00042 00043 00044 static VOID 00045 CdfsGetPVDData(PUCHAR Buffer, 00046 PCDINFO CdInfo) 00047 { 00048 PPVD Pvd; 00049 USHORT i; 00050 PUCHAR pc; 00051 PWCHAR pw; 00052 00053 union 00054 { 00055 ULONG Value; 00056 UCHAR Part[4]; 00057 } Serial; 00058 00059 Pvd = (PPVD)Buffer; 00060 00061 /* Calculate the volume serial number */ 00062 Serial.Value = 0; 00063 for (i = 0; i < 2048; i += 4) 00064 { 00065 /* DON'T optimize this to ULONG!!! (breaks overflow) */ 00066 Serial.Part[3] += Buffer[i+0]; 00067 Serial.Part[2] += Buffer[i+1]; 00068 Serial.Part[1] += Buffer[i+2]; 00069 Serial.Part[0] += Buffer[i+3]; 00070 } 00071 CdInfo->SerialNumber = Serial.Value; 00072 00073 /* Extract the volume label */ 00074 pc = Pvd->VolumeId; 00075 pw = CdInfo->VolumeLabel; 00076 for (i = 0; i < (MAXIMUM_VOLUME_LABEL_LENGTH / sizeof(WCHAR)) - 1; i++) 00077 { 00078 *pw++ = (WCHAR)*pc++; 00079 } 00080 *pw = 0; 00081 00082 /* Trim trailing spaces */ 00083 while (pw > CdInfo->VolumeLabel) 00084 { 00085 if (*--pw != ' ') break; 00086 00087 /* Remove the space */ 00088 *pw = '\0'; 00089 00090 /* Decrease size */ 00091 i--; 00092 } 00093 00094 CdInfo->VolumeLabelLength = i * sizeof(WCHAR); 00095 00096 CdInfo->VolumeSpaceSize = Pvd->VolumeSpaceSizeL; 00097 CdInfo->RootStart = Pvd->RootDirRecord.ExtentLocationL; 00098 CdInfo->RootSize = Pvd->RootDirRecord.DataLengthL; 00099 00100 DPRINT("VolumeSerial: %08lx\n", CdInfo->SerialNumber); 00101 DPRINT("VolumeLabel: '%S'\n", CdInfo->VolumeLabel); 00102 DPRINT("VolumeLabelLength: %lu\n", CdInfo->VolumeLabelLength); 00103 DPRINT("VolumeSize: %lu\n", Pvd->VolumeSpaceSizeL); 00104 DPRINT("RootStart: %lu\n", Pvd->RootDirRecord.ExtentLocationL); 00105 DPRINT("RootSize: %lu\n", Pvd->RootDirRecord.DataLengthL); 00106 DPRINT("PathTableSize: %lu\n", Pvd->PathTableSizeL); 00107 DPRINT("PathTablePos: %lu\n", Pvd->LPathTablePos); 00108 DPRINT("OptPathTablePos: %lu\n", Pvd->LOptPathTablePos); 00109 00110 #if 0 00111 DbgPrint("******** PVD **********\n"); 00112 DbgPrint("VdType: %d\n", Pvd->VdType); 00113 DbgPrint("StandardId: '%.*s'\n", 5, Pvd->StandardId); 00114 DbgPrint("VdVersion: %d\n", Pvd->VdVersion); 00115 DbgPrint("SystemId: '%.*s'\n", 32, Pvd->SystemId); 00116 DbgPrint("VolumeId: '%.*s'\n", 32, Pvd->VolumeId); 00117 DbgPrint("VolumeSpaceSizeL: %d (%x)\n", Pvd->VolumeSpaceSizeL, Pvd->VolumeSpaceSizeL); 00118 DbgPrint("VolumeSpaceSizeM: %d (%x)\n", Pvd->VolumeSpaceSizeM, Pvd->VolumeSpaceSizeM); 00119 DbgPrint("VolumeSetSize: %d (%x)\n", Pvd->VolumeSequenceNumber, Pvd->VolumeSequenceNumber); 00120 DbgPrint("VolumeSequenceNumber: %d (%x)\n", Pvd->VolumeSequenceNumber, Pvd->VolumeSequenceNumber); 00121 DbgPrint("LogicalBlockSize: %d (%x)\n", Pvd->LogicalBlockSize, Pvd->LogicalBlockSize); 00122 DbgPrint("PathTableSizeL: %d (%x)\n", Pvd->PathTableSizeL, Pvd->PathTableSizeL); 00123 DbgPrint("PathTableSizeM: %d (%x)\n", Pvd->PathTableSizeM, Pvd->PathTableSizeM); 00124 DbgPrint("LPathTablePos: %d (%x)\n", Pvd->LPathTablePos, Pvd->LPathTablePos); 00125 DbgPrint("LOptPathTablePos: %d (%x)\n", Pvd->LOptPathTablePos, Pvd->LOptPathTablePos); 00126 DbgPrint("MPathTablePos: %d (%x)\n", Pvd->MPathTablePos, Pvd->MPathTablePos); 00127 DbgPrint("MOptPathTablePos: %d (%x)\n", Pvd->MOptPathTablePos, Pvd->MOptPathTablePos); 00128 DbgPrint("VolumeSetIdentifier: '%.*s'\n", 128, Pvd->VolumeSetIdentifier); 00129 DbgPrint("PublisherIdentifier: '%.*s'\n", 128, Pvd->PublisherIdentifier); 00130 DbgPrint("******** Root *********\n"); 00131 DbgPrint("RecordLength: %d\n", Pvd->RootDirRecord.RecordLength); 00132 DbgPrint("ExtAttrRecordLength: %d\n", Pvd->RootDirRecord.ExtAttrRecordLength); 00133 DbgPrint("ExtentLocationL: %d\n", Pvd->RootDirRecord.ExtentLocationL); 00134 DbgPrint("DataLengthL: %d\n", Pvd->RootDirRecord.DataLengthL); 00135 DbgPrint("Year: %d\n", Pvd->RootDirRecord.Year); 00136 DbgPrint("Month: %d\n", Pvd->RootDirRecord.Month); 00137 DbgPrint("Day: %d\n", Pvd->RootDirRecord.Day); 00138 DbgPrint("Hour: %d\n", Pvd->RootDirRecord.Hour); 00139 DbgPrint("Minute: %d\n", Pvd->RootDirRecord.Minute); 00140 DbgPrint("Second: %d\n", Pvd->RootDirRecord.Second); 00141 DbgPrint("TimeZone: %d\n", Pvd->RootDirRecord.TimeZone); 00142 DbgPrint("FileFlags: %d\n", Pvd->RootDirRecord.FileFlags); 00143 DbgPrint("FileUnitSize: %d\n", Pvd->RootDirRecord.FileUnitSize); 00144 DbgPrint("InterleaveGapSize: %d\n", Pvd->RootDirRecord.InterleaveGapSize); 00145 DbgPrint("VolumeSequenceNumber: %d\n", Pvd->RootDirRecord.VolumeSequenceNumber); 00146 DbgPrint("FileIdLength: %d\n", Pvd->RootDirRecord.FileIdLength); 00147 DbgPrint("FileId: '%.*s'\n", Pvd->RootDirRecord.FileId); 00148 DbgPrint("***********************\n"); 00149 #endif 00150 } 00151 00152 00153 static VOID 00154 CdfsGetSVDData(PUCHAR Buffer, 00155 PCDINFO CdInfo) 00156 { 00157 PSVD Svd; 00158 ULONG JolietLevel = 0; 00159 00160 Svd = (PSVD)Buffer; 00161 00162 DPRINT("EscapeSequences: '%.32s'\n", Svd->EscapeSequences); 00163 00164 if (strncmp((PCHAR)Svd->EscapeSequences, "%/@", 3) == 0) 00165 { 00166 DPRINT("Joliet extension found (UCS-2 Level 1)\n"); 00167 JolietLevel = 1; 00168 } 00169 else if (strncmp((PCHAR)Svd->EscapeSequences, "%/C", 3) == 0) 00170 { 00171 DPRINT("Joliet extension found (UCS-2 Level 2)\n"); 00172 JolietLevel = 2; 00173 } 00174 else if (strncmp((PCHAR)Svd->EscapeSequences, "%/E", 3) == 0) 00175 { 00176 DPRINT("Joliet extension found (UCS-2 Level 3)\n"); 00177 JolietLevel = 3; 00178 } 00179 00180 CdInfo->JolietLevel = JolietLevel; 00181 00182 if (JolietLevel != 0) 00183 { 00184 CdInfo->RootStart = Svd->RootDirRecord.ExtentLocationL; 00185 CdInfo->RootSize = Svd->RootDirRecord.DataLengthL; 00186 00187 DPRINT("RootStart: %lu\n", Svd->RootDirRecord.ExtentLocationL); 00188 DPRINT("RootSize: %lu\n", Svd->RootDirRecord.DataLengthL); 00189 } 00190 } 00191 00192 00193 static NTSTATUS 00194 CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject, 00195 PCDINFO CdInfo) 00196 { 00197 PUCHAR Buffer; 00198 NTSTATUS Status; 00199 ULONG Sector; 00200 PVD_HEADER VdHeader; 00201 ULONG Size; 00202 ULONG Offset; 00203 ULONG i; 00204 struct 00205 { 00206 UCHAR Length[2]; 00207 UCHAR FirstSession; 00208 UCHAR LastSession; 00209 TRACK_DATA TrackData; 00210 } 00211 Toc; 00212 00213 DPRINT("CdfsGetVolumeData\n"); 00214 00215 Buffer = ExAllocatePool(NonPagedPool, 00216 CDFS_BASIC_SECTOR); 00217 if (Buffer == NULL) 00218 return STATUS_INSUFFICIENT_RESOURCES; 00219 00220 Size = sizeof(Toc); 00221 Status = CdfsDeviceIoControl(DeviceObject, 00222 IOCTL_CDROM_GET_LAST_SESSION, 00223 NULL, 00224 0, 00225 &Toc, 00226 &Size, 00227 TRUE); 00228 if (!NT_SUCCESS(Status)) 00229 { 00230 ExFreePool(Buffer); 00231 return Status; 00232 } 00233 00234 DPRINT("FirstSession %d, LastSession %d, FirstTrack %d\n", 00235 Toc.FirstSession, Toc.LastSession, Toc.TrackData.TrackNumber); 00236 00237 Offset = 0; 00238 for (i = 0; i < 4; i++) 00239 { 00240 Offset = (Offset << 8) + Toc.TrackData.Address[i]; 00241 } 00242 CdInfo->VolumeOffset = Offset; 00243 00244 DPRINT("Offset of first track in last session %d\n", Offset); 00245 00246 CdInfo->JolietLevel = 0; 00247 VdHeader = (PVD_HEADER)Buffer; 00248 Buffer[0] = 0; 00249 00250 for (Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION; Sector < 100 && Buffer[0] != 255; Sector++) 00251 { 00252 /* Read the Primary Volume Descriptor (PVD) */ 00253 Status = CdfsReadSectors (DeviceObject, 00254 Sector + Offset, 00255 1, 00256 Buffer, 00257 TRUE); 00258 if (!NT_SUCCESS(Status)) 00259 { 00260 ExFreePool(Buffer); 00261 return Status; 00262 } 00263 00264 if (Sector == CDFS_PRIMARY_DESCRIPTOR_LOCATION) 00265 { 00266 DPRINT("CD-identifier: [%.5s]\n", Buffer + 1); 00267 00268 if (Buffer[0] != 1 || Buffer[1] != 'C' || Buffer[2] != 'D' || 00269 Buffer[3] != '0' || Buffer[4] != '0' || Buffer[5] != '1') 00270 { 00271 ExFreePool(Buffer); 00272 return STATUS_UNRECOGNIZED_VOLUME; 00273 } 00274 } 00275 00276 switch (VdHeader->VdType) 00277 { 00278 case 0: 00279 DPRINT("BootVolumeDescriptor found!\n"); 00280 break; 00281 00282 case 1: 00283 DPRINT("PrimaryVolumeDescriptor found!\n"); 00284 CdfsGetPVDData(Buffer, CdInfo); 00285 break; 00286 00287 case 2: 00288 DPRINT("SupplementaryVolumeDescriptor found!\n"); 00289 CdfsGetSVDData(Buffer, CdInfo); 00290 break; 00291 00292 case 3: 00293 DPRINT("VolumePartitionDescriptor found!\n"); 00294 break; 00295 00296 case 255: 00297 DPRINT("VolumeDescriptorSetTerminator found!\n"); 00298 break; 00299 00300 default: 00301 DPRINT1("Unknown volume descriptor type %u found!\n", VdHeader->VdType); 00302 break; 00303 } 00304 } 00305 00306 ExFreePool(Buffer); 00307 00308 return(STATUS_SUCCESS); 00309 } 00310 00311 00312 static NTSTATUS 00313 CdfsMountVolume(PDEVICE_OBJECT DeviceObject, 00314 PIRP Irp) 00315 { 00316 PDEVICE_EXTENSION DeviceExt = NULL; 00317 PDEVICE_OBJECT NewDeviceObject = NULL; 00318 PDEVICE_OBJECT DeviceToMount; 00319 PIO_STACK_LOCATION Stack; 00320 PFCB Fcb = NULL; 00321 PCCB Ccb = NULL; 00322 PVPB Vpb; 00323 NTSTATUS Status; 00324 CDINFO CdInfo; 00325 00326 DPRINT("CdfsMountVolume() called\n"); 00327 00328 if (DeviceObject != CdfsGlobalData->DeviceObject) 00329 { 00330 Status = STATUS_INVALID_DEVICE_REQUEST; 00331 goto ByeBye; 00332 } 00333 00334 Stack = IoGetCurrentIrpStackLocation(Irp); 00335 DeviceToMount = Stack->Parameters.MountVolume.DeviceObject; 00336 Vpb = Stack->Parameters.MountVolume.Vpb; 00337 00338 Status = CdfsGetVolumeData(DeviceToMount, &CdInfo); 00339 if (!NT_SUCCESS(Status)) 00340 { 00341 goto ByeBye; 00342 } 00343 00344 Status = IoCreateDevice(CdfsGlobalData->DriverObject, 00345 sizeof(DEVICE_EXTENSION), 00346 NULL, 00347 FILE_DEVICE_CD_ROM_FILE_SYSTEM, 00348 DeviceToMount->Characteristics, 00349 FALSE, 00350 &NewDeviceObject); 00351 if (!NT_SUCCESS(Status)) 00352 goto ByeBye; 00353 00354 NewDeviceObject->Flags = NewDeviceObject->Flags | DO_DIRECT_IO; 00355 NewDeviceObject->Flags &= ~DO_VERIFY_VOLUME; 00356 DeviceExt = (PVOID)NewDeviceObject->DeviceExtension; 00357 RtlZeroMemory(DeviceExt, 00358 sizeof(DEVICE_EXTENSION)); 00359 00360 Vpb->SerialNumber = CdInfo.SerialNumber; 00361 Vpb->VolumeLabelLength = CdInfo.VolumeLabelLength; 00362 RtlCopyMemory(Vpb->VolumeLabel, CdInfo.VolumeLabel, CdInfo.VolumeLabelLength); 00363 RtlCopyMemory(&DeviceExt->CdInfo, &CdInfo, sizeof(CDINFO)); 00364 00365 NewDeviceObject->Vpb = DeviceToMount->Vpb; 00366 00367 DeviceExt->VolumeDevice = NewDeviceObject; 00368 DeviceExt->StorageDevice = DeviceToMount; 00369 DeviceExt->StorageDevice->Vpb->DeviceObject = NewDeviceObject; 00370 DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice; 00371 DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED; 00372 NewDeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1; 00373 NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 00374 00375 /* Close (and cleanup) might be called from IoCreateStreamFileObject 00376 * but we use this resource from CdfsCleanup, therefore it should be 00377 * initialized no later than this. */ 00378 ExInitializeResourceLite(&DeviceExt->DirResource); 00379 00380 DeviceExt->StreamFileObject = IoCreateStreamFileObject(NULL, 00381 DeviceExt->StorageDevice); 00382 00383 Fcb = CdfsCreateFCB(NULL); 00384 if (Fcb == NULL) 00385 { 00386 Status = STATUS_INSUFFICIENT_RESOURCES; 00387 goto ByeBye; 00388 } 00389 00390 Ccb = ExAllocatePoolWithTag(NonPagedPool, 00391 sizeof(CCB), 00392 TAG_CCB); 00393 if (Ccb == NULL) 00394 { 00395 Status = STATUS_INSUFFICIENT_RESOURCES; 00396 goto ByeBye; 00397 } 00398 RtlZeroMemory(Ccb, 00399 sizeof(CCB)); 00400 00401 DeviceExt->StreamFileObject->ReadAccess = TRUE; 00402 DeviceExt->StreamFileObject->WriteAccess = FALSE; 00403 DeviceExt->StreamFileObject->DeleteAccess = FALSE; 00404 DeviceExt->StreamFileObject->FsContext = Fcb; 00405 DeviceExt->StreamFileObject->FsContext2 = Ccb; 00406 DeviceExt->StreamFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; 00407 DeviceExt->StreamFileObject->PrivateCacheMap = NULL; 00408 DeviceExt->StreamFileObject->Vpb = DeviceExt->Vpb; 00409 Ccb->PtrFileObject = DeviceExt->StreamFileObject; 00410 Fcb->FileObject = DeviceExt->StreamFileObject; 00411 Fcb->DevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice; 00412 00413 Fcb->Flags = FCB_IS_VOLUME_STREAM; 00414 00415 Fcb->RFCB.FileSize.QuadPart = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE; 00416 Fcb->RFCB.ValidDataLength = Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize; 00417 00418 Fcb->Entry.ExtentLocationL = 0; 00419 Fcb->Entry.DataLengthL = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE; 00420 00421 CcInitializeCacheMap(DeviceExt->StreamFileObject, 00422 (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize), 00423 TRUE, 00424 &(CdfsGlobalData->CacheMgrCallbacks), 00425 Fcb); 00426 00427 ExInitializeResourceLite(&DeviceExt->VcbResource); 00428 00429 KeInitializeSpinLock(&DeviceExt->FcbListLock); 00430 InitializeListHead(&DeviceExt->FcbListHead); 00431 00432 Status = STATUS_SUCCESS; 00433 00434 ByeBye: 00435 if (!NT_SUCCESS(Status)) 00436 { 00437 /* Cleanup */ 00438 if (DeviceExt && DeviceExt->StreamFileObject) 00439 ObDereferenceObject(DeviceExt->StreamFileObject); 00440 if (Fcb) 00441 ExFreePool(Fcb); 00442 if (Ccb) 00443 ExFreePool(Ccb); 00444 if (NewDeviceObject) 00445 IoDeleteDevice(NewDeviceObject); 00446 } 00447 00448 DPRINT("CdfsMountVolume() done (Status: %lx)\n", Status); 00449 00450 return(Status); 00451 } 00452 00453 00454 static NTSTATUS 00455 CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject, 00456 PIRP Irp) 00457 { 00458 PDEVICE_EXTENSION DeviceExt; 00459 PDEVICE_OBJECT DeviceToVerify; 00460 PIO_STACK_LOCATION Stack; 00461 NTSTATUS Status; 00462 CDINFO CdInfo; 00463 00464 PLIST_ENTRY Entry; 00465 PFCB Fcb; 00466 00467 DPRINT1 ("CdfsVerifyVolume() called\n"); 00468 00469 #if 0 00470 if (DeviceObject != CdfsGlobalData->DeviceObject) 00471 { 00472 DPRINT1("DeviceObject != CdfsGlobalData->DeviceObject\n"); 00473 return(STATUS_INVALID_DEVICE_REQUEST); 00474 } 00475 #endif 00476 00477 DeviceExt = DeviceObject->DeviceExtension; 00478 00479 Stack = IoGetCurrentIrpStackLocation (Irp); 00480 DeviceToVerify = Stack->Parameters.VerifyVolume.DeviceObject; 00481 00482 FsRtlEnterFileSystem(); 00483 ExAcquireResourceExclusiveLite (&DeviceExt->VcbResource, 00484 TRUE); 00485 00486 if (!(DeviceToVerify->Flags & DO_VERIFY_VOLUME)) 00487 { 00488 DPRINT1 ("Volume has been verified!\n"); 00489 ExReleaseResourceLite (&DeviceExt->VcbResource); 00490 FsRtlExitFileSystem(); 00491 return STATUS_SUCCESS; 00492 } 00493 00494 DPRINT1 ("Device object %p Device to verify %p\n", DeviceObject, DeviceToVerify); 00495 00496 Status = CdfsGetVolumeData (DeviceToVerify, 00497 &CdInfo); 00498 if (NT_SUCCESS(Status) && 00499 CdInfo.SerialNumber == DeviceToVerify->Vpb->SerialNumber && 00500 CdInfo.VolumeLabelLength == DeviceToVerify->Vpb->VolumeLabelLength && 00501 !wcsncmp (CdInfo.VolumeLabel, DeviceToVerify->Vpb->VolumeLabel, CdInfo.VolumeLabelLength)) 00502 { 00503 DPRINT1 ("Same volume!\n"); 00504 00505 /* FIXME: Flush and purge metadata */ 00506 00507 Status = STATUS_SUCCESS; 00508 } 00509 else 00510 { 00511 DPRINT1 ("Different volume!\n"); 00512 00513 /* FIXME: force volume dismount */ 00514 Entry = DeviceExt->FcbListHead.Flink; 00515 while (Entry != &DeviceExt->FcbListHead) 00516 { 00517 Fcb = (PFCB)CONTAINING_RECORD(Entry, FCB, FcbListEntry); 00518 DPRINT1("OpenFile %S RefCount %ld\n", Fcb->PathName, Fcb->RefCount); 00519 00520 Entry = Entry->Flink; 00521 } 00522 00523 Status = STATUS_WRONG_VOLUME; 00524 } 00525 00526 DeviceToVerify->Flags &= ~DO_VERIFY_VOLUME; 00527 00528 ExReleaseResourceLite (&DeviceExt->VcbResource); 00529 FsRtlExitFileSystem(); 00530 00531 return Status; 00532 } 00533 00534 00535 NTSTATUS NTAPI 00536 CdfsSetCompression( 00537 IN PDEVICE_OBJECT DeviceObject, 00538 IN PIRP Irp) 00539 { 00540 PIO_STACK_LOCATION Stack; 00541 USHORT CompressionState; 00542 00543 Stack = IoGetCurrentIrpStackLocation(Irp); 00544 00545 if (Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(CompressionState)) 00546 return STATUS_INVALID_DEVICE_REQUEST; 00547 00548 CompressionState = *(USHORT *)Irp->AssociatedIrp.SystemBuffer; 00549 if (CompressionState != COMPRESSION_FORMAT_NONE) 00550 return STATUS_INVALID_PARAMETER; 00551 00552 return STATUS_SUCCESS; 00553 } 00554 00555 00556 NTSTATUS NTAPI 00557 CdfsFileSystemControl(PDEVICE_OBJECT DeviceObject, 00558 PIRP Irp) 00559 { 00560 PIO_STACK_LOCATION Stack; 00561 NTSTATUS Status; 00562 00563 DPRINT("CdfsFileSystemControl() called\n"); 00564 00565 Stack = IoGetCurrentIrpStackLocation(Irp); 00566 00567 switch (Stack->MinorFunction) 00568 { 00569 case IRP_MN_KERNEL_CALL: 00570 case IRP_MN_USER_FS_REQUEST: 00571 switch (Stack->Parameters.DeviceIoControl.IoControlCode) 00572 { 00573 case FSCTL_SET_COMPRESSION: 00574 DPRINT("CDFS: IRP_MN_USER_FS_REQUEST / FSCTL_SET_COMPRESSION\n"); 00575 Status = CdfsSetCompression(DeviceObject, Irp); 00576 break; 00577 00578 default: 00579 DPRINT1("CDFS: IRP_MN_USER_FS_REQUEST / Unknown IoControlCode 0x%x\n", 00580 Stack->Parameters.DeviceIoControl.IoControlCode); 00581 Status = STATUS_INVALID_DEVICE_REQUEST; 00582 } 00583 break; 00584 00585 case IRP_MN_MOUNT_VOLUME: 00586 DPRINT("CDFS: IRP_MN_MOUNT_VOLUME\n"); 00587 Status = CdfsMountVolume(DeviceObject, Irp); 00588 break; 00589 00590 case IRP_MN_VERIFY_VOLUME: 00591 DPRINT1("CDFS: IRP_MN_VERIFY_VOLUME\n"); 00592 Status = CdfsVerifyVolume(DeviceObject, Irp); 00593 break; 00594 00595 default: 00596 DPRINT1("CDFS FSC: MinorFunction %d\n", Stack->MinorFunction); 00597 Status = STATUS_INVALID_DEVICE_REQUEST; 00598 break; 00599 } 00600 00601 Irp->IoStatus.Status = Status; 00602 Irp->IoStatus.Information = 0; 00603 00604 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00605 00606 return(Status); 00607 } 00608 00609 /* EOF */ Generated on Sat May 26 2012 04:26:16 for ReactOS by
1.7.6.1
|