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

dirctl.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:  See COPYING in the top level directory
00003  * PROJECT:    ReactOS kernel
00004  * FILE:       drivers/filesastems/npfs/dirctl.c
00005  * PURPOSE:    Named pipe filesystem
00006  * PROGRAMMER: Eric Kohl
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 
00011 #include "npfs.h"
00012 
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /* FUNCTIONS *****************************************************************/
00017 
00018 static NTSTATUS
00019 NpfsQueryDirectory(PNPFS_CCB Ccb,
00020                    PIRP Irp,
00021                    PULONG Size)
00022 {
00023     PIO_STACK_LOCATION Stack;
00024     ULONG BufferLength = 0;
00025     PUNICODE_STRING SearchPattern = NULL;
00026     FILE_INFORMATION_CLASS FileInformationClass;
00027     ULONG FileIndex = 0;
00028     PUCHAR Buffer = NULL;
00029     BOOLEAN First = FALSE;
00030     PLIST_ENTRY CurrentEntry;
00031     PNPFS_VCB Vcb;
00032     PNPFS_FCB PipeFcb;
00033     ULONG PipeIndex;
00034     NTSTATUS Status = STATUS_SUCCESS;
00035     PFILE_NAMES_INFORMATION NamesBuffer;
00036     PFILE_DIRECTORY_INFORMATION DirectoryBuffer;
00037     PFILE_FULL_DIR_INFORMATION FullDirBuffer;
00038     PFILE_BOTH_DIR_INFORMATION BothDirBuffer;
00039     ULONG InfoSize = 0;
00040     ULONG NameLength;
00041     ULONG CurrentOffset = 0;
00042     ULONG LastOffset = 0;
00043     PULONG NextEntryOffset;
00044 
00045     Stack = IoGetCurrentIrpStackLocation(Irp);
00046 
00047     /* Obtain the callers parameters */
00048     BufferLength = Stack->Parameters.QueryDirectory.Length;
00049     SearchPattern = Stack->Parameters.QueryDirectory.FileName;
00050     FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
00051     FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
00052 
00053     DPRINT("SearchPattern: %p  '%wZ'\n", SearchPattern, SearchPattern);
00054 
00055     /* Determine Buffer for result */
00056     if (Irp->MdlAddress)
00057     {
00058         Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
00059     }
00060     else
00061     {
00062         Buffer = Irp->UserBuffer;
00063     }
00064 
00065     /* Build the search pattern string */
00066     DPRINT("Ccb->u.Directory.SearchPattern.Buffer: %p\n", Ccb->u.Directory.SearchPattern.Buffer);
00067     if (Ccb->u.Directory.SearchPattern.Buffer == NULL)
00068     {
00069         First = TRUE;
00070 
00071         if (SearchPattern != NULL)
00072         {
00073             Ccb->u.Directory.SearchPattern.Buffer =
00074                 ExAllocatePoolWithTag(NonPagedPool,
00075                                       SearchPattern->Length + sizeof(WCHAR),
00076                                       TAG_NPFS_NAMEBLOCK);
00077             if (Ccb->u.Directory.SearchPattern.Buffer == NULL)
00078             {
00079                 return STATUS_INSUFFICIENT_RESOURCES;
00080             }
00081 
00082             Ccb->u.Directory.SearchPattern.Length = SearchPattern->Length;
00083             Ccb->u.Directory.SearchPattern.MaximumLength = SearchPattern->Length + sizeof(WCHAR);
00084             RtlCopyMemory(Ccb->u.Directory.SearchPattern.Buffer,
00085                           SearchPattern->Buffer,
00086                           SearchPattern->Length);
00087             Ccb->u.Directory.SearchPattern.Buffer[SearchPattern->Length / sizeof(WCHAR)] = 0;
00088         }
00089         else
00090         {
00091             Ccb->u.Directory.SearchPattern.Buffer =
00092                 ExAllocatePoolWithTag(NonPagedPool,
00093                                       2 * sizeof(WCHAR),
00094                                       TAG_NPFS_NAMEBLOCK);
00095             if (Ccb->u.Directory.SearchPattern.Buffer == NULL)
00096             {
00097                 return STATUS_INSUFFICIENT_RESOURCES;
00098             }
00099 
00100             Ccb->u.Directory.SearchPattern.Length = sizeof(WCHAR);
00101             Ccb->u.Directory.SearchPattern.MaximumLength = 2 * sizeof(WCHAR);
00102             Ccb->u.Directory.SearchPattern.Buffer[0] = L'*';
00103             Ccb->u.Directory.SearchPattern.Buffer[1] = 0;
00104         }
00105     }
00106     DPRINT("Search pattern: '%wZ'\n", &Ccb->u.Directory.SearchPattern);
00107 
00108     /* Determine the file index */
00109     if (First || (Stack->Flags & SL_RESTART_SCAN))
00110     {
00111         FileIndex = 0;
00112     }
00113     else if ((Stack->Flags & SL_INDEX_SPECIFIED) == 0)
00114     {
00115         FileIndex = Ccb->u.Directory.FileIndex + 1;
00116     }
00117     DPRINT("FileIndex: %lu\n", FileIndex);
00118 
00119     DPRINT("Buffer = %p  tofind = %wZ\n", Buffer, &Ccb->u.Directory.SearchPattern);
00120 
00121     switch (FileInformationClass)
00122     {
00123         case FileDirectoryInformation:
00124             InfoSize = sizeof(FILE_DIRECTORY_INFORMATION) - sizeof(WCHAR);
00125             break;
00126 
00127         case FileFullDirectoryInformation:
00128             InfoSize = sizeof(FILE_FULL_DIR_INFORMATION) - sizeof(WCHAR);
00129             break;
00130 
00131         case FileBothDirectoryInformation:
00132             InfoSize = sizeof(FILE_BOTH_DIR_INFORMATION) - sizeof(WCHAR);
00133             break;
00134 
00135         case FileNamesInformation:
00136             InfoSize = sizeof(FILE_NAMES_INFORMATION) - sizeof(WCHAR);
00137             break;
00138 
00139         default:
00140             DPRINT1("Invalid information class: %lu\n", FileInformationClass);
00141             return STATUS_INVALID_INFO_CLASS;
00142     }
00143 
00144     PipeIndex = 0;
00145 
00146     Vcb = Ccb->Fcb->Vcb;
00147     CurrentEntry = Vcb->PipeListHead.Flink;
00148     while (CurrentEntry != &Vcb->PipeListHead &&
00149            Status == STATUS_SUCCESS)
00150     {
00151         /* Get the FCB of the next pipe */
00152         PipeFcb = CONTAINING_RECORD(CurrentEntry,
00153                                     NPFS_FCB,
00154                                     PipeListEntry);
00155 
00156         /* Make sure it is a pipe FCB */
00157         ASSERT(PipeFcb->Type == FCB_PIPE);
00158 
00159         DPRINT("PipeName: %wZ\n", &PipeFcb->PipeName);
00160 
00161         if (FsRtlIsNameInExpression(&Ccb->u.Directory.SearchPattern,
00162                                     &PipeFcb->PipeName,
00163                                     TRUE,
00164                                     NULL))
00165         {
00166             DPRINT("Found pipe: %wZ\n", &PipeFcb->PipeName);
00167 
00168             if (PipeIndex >= FileIndex)
00169             {
00170                 /* Determine whether or not the full pipe name fits into the buffer */
00171                 if (InfoSize + PipeFcb->PipeName.Length > BufferLength)
00172                 {
00173                     NameLength = BufferLength - InfoSize;
00174                     Status = STATUS_BUFFER_OVERFLOW;
00175                 }
00176                 else
00177                 {
00178                     NameLength = PipeFcb->PipeName.Length;
00179                     Status = STATUS_SUCCESS;
00180                 }
00181 
00182                 /* Initialize the information struct */
00183                 RtlZeroMemory(&Buffer[CurrentOffset], InfoSize);
00184 
00185                 switch (FileInformationClass)
00186                 {
00187                     case FileDirectoryInformation:
00188                         DirectoryBuffer = (PFILE_DIRECTORY_INFORMATION)&Buffer[CurrentOffset];
00189                         DirectoryBuffer->FileIndex = PipeIndex;
00190                         DirectoryBuffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
00191                         DirectoryBuffer->EndOfFile.QuadPart = PipeFcb->CurrentInstances;
00192                         DirectoryBuffer->AllocationSize.LowPart = PipeFcb->MaximumInstances;
00193                         DirectoryBuffer->FileNameLength = NameLength;
00194                         RtlCopyMemory(DirectoryBuffer->FileName,
00195                                       PipeFcb->PipeName.Buffer,
00196                                       NameLength);
00197                         break;
00198 
00199                     case FileFullDirectoryInformation:
00200                         FullDirBuffer = (PFILE_FULL_DIR_INFORMATION)&Buffer[CurrentOffset];
00201                         FullDirBuffer->FileIndex = PipeIndex;
00202                         FullDirBuffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
00203                         FullDirBuffer->EndOfFile.QuadPart = PipeFcb->CurrentInstances;
00204                         FullDirBuffer->AllocationSize.LowPart = PipeFcb->MaximumInstances;
00205                         FullDirBuffer->FileNameLength = NameLength;
00206                         RtlCopyMemory(FullDirBuffer->FileName,
00207                                       PipeFcb->PipeName.Buffer,
00208                                       NameLength);
00209                         break;
00210 
00211                     case FileBothDirectoryInformation:
00212                         BothDirBuffer = (PFILE_BOTH_DIR_INFORMATION)&Buffer[CurrentOffset];
00213                         BothDirBuffer->NextEntryOffset = 0;
00214                         BothDirBuffer->FileIndex = PipeIndex;
00215                         BothDirBuffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
00216                         BothDirBuffer->EndOfFile.QuadPart = PipeFcb->CurrentInstances;
00217                         BothDirBuffer->AllocationSize.LowPart = PipeFcb->MaximumInstances;
00218                         BothDirBuffer->FileNameLength = NameLength;
00219                         RtlCopyMemory(BothDirBuffer->FileName,
00220                                       PipeFcb->PipeName.Buffer,
00221                                       NameLength);
00222                         break;
00223 
00224                     case FileNamesInformation:
00225                         NamesBuffer = (PFILE_NAMES_INFORMATION)&Buffer[CurrentOffset];
00226                         NamesBuffer->FileIndex = PipeIndex;
00227                         NamesBuffer->FileNameLength = NameLength;
00228                         RtlCopyMemory(NamesBuffer->FileName,
00229                                       PipeFcb->PipeName.Buffer,
00230                                       NameLength);
00231                         break;
00232 
00233                     default:
00234                         /* Should never happen! */
00235                         ASSERT(FALSE);
00236                         break;
00237                 }
00238 
00239                 DPRINT("CurrentOffset: %lu\n", CurrentOffset);
00240 
00241                 /* Store the current pipe index in the CCB */
00242                 Ccb->u.Directory.FileIndex = PipeIndex;
00243 
00244                 /* Get the pointer to the previous entries NextEntryOffset */
00245                 NextEntryOffset = (PULONG)&Buffer[LastOffset];
00246 
00247                 /* Set the previous entries NextEntryOffset */
00248                 *NextEntryOffset = CurrentOffset - LastOffset;
00249 
00250                 /* Return the used buffer size */
00251                 *Size = CurrentOffset + InfoSize + NameLength;
00252 
00253                 /* Leave, if there is no space left in the buffer */
00254                 if (Status == STATUS_BUFFER_OVERFLOW)
00255                     return Status;
00256 
00257                 /* Leave, if we should return only one entry */
00258                 if (Stack->Flags & SL_RETURN_SINGLE_ENTRY)
00259                     return STATUS_SUCCESS;
00260 
00261                 /* Store the current offset for the next round */
00262                 LastOffset = CurrentOffset;
00263 
00264                 /* Set the offset for the next entry */
00265                 CurrentOffset += ROUND_UP(InfoSize + NameLength, sizeof(ULONG));
00266             }
00267 
00268             PipeIndex++;
00269         }
00270 
00271         CurrentEntry = CurrentEntry->Flink;
00272     }
00273 
00274     /* Return STATUS_NO_MORE_FILES if no matching pipe name was found */
00275     if (CurrentOffset == 0)
00276         Status = STATUS_NO_MORE_FILES;
00277 
00278     return Status;
00279 }
00280 
00281 
00282 NTSTATUS NTAPI
00283 NpfsDirectoryControl(PDEVICE_OBJECT DeviceObject,
00284                      PIRP Irp)
00285 {
00286     PIO_STACK_LOCATION IoStack;
00287     PFILE_OBJECT FileObject;
00288     PNPFS_CCB Ccb;
00289     //PNPFS_FCB Fcb;
00290     NTSTATUS Status;
00291     ULONG Size = 0;
00292 
00293     DPRINT("NpfsDirectoryControl() called\n");
00294 
00295     IoStack = IoGetCurrentIrpStackLocation(Irp);
00296 
00297     FileObject = IoStack->FileObject;
00298 
00299     if (NpfsGetCcb(FileObject, &Ccb) != CCB_DIRECTORY)
00300     {
00301         Status = STATUS_INVALID_PARAMETER;
00302 
00303         Irp->IoStatus.Status = Status;
00304         Irp->IoStatus.Information = 0;
00305 
00306         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00307 
00308         return Status;
00309     }
00310 
00311     //Fcb = Ccb->Fcb;
00312 
00313     switch (IoStack->MinorFunction)
00314     {
00315         case IRP_MN_QUERY_DIRECTORY:
00316             Status = NpfsQueryDirectory(Ccb,
00317                                         Irp,
00318                                         &Size);
00319             break;
00320 
00321         case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
00322             DPRINT1("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n");
00323             Status = STATUS_NOT_IMPLEMENTED;
00324             break;
00325 
00326         default:
00327             DPRINT1("NPFS: MinorFunction %d\n", IoStack->MinorFunction);
00328             Status = STATUS_INVALID_DEVICE_REQUEST;
00329             break;
00330     }
00331 
00332     Irp->IoStatus.Status = Status;
00333     Irp->IoStatus.Information = Size;
00334 
00335     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00336 
00337     return Status;
00338 }
00339 
00340 /* EOF */

Generated on Sat May 26 2012 04:26:05 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.