ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

fsctl.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.