Doxygen

dirctl.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
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  * COPYRIGHT:        See COPYING in the top level directory
00020  * PROJECT:          ReactOS kernel
00021  * FILE:             drivers/filesystem/ntfs/dirctl.c
00022  * PURPOSE:          NTFS filesystem driver
00023  * PROGRAMMER:       Eric Kohl
00024  */
00025 
00026 /* INCLUDES *****************************************************************/
00027 
00028 #include "ntfs.h"
00029 
00030 #define NDEBUG
00031 #include <debug.h>
00032 
00033 /* GLOBALS *****************************************************************/
00034 
00035 
00036 /* FUNCTIONS ****************************************************************/
00037 
00038 #if 0
00039 static NTSTATUS
00040 CdfsGetEntryName(PDEVICE_EXTENSION DeviceExt,
00041          PVOID *Context,
00042          PVOID *Block,
00043          PLARGE_INTEGER StreamOffset,
00044          ULONG DirLength,
00045          PVOID *Ptr,
00046          PWSTR Name,
00047          PULONG pIndex,
00048          PULONG pIndex2)
00049 /*
00050  * FUNCTION: Retrieves the file name, be it in short or long file name format
00051  */
00052 {
00053   PDIR_RECORD Record;
00054   NTSTATUS Status;
00055   ULONG Index = 0;
00056   ULONG Offset = 0;
00057   ULONG BlockOffset = 0;
00058 
00059   Record = (PDIR_RECORD)*Block;
00060   while(Index < *pIndex)
00061     {
00062       BlockOffset += Record->RecordLength;
00063       Offset += Record->RecordLength;
00064 
00065       Record = (PDIR_RECORD)(*Block + BlockOffset);
00066       if (BlockOffset >= BLOCKSIZE || Record->RecordLength == 0)
00067     {
00068       DPRINT("Map next sector\n");
00069       CcUnpinData(*Context);
00070       StreamOffset->QuadPart += BLOCKSIZE;
00071       Offset = ROUND_UP(Offset, BLOCKSIZE);
00072       BlockOffset = 0;
00073 
00074       if (!CcMapData(DeviceExt->StreamFileObject,
00075              StreamOffset,
00076              BLOCKSIZE, TRUE,
00077              Context, Block))
00078         {
00079           DPRINT("CcMapData() failed\n");
00080           return(STATUS_UNSUCCESSFUL);
00081         }
00082       Record = (PDIR_RECORD)(*Block + BlockOffset);
00083     }
00084 
00085       if (Offset >= DirLength)
00086     return(STATUS_NO_MORE_ENTRIES);
00087 
00088       Index++;
00089     }
00090 
00091   DPRINT("Index %lu  RecordLength %lu  Offset %lu\n",
00092      Index, Record->RecordLength, Offset);
00093 
00094   if (Record->FileIdLength == 1 && Record->FileId[0] == 0)
00095     {
00096       wcscpy(Name, L".");
00097     }
00098   else if (Record->FileIdLength == 1 && Record->FileId[0] == 1)
00099     {
00100       wcscpy(Name, L"..");
00101     }
00102   else
00103     {
00104       if (DeviceExt->CdInfo.JolietLevel == 0)
00105     {
00106       ULONG i;
00107 
00108       for (i = 0; i < Record->FileIdLength && Record->FileId[i] != ';'; i++)
00109         Name[i] = (WCHAR)Record->FileId[i];
00110       Name[i] = 0;
00111     }
00112       else
00113     {
00114       CdfsSwapString(Name, Record->FileId, Record->FileIdLength);
00115     }
00116     }
00117 
00118   DPRINT("Name '%S'\n", Name);
00119 
00120   *Ptr = Record;
00121 
00122   *pIndex = Index;
00123 
00124   return(STATUS_SUCCESS);
00125 }
00126 
00127 
00128 static NTSTATUS
00129 CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
00130          PFCB Fcb,
00131          PFCB Parent,
00132          PWSTR FileToFind,
00133          PULONG pDirIndex,
00134          PULONG pDirIndex2)
00135 /*
00136  * FUNCTION: Find a file
00137  */
00138 {
00139   WCHAR name[256];
00140   WCHAR TempStr[2];
00141   PVOID Block;
00142   NTSTATUS Status;
00143   ULONG len;
00144   ULONG DirIndex;
00145   ULONG Offset;
00146   ULONG Read;
00147   BOOLEAN IsRoot;
00148   PVOID Context = NULL;
00149   ULONG DirSize;
00150   PUCHAR Ptr;
00151   PDIR_RECORD Record;
00152   LARGE_INTEGER StreamOffset;
00153 
00154   DPRINT("FindFile(Parent %x, FileToFind '%S', DirIndex: %d)\n",
00155      Parent, FileToFind, pDirIndex ? *pDirIndex : 0);
00156   DPRINT("FindFile: old Pathname %x, old Objectname %x)\n",
00157      Fcb->PathName, Fcb->ObjectName);
00158 
00159   IsRoot = FALSE;
00160   DirIndex = 0;
00161   if (wcslen (FileToFind) == 0)
00162     {
00163       CHECKPOINT;
00164       TempStr[0] = (WCHAR) '.';
00165       TempStr[1] = 0;
00166       FileToFind = (PWSTR)&TempStr;
00167     }
00168 
00169   if (Parent)
00170     {
00171       if (Parent->Entry.ExtentLocationL == DeviceExt->CdInfo.RootStart)
00172     {
00173       IsRoot = TRUE;
00174     }
00175     }
00176   else
00177     {
00178       IsRoot = TRUE;
00179     }
00180 
00181   if (IsRoot == TRUE)
00182     {
00183       StreamOffset.QuadPart = (LONGLONG)DeviceExt->CdInfo.RootStart * (LONGLONG)BLOCKSIZE;
00184       DirSize = DeviceExt->CdInfo.RootSize;
00185 
00186 
00187       if (FileToFind[0] == 0 || (FileToFind[0] == '\\' && FileToFind[1] == 0)
00188       || (FileToFind[0] == '.' && FileToFind[1] == 0))
00189     {
00190       /* it's root : complete essentials fields then return ok */
00191       RtlZeroMemory(Fcb, sizeof(FCB));
00192 
00193       Fcb->PathName[0]='\\';
00194       Fcb->ObjectName = &Fcb->PathName[1];
00195       Fcb->Entry.ExtentLocationL = DeviceExt->CdInfo.RootStart;
00196       Fcb->Entry.DataLengthL = DeviceExt->CdInfo.RootSize;
00197       Fcb->Entry.FileFlags = 0x02; //FILE_ATTRIBUTE_DIRECTORY;
00198 
00199       if (pDirIndex)
00200         *pDirIndex = 0;
00201       if (pDirIndex2)
00202         *pDirIndex2 = 0;
00203       DPRINT("CdfsFindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName);
00204       return (STATUS_SUCCESS);
00205     }
00206     }
00207   else
00208     {
00209       StreamOffset.QuadPart = (LONGLONG)Parent->Entry.ExtentLocationL * (LONGLONG)BLOCKSIZE;
00210       DirSize = Parent->Entry.DataLengthL;
00211     }
00212 
00213   DPRINT("StreamOffset %I64u  DirSize %lu\n", StreamOffset.QuadPart, DirSize);
00214 
00215   if (pDirIndex && (*pDirIndex))
00216     DirIndex = *pDirIndex;
00217 
00218   if(!CcMapData(DeviceExt->StreamFileObject, &StreamOffset,
00219         BLOCKSIZE, TRUE, &Context, &Block))
00220   {
00221     DPRINT("CcMapData() failed\n");
00222     return(STATUS_UNSUCCESSFUL);
00223   }
00224 
00225   Ptr = (PUCHAR)Block;
00226   while(TRUE)
00227     {
00228       Record = (PDIR_RECORD)Ptr;
00229       if (Record->RecordLength == 0)
00230     {
00231       DPRINT1("Stopped!\n");
00232       break;
00233     }
00234 
00235       DPRINT("RecordLength %u  ExtAttrRecordLength %u  NameLength %u\n",
00236          Record->RecordLength, Record->ExtAttrRecordLength, Record->FileIdLength);
00237 
00238       Status = CdfsGetEntryName(DeviceExt, &Context, &Block, &StreamOffset,
00239                 DirSize, (PVOID*)&Ptr, name, &DirIndex, pDirIndex2);
00240       if (Status == STATUS_NO_MORE_ENTRIES)
00241     {
00242       break;
00243     }
00244       else if (Status == STATUS_UNSUCCESSFUL)
00245     {
00246       /* Note: the directory cache has already been unpinned */
00247       return(Status);
00248     }
00249 
00250       DPRINT("Name '%S'\n", name);
00251 
00252       if (wstrcmpjoki(name, FileToFind)) /* || wstrcmpjoki (name2, FileToFind)) */
00253     {
00254       if (Parent && Parent->PathName)
00255         {
00256           len = wcslen(Parent->PathName);
00257           memcpy(Fcb->PathName, Parent->PathName, len*sizeof(WCHAR));
00258           Fcb->ObjectName=&Fcb->PathName[len];
00259           if (len != 1 || Fcb->PathName[0] != '\\')
00260         {
00261           Fcb->ObjectName[0] = '\\';
00262           Fcb->ObjectName = &Fcb->ObjectName[1];
00263         }
00264         }
00265       else
00266         {
00267           Fcb->ObjectName=Fcb->PathName;
00268           Fcb->ObjectName[0]='\\';
00269           Fcb->ObjectName=&Fcb->ObjectName[1];
00270         }
00271 
00272       DPRINT("PathName '%S'  ObjectName '%S'\n", Fcb->PathName, Fcb->ObjectName);
00273 
00274       memcpy(&Fcb->Entry, Ptr, sizeof(DIR_RECORD));
00275       wcsncpy(Fcb->ObjectName, name, MAX_PATH);
00276       if (pDirIndex)
00277         *pDirIndex = DirIndex;
00278 
00279       DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",
00280          Fcb->PathName, Fcb->ObjectName, DirIndex);
00281 
00282       CcUnpinData(Context);
00283 
00284       return(STATUS_SUCCESS);
00285     }
00286 
00287 
00288       Ptr = Ptr + Record->RecordLength;
00289       DirIndex++;
00290 
00291       if (((ULONG)Ptr - (ULONG)Block) >= DirSize)
00292     {
00293       DPRINT("Stopped!\n");
00294       break;
00295     }
00296     }
00297 
00298   CcUnpinData(Context);
00299 
00300   if (pDirIndex)
00301     *pDirIndex = DirIndex;
00302 
00303   return(STATUS_UNSUCCESSFUL);
00304 }
00305 
00306 
00307 static NTSTATUS
00308 CdfsGetNameInformation(PFCB Fcb,
00309                PDEVICE_EXTENSION DeviceExt,
00310                PFILE_NAMES_INFORMATION Info,
00311                ULONG BufferLength)
00312 {
00313   ULONG Length;
00314 
00315   DPRINT("CdfsGetNameInformation() called\n");
00316 
00317   Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
00318   if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
00319     return(STATUS_BUFFER_OVERFLOW);
00320 
00321   Info->FileNameLength = Length;
00322   Info->NextEntryOffset =
00323     ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
00324   memcpy(Info->FileName, Fcb->ObjectName, Length);
00325 
00326   return(STATUS_SUCCESS);
00327 }
00328 
00329 
00330 static NTSTATUS
00331 CdfsGetDirectoryInformation(PFCB Fcb,
00332                 PDEVICE_EXTENSION DeviceExt,
00333                 PFILE_DIRECTORY_INFORMATION Info,
00334                 ULONG BufferLength)
00335 {
00336   ULONG Length;
00337 
00338   DPRINT("CdfsGetDirectoryInformation() called\n");
00339 
00340   Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
00341   if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
00342     return(STATUS_BUFFER_OVERFLOW);
00343 
00344   Info->FileNameLength = Length;
00345   Info->NextEntryOffset =
00346     ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
00347   memcpy(Info->FileName, Fcb->ObjectName, Length);
00348 
00349   /* Convert file times */
00350   CdfsDateTimeToFileTime(Fcb,
00351              &Info->CreationTime);
00352   CdfsDateTimeToFileTime(Fcb,
00353              &Info->LastAccessTime);
00354   CdfsDateTimeToFileTime(Fcb,
00355              &Info->LastWriteTime);
00356   CdfsDateTimeToFileTime(Fcb,
00357              &Info->ChangeTime);
00358 
00359   /* Convert file flags */
00360   CdfsFileFlagsToAttributes(Fcb,
00361                 &Info->FileAttributes);
00362 
00363   Info->EndOfFile.QuadPart = Fcb->Entry.DataLengthL;
00364 
00365   /* Make AllocSize a rounded up multiple of the sector size */
00366   Info->AllocationSize.QuadPart = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE);
00367 
00368 //  Info->FileIndex=;
00369 
00370   return(STATUS_SUCCESS);
00371 }
00372 
00373 
00374 static NTSTATUS
00375 CdfsGetFullDirectoryInformation(PFCB Fcb,
00376                 PDEVICE_EXTENSION DeviceExt,
00377                 PFILE_FULL_DIRECTORY_INFORMATION Info,
00378                 ULONG BufferLength)
00379 {
00380   ULONG Length;
00381 
00382   DPRINT("CdfsGetFullDirectoryInformation() called\n");
00383 
00384   Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
00385   if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
00386     return(STATUS_BUFFER_OVERFLOW);
00387 
00388   Info->FileNameLength = Length;
00389   Info->NextEntryOffset =
00390     ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
00391   memcpy(Info->FileName, Fcb->ObjectName, Length);
00392 
00393   /* Convert file times */
00394   CdfsDateTimeToFileTime(Fcb,
00395              &Info->CreationTime);
00396   CdfsDateTimeToFileTime(Fcb,
00397              &Info->LastAccessTime);
00398   CdfsDateTimeToFileTime(Fcb,
00399              &Info->LastWriteTime);
00400   CdfsDateTimeToFileTime(Fcb,
00401              &Info->ChangeTime);
00402 
00403   /* Convert file flags */
00404   CdfsFileFlagsToAttributes(Fcb,
00405                 &Info->FileAttributes);
00406 
00407   Info->EndOfFile.QuadPart = Fcb->Entry.DataLengthL;
00408 
00409   /* Make AllocSize a rounded up multiple of the sector size */
00410   Info->AllocationSize.QuadPart = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE);
00411 
00412 //  Info->FileIndex=;
00413   Info->EaSize = 0;
00414 
00415   return(STATUS_SUCCESS);
00416 }
00417 
00418 
00419 static NTSTATUS
00420 CdfsGetBothDirectoryInformation(PFCB Fcb,
00421                 PDEVICE_EXTENSION DeviceExt,
00422                 PFILE_BOTH_DIRECTORY_INFORMATION Info,
00423                 ULONG BufferLength)
00424 {
00425   ULONG Length;
00426 
00427   DPRINT("CdfsGetBothDirectoryInformation() called\n");
00428 
00429   Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
00430   if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
00431     return(STATUS_BUFFER_OVERFLOW);
00432 
00433   Info->FileNameLength = Length;
00434   Info->NextEntryOffset =
00435     ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
00436   memcpy(Info->FileName, Fcb->ObjectName, Length);
00437 
00438   /* Convert file times */
00439   CdfsDateTimeToFileTime(Fcb,
00440              &Info->CreationTime);
00441   CdfsDateTimeToFileTime(Fcb,
00442              &Info->LastAccessTime);
00443   CdfsDateTimeToFileTime(Fcb,
00444              &Info->LastWriteTime);
00445   CdfsDateTimeToFileTime(Fcb,
00446              &Info->ChangeTime);
00447 
00448   /* Convert file flags */
00449   CdfsFileFlagsToAttributes(Fcb,
00450                 &Info->FileAttributes);
00451 
00452   Info->EndOfFile.QuadPart = Fcb->Entry.DataLengthL;
00453 
00454   /* Make AllocSize a rounded up multiple of the sector size */
00455   Info->AllocationSize.QuadPart = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE);
00456 
00457 //  Info->FileIndex=;
00458   Info->EaSize = 0;
00459 
00460   if (DeviceExt->CdInfo.JolietLevel == 0)
00461     {
00462       /* Standard ISO-9660 format */
00463       Info->ShortNameLength = Length;
00464       memcpy(Info->ShortName, Fcb->ObjectName, Length);
00465     }
00466   else
00467     {
00468       /* Joliet extension */
00469 
00470       /* FIXME: Copy or create a short file name */
00471 
00472       Info->ShortName[0] = 0;
00473       Info->ShortNameLength = 0;
00474     }
00475 
00476   return(STATUS_SUCCESS);
00477 }
00478 #endif
00479 
00480 NTSTATUS
00481 NtfsQueryDirectory(PNTFS_IRP_CONTEXT IrpContext)
00482 {
00483   PIRP Irp;
00484   //PDEVICE_OBJECT DeviceObject;
00485   //PDEVICE_EXTENSION DeviceExtension;
00486   //LONG BufferLength = 0;
00487   PUNICODE_STRING SearchPattern = NULL;
00488   //FILE_INFORMATION_CLASS FileInformationClass;
00489   ULONG FileIndex = 0;
00490   PUCHAR Buffer = NULL;
00491   PFILE_NAMES_INFORMATION Buffer0 = NULL;
00492   //PNTFS_FCB Fcb;
00493   PNTFS_CCB Ccb;
00494 //  FCB TempFcb;
00495   BOOLEAN First = FALSE;
00496   PIO_STACK_LOCATION Stack;
00497   PFILE_OBJECT FileObject;
00498   //NTSTATUS Status = STATUS_SUCCESS;
00499 
00500   DPRINT1("NtfsQueryDirectory() called\n");
00501 
00502   ASSERT(IrpContext);
00503   Irp = IrpContext->Irp;
00504   //DeviceObject = IrpContext->DeviceObject;
00505 
00506   //DeviceExtension = DeviceObject->DeviceExtension;
00507   Stack = IoGetCurrentIrpStackLocation(Irp);
00508   FileObject = Stack->FileObject;
00509 
00510   Ccb = (PNTFS_CCB)FileObject->FsContext2;
00511   //Fcb = (PNTFS_FCB)FileObject->FsContext;
00512 
00513   /* Obtain the callers parameters */
00514   //BufferLength = Stack->Parameters.QueryDirectory.Length;
00515   SearchPattern = Stack->Parameters.QueryDirectory.FileName;
00516   //FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
00517   FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
00518 
00519 
00520   if (SearchPattern != NULL)
00521   {
00522     if (!Ccb->DirectorySearchPattern)
00523     {
00524       First = TRUE;
00525       Ccb->DirectorySearchPattern =
00526         ExAllocatePoolWithTag(NonPagedPool, SearchPattern->Length + sizeof(WCHAR), TAG_NTFS);
00527       if (!Ccb->DirectorySearchPattern)
00528       {
00529         return(STATUS_INSUFFICIENT_RESOURCES);
00530       }
00531 
00532       memcpy(Ccb->DirectorySearchPattern,
00533              SearchPattern->Buffer,
00534              SearchPattern->Length);
00535       Ccb->DirectorySearchPattern[SearchPattern->Length / sizeof(WCHAR)] = 0;
00536     }
00537   }
00538   else if (!Ccb->DirectorySearchPattern)
00539   {
00540     First = TRUE;
00541     Ccb->DirectorySearchPattern = ExAllocatePoolWithTag(NonPagedPool, 2 * sizeof(WCHAR), TAG_NTFS);
00542     if (!Ccb->DirectorySearchPattern)
00543     {
00544       return(STATUS_INSUFFICIENT_RESOURCES);
00545     }
00546     Ccb->DirectorySearchPattern[0] = L'*';
00547     Ccb->DirectorySearchPattern[1] = 0;
00548   }
00549   DPRINT("Search pattern '%S'\n", Ccb->DirectorySearchPattern);
00550 
00551   /* Determine directory index */
00552   if (Stack->Flags & SL_INDEX_SPECIFIED)
00553   {
00554     Ccb->Entry = Ccb->CurrentByteOffset.u.LowPart;
00555   }
00556   else if (First || (Stack->Flags & SL_RESTART_SCAN))
00557   {
00558     Ccb->Entry = 0;
00559   }
00560 
00561   /* Determine Buffer for result */
00562   if (Irp->MdlAddress)
00563   {
00564     Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
00565   }
00566   else
00567   {
00568     Buffer = Irp->UserBuffer;
00569   }
00570   DPRINT("Buffer=%p tofind=%S\n", Buffer, Ccb->DirectorySearchPattern);
00571 #if 0
00572   TempFcb.ObjectName = TempFcb.PathName;
00573   while (Status == STATUS_SUCCESS && BufferLength > 0)
00574     {
00575       Status = CdfsFindFile(DeviceExtension,
00576                 &TempFcb,
00577                 Fcb,
00578                 Ccb->DirectorySearchPattern,
00579                 &Ccb->Entry,
00580                 NULL);
00581       DPRINT("Found %S, Status=%x, entry %x\n", TempFcb.ObjectName, Status, Ccb->Entry);
00582 
00583       if (NT_SUCCESS(Status))
00584     {
00585       switch (FileInformationClass)
00586         {
00587           case FileNameInformation:
00588         Status = CdfsGetNameInformation(&TempFcb,
00589                         DeviceExtension,
00590                         (PFILE_NAMES_INFORMATION)Buffer,
00591                         BufferLength);
00592         break;
00593 
00594           case FileDirectoryInformation:
00595         Status = CdfsGetDirectoryInformation(&TempFcb,
00596                              DeviceExtension,
00597                              (PFILE_DIRECTORY_INFORMATION)Buffer,
00598                              BufferLength);
00599         break;
00600 
00601           case FileFullDirectoryInformation:
00602         Status = CdfsGetFullDirectoryInformation(&TempFcb,
00603                              DeviceExtension,
00604                              (PFILE_FULL_DIRECTORY_INFORMATION)Buffer,
00605                              BufferLength);
00606         break;
00607 
00608           case FileBothDirectoryInformation:
00609         Status = NtfsGetBothDirectoryInformation(&TempFcb,
00610                              DeviceExtension,
00611                              (PFILE_BOTH_DIRECTORY_INFORMATION)Buffer,
00612                              BufferLength);
00613         break;
00614 
00615           default:
00616         Status = STATUS_INVALID_INFO_CLASS;
00617         }
00618 
00619       if (Status == STATUS_BUFFER_OVERFLOW)
00620         {
00621           if (Buffer0)
00622         {
00623           Buffer0->NextEntryOffset = 0;
00624         }
00625           break;
00626         }
00627     }
00628       else
00629     {
00630       if (Buffer0)
00631         {
00632           Buffer0->NextEntryOffset = 0;
00633         }
00634 
00635       if (First)
00636         {
00637           Status = STATUS_NO_SUCH_FILE;
00638         }
00639       else
00640         {
00641           Status = STATUS_NO_MORE_FILES;
00642         }
00643       break;
00644     }
00645 
00646       Buffer0 = (PFILE_NAMES_INFORMATION)Buffer;
00647       Buffer0->FileIndex = FileIndex++;
00648       Ccb->Entry++;
00649 
00650       if (Stack->Flags & SL_RETURN_SINGLE_ENTRY)
00651     {
00652       break;
00653     }
00654       BufferLength -= Buffer0->NextEntryOffset;
00655       Buffer += Buffer0->NextEntryOffset;
00656     }
00657 #endif
00658 
00659   if (Buffer0)
00660   {
00661     Buffer0->NextEntryOffset = 0;
00662   }
00663 
00664   if (FileIndex > 0)
00665   {
00666     //Status = STATUS_SUCCESS;
00667   }
00668 
00669 //  return(Status);
00670   return(STATUS_NO_MORE_FILES);
00671 }
00672 
00673 
00674 
00675 NTSTATUS NTAPI
00676 NtfsFsdDirectoryControl(PDEVICE_OBJECT DeviceObject,
00677                         PIRP Irp)
00678 {
00679   PNTFS_IRP_CONTEXT IrpContext = NULL;
00680   NTSTATUS Status = STATUS_UNSUCCESSFUL;
00681 
00682   DPRINT1("NtfsDirectoryControl() called\n");
00683 
00684   FsRtlEnterFileSystem();
00685   ASSERT(DeviceObject);
00686   ASSERT(Irp);
00687 
00688   NtfsIsIrpTopLevel(Irp);
00689 
00690   IrpContext = NtfsAllocateIrpContext(DeviceObject, Irp);
00691   if (IrpContext)
00692   {
00693     switch (IrpContext->MinorFunction)
00694     {
00695       case IRP_MN_QUERY_DIRECTORY:
00696         Status = NtfsQueryDirectory(IrpContext);
00697         break;
00698       
00699       case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
00700         DPRINT1("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n");
00701         Status = STATUS_NOT_IMPLEMENTED;
00702         break;
00703         
00704       default:
00705         Status = STATUS_INVALID_DEVICE_REQUEST;
00706         break;
00707     }
00708   }
00709   else
00710     Status = STATUS_INSUFFICIENT_RESOURCES;
00711   
00712   Irp->IoStatus.Status = Status;
00713   Irp->IoStatus.Information = 0;
00714   IoCompleteRequest(Irp, IO_NO_INCREMENT);
00715   
00716   if (IrpContext)
00717     ExFreePoolWithTag(IrpContext, 'PRIN');
00718   
00719   IoSetTopLevelIrp(NULL);
00720   FsRtlExitFileSystem();
00721   return Status;
00722 }
00723 
00724 /* EOF */