Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendirctl.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 */ Generated on Sat May 26 2012 04:26:05 for ReactOS by
1.7.6.1
|