Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfcb.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2002 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/fcb.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 00037 /* MACROS *******************************************************************/ 00038 00039 #define TAG_FCB 'BCFI' 00040 00041 00042 00043 /* FUNCTIONS ****************************************************************/ 00044 00045 static PWCHAR 00046 NtfsGetNextPathElement(PWCHAR FileName) 00047 { 00048 if (*FileName == L'\0') 00049 { 00050 return(NULL); 00051 } 00052 00053 while (*FileName != L'\0' && *FileName != L'\\') 00054 { 00055 FileName++; 00056 } 00057 00058 return(FileName); 00059 } 00060 00061 00062 static VOID 00063 NtfsWSubString(PWCHAR pTarget, const PWCHAR pSource, size_t pLength) 00064 { 00065 wcsncpy (pTarget, pSource, pLength); 00066 pTarget [pLength] = L'\0'; 00067 } 00068 00069 00070 PNTFS_FCB 00071 NtfsCreateFCB(PCWSTR FileName, PNTFS_VCB Vcb) 00072 { 00073 PNTFS_FCB Fcb; 00074 00075 ASSERT(Vcb); 00076 ASSERT(Vcb->Identifier.Type == NTFS_TYPE_VCB); 00077 00078 Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_FCB), TAG_FCB); 00079 RtlZeroMemory(Fcb, sizeof(NTFS_FCB)); 00080 00081 Fcb->Identifier.Type = NTFS_TYPE_FCB; 00082 Fcb->Identifier.Size = sizeof(NTFS_TYPE_FCB); 00083 00084 Fcb->Vcb = Vcb; 00085 00086 if (FileName) 00087 { 00088 wcscpy(Fcb->PathName, FileName); 00089 if (wcsrchr(Fcb->PathName, '\\') != 0) 00090 { 00091 Fcb->ObjectName = wcsrchr(Fcb->PathName, '\\'); 00092 } 00093 else 00094 { 00095 Fcb->ObjectName = Fcb->PathName; 00096 } 00097 } 00098 00099 ExInitializeResourceLite(&Fcb->MainResource); 00100 00101 Fcb->RFCB.Resource = &(Fcb->MainResource); 00102 00103 return(Fcb); 00104 } 00105 00106 00107 VOID 00108 NtfsDestroyFCB(PNTFS_FCB Fcb) 00109 { 00110 ASSERT(Fcb); 00111 ASSERT(Fcb->Identifier.Type == NTFS_TYPE_FCB); 00112 00113 ExDeleteResourceLite(&Fcb->MainResource); 00114 00115 ExFreePool(Fcb); 00116 } 00117 00118 00119 BOOLEAN 00120 NtfsFCBIsDirectory(PNTFS_FCB Fcb) 00121 { 00122 // return(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY); 00123 // return(Fcb->Entry.FileFlags & 0x02); 00124 return(TRUE); 00125 } 00126 00127 00128 BOOLEAN 00129 NtfsFCBIsRoot(PNTFS_FCB Fcb) 00130 { 00131 return(wcscmp(Fcb->PathName, L"\\") == 0); 00132 } 00133 00134 00135 VOID 00136 NtfsGrabFCB(PNTFS_VCB Vcb, 00137 PNTFS_FCB Fcb) 00138 { 00139 KIRQL oldIrql; 00140 00141 DPRINT("grabbing FCB at %p: %S, refCount:%d\n", 00142 Fcb, 00143 Fcb->PathName, 00144 Fcb->RefCount); 00145 00146 KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql); 00147 Fcb->RefCount++; 00148 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); 00149 } 00150 00151 00152 VOID 00153 NtfsReleaseFCB(PNTFS_VCB Vcb, 00154 PNTFS_FCB Fcb) 00155 { 00156 KIRQL oldIrql; 00157 00158 DPRINT("releasing FCB at %p: %S, refCount:%d\n", 00159 Fcb, 00160 Fcb->PathName, 00161 Fcb->RefCount); 00162 00163 KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql); 00164 Fcb->RefCount--; 00165 if (Fcb->RefCount <= 0 && !NtfsFCBIsDirectory(Fcb)) 00166 { 00167 RemoveEntryList(&Fcb->FcbListEntry); 00168 CcUninitializeCacheMap(Fcb->FileObject, NULL, NULL); 00169 NtfsDestroyFCB(Fcb); 00170 } 00171 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); 00172 } 00173 00174 00175 VOID 00176 NtfsAddFCBToTable(PNTFS_VCB Vcb, 00177 PNTFS_FCB Fcb) 00178 { 00179 KIRQL oldIrql; 00180 00181 KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql); 00182 Fcb->Vcb = Vcb; 00183 InsertTailList(&Vcb->FcbListHead, &Fcb->FcbListEntry); 00184 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); 00185 } 00186 00187 00188 PNTFS_FCB 00189 NtfsGrabFCBFromTable(PNTFS_VCB Vcb, 00190 PCWSTR FileName) 00191 { 00192 KIRQL oldIrql; 00193 PNTFS_FCB Fcb; 00194 PLIST_ENTRY current_entry; 00195 00196 KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql); 00197 00198 if (FileName == NULL || *FileName == 0) 00199 { 00200 DPRINT("Return FCB for stream file object\n"); 00201 Fcb = Vcb->StreamFileObject->FsContext; 00202 Fcb->RefCount++; 00203 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); 00204 return(Fcb); 00205 } 00206 00207 current_entry = Vcb->FcbListHead.Flink; 00208 while (current_entry != &Vcb->FcbListHead) 00209 { 00210 Fcb = CONTAINING_RECORD(current_entry, NTFS_FCB, FcbListEntry); 00211 00212 DPRINT("Comparing '%S' and '%S'\n", FileName, Fcb->PathName); 00213 if (_wcsicmp(FileName, Fcb->PathName) == 0) 00214 { 00215 Fcb->RefCount++; 00216 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); 00217 return(Fcb); 00218 } 00219 00220 //FIXME: need to compare against short name in FCB here 00221 00222 current_entry = current_entry->Flink; 00223 } 00224 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); 00225 00226 return(NULL); 00227 } 00228 00229 00230 NTSTATUS 00231 NtfsFCBInitializeCache(PNTFS_VCB Vcb, 00232 PNTFS_FCB Fcb) 00233 { 00234 PFILE_OBJECT FileObject; 00235 NTSTATUS Status; 00236 PNTFS_CCB newCCB; 00237 00238 FileObject = IoCreateStreamFileObject(NULL, Vcb->StorageDevice); 00239 00240 newCCB = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_CCB), TAG_CCB); 00241 if (newCCB == NULL) 00242 { 00243 return(STATUS_INSUFFICIENT_RESOURCES); 00244 } 00245 RtlZeroMemory(newCCB, sizeof(NTFS_CCB)); 00246 00247 newCCB->Identifier.Type = NTFS_TYPE_CCB; 00248 newCCB->Identifier.Size = sizeof(NTFS_TYPE_CCB); 00249 00250 FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; 00251 FileObject->FsContext = Fcb; 00252 FileObject->FsContext2 = newCCB; 00253 newCCB->PtrFileObject = FileObject; 00254 Fcb->FileObject = FileObject; 00255 Fcb->Vcb = Vcb; 00256 00257 Status = STATUS_SUCCESS; 00258 CcInitializeCacheMap(FileObject, 00259 (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize), 00260 FALSE, 00261 &(NtfsGlobalData->CacheMgrCallbacks), 00262 Fcb); 00263 00264 ObDereferenceObject(FileObject); 00265 Fcb->Flags |= FCB_CACHE_INITIALIZED; 00266 00267 return(Status); 00268 } 00269 00270 00271 PNTFS_FCB 00272 NtfsMakeRootFCB(PNTFS_VCB Vcb) 00273 { 00274 PNTFS_FCB Fcb; 00275 00276 Fcb = NtfsCreateFCB(L"\\", Vcb); 00277 00278 // memset(Fcb->entry.Filename, ' ', 11); 00279 00280 // Fcb->Entry.DataLengthL = Vcb->CdInfo.RootSize; 00281 // Fcb->Entry.ExtentLocationL = Vcb->CdInfo.RootStart; 00282 // Fcb->Entry.FileFlags = 0x02; // FILE_ATTRIBUTE_DIRECTORY; 00283 Fcb->RefCount = 1; 00284 Fcb->DirIndex = 0; 00285 Fcb->RFCB.FileSize.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize; 00286 Fcb->RFCB.ValidDataLength.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize; 00287 Fcb->RFCB.AllocationSize.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize; 00288 00289 NtfsFCBInitializeCache(Vcb, Fcb); 00290 NtfsAddFCBToTable(Vcb, Fcb); 00291 NtfsGrabFCB(Vcb, Fcb); 00292 00293 return(Fcb); 00294 } 00295 00296 00297 PNTFS_FCB 00298 NtfsOpenRootFCB(PNTFS_VCB Vcb) 00299 { 00300 PNTFS_FCB Fcb; 00301 00302 Fcb = NtfsGrabFCBFromTable(Vcb, L"\\"); 00303 if (Fcb == NULL) 00304 { 00305 Fcb = NtfsMakeRootFCB(Vcb); 00306 } 00307 00308 return(Fcb); 00309 } 00310 00311 00312 #if 0 00313 static VOID 00314 NtfsGetDirEntryName(PDEVICE_EXTENSION DeviceExt, 00315 PDIR_RECORD Record, 00316 PWSTR Name) 00317 /* 00318 * FUNCTION: Retrieves the file name, be it in short or long file name format 00319 */ 00320 { 00321 if (Record->FileIdLength == 1 && Record->FileId[0] == 0) 00322 { 00323 wcscpy(Name, L"."); 00324 } 00325 else if (Record->FileIdLength == 1 && Record->FileId[0] == 1) 00326 { 00327 wcscpy(Name, L".."); 00328 } 00329 else 00330 { 00331 if (DeviceExt->CdInfo.JolietLevel == 0) 00332 { 00333 ULONG i; 00334 00335 for (i = 0; i < Record->FileIdLength && Record->FileId[i] != ';'; i++) 00336 Name[i] = (WCHAR)Record->FileId[i]; 00337 Name[i] = 0; 00338 } 00339 else 00340 { 00341 NtfsSwapString(Name, Record->FileId, Record->FileIdLength); 00342 } 00343 } 00344 00345 DPRINT("Name '%S'\n", Name); 00346 } 00347 00348 00349 NTSTATUS 00350 NtfsMakeFCBFromDirEntry(PVCB Vcb, 00351 PFCB DirectoryFCB, 00352 PWSTR Name, 00353 PDIR_RECORD Record, 00354 PFCB * fileFCB) 00355 { 00356 WCHAR pathName[MAX_PATH]; 00357 PFCB rcFCB; 00358 ULONG Size; 00359 00360 if (Name [0] != 0 && wcslen (DirectoryFCB->PathName) + 00361 sizeof(WCHAR) + wcslen (Name) > MAX_PATH) 00362 { 00363 return(STATUS_OBJECT_NAME_INVALID); 00364 } 00365 00366 wcscpy(pathName, DirectoryFCB->PathName); 00367 if (!NtfsFCBIsRoot(DirectoryFCB)) 00368 { 00369 wcscat(pathName, L"\\"); 00370 } 00371 00372 if (Name[0] != 0) 00373 { 00374 wcscat(pathName, Name); 00375 } 00376 else 00377 { 00378 WCHAR entryName[MAX_PATH]; 00379 00380 NtfsGetDirEntryName(Vcb, Record, entryName); 00381 wcscat(pathName, entryName); 00382 } 00383 00384 rcFCB = NtfsCreateFCB(pathName, Vcb); 00385 memcpy(&rcFCB->Entry, Record, sizeof(DIR_RECORD)); 00386 00387 Size = rcFCB->Entry.DataLengthL; 00388 00389 rcFCB->RFCB.FileSize.QuadPart = Size; 00390 rcFCB->RFCB.ValidDataLength.QuadPart = Size; 00391 rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, BLOCKSIZE); 00392 // DPRINT1("%S %d %d\n", longName, Size, (ULONG)rcFCB->RFCB.AllocationSize.QuadPart); 00393 NtfsFCBInitializeCache(Vcb, rcFCB); 00394 rcFCB->RefCount++; 00395 NtfsAddFCBToTable(Vcb, rcFCB); 00396 *fileFCB = rcFCB; 00397 00398 return(STATUS_SUCCESS); 00399 } 00400 #endif 00401 00402 00403 NTSTATUS 00404 NtfsAttachFCBToFileObject(PNTFS_VCB Vcb, 00405 PNTFS_FCB Fcb, 00406 PFILE_OBJECT FileObject) 00407 { 00408 PNTFS_CCB newCCB; 00409 00410 newCCB = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_CCB), TAG_CCB); 00411 if (newCCB == NULL) 00412 { 00413 return(STATUS_INSUFFICIENT_RESOURCES); 00414 } 00415 RtlZeroMemory(newCCB, sizeof(NTFS_CCB)); 00416 00417 newCCB->Identifier.Type = NTFS_TYPE_CCB; 00418 newCCB->Identifier.Size = sizeof(NTFS_TYPE_CCB); 00419 00420 FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; 00421 FileObject->FsContext = Fcb; 00422 FileObject->FsContext2 = newCCB; 00423 newCCB->PtrFileObject = FileObject; 00424 Fcb->Vcb = Vcb; 00425 00426 if (!(Fcb->Flags & FCB_CACHE_INITIALIZED)) 00427 { 00428 CcInitializeCacheMap(FileObject, 00429 (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize), 00430 FALSE, 00431 NULL, 00432 NULL); 00433 00434 Fcb->Flags |= FCB_CACHE_INITIALIZED; 00435 } 00436 00437 //DPRINT("file open: fcb:%x file size: %d\n", Fcb, Fcb->Entry.DataLengthL); 00438 00439 return(STATUS_SUCCESS); 00440 } 00441 00442 00443 static NTSTATUS 00444 NtfsDirFindFile(PNTFS_VCB Vcb, 00445 PNTFS_FCB DirectoryFcb, 00446 PWSTR FileToFind, 00447 PNTFS_FCB *FoundFCB) 00448 { 00449 #if 0 00450 WCHAR TempName[2]; 00451 WCHAR Name[256]; 00452 PVOID Block; 00453 ULONG FirstSector; 00454 ULONG DirSize; 00455 PDIR_RECORD Record; 00456 ULONG Offset; 00457 ULONG BlockOffset; 00458 NTSTATUS Status; 00459 00460 LARGE_INTEGER StreamOffset; 00461 PVOID Context; 00462 00463 ASSERT(DeviceExt); 00464 ASSERT(DirectoryFcb); 00465 ASSERT(FileToFind); 00466 00467 DPRINT("NtfsDirFindFile(VCB:%08x, dirFCB:%08x, File:%S)\n", 00468 DeviceExt, 00469 DirectoryFcb, 00470 FileToFind); 00471 DPRINT("Dir Path:%S\n", DirectoryFcb->PathName); 00472 00473 /* default to '.' if no filename specified */ 00474 if (wcslen(FileToFind) == 0) 00475 { 00476 TempName[0] = L'.'; 00477 TempName[1] = 0; 00478 FileToFind = TempName; 00479 } 00480 00481 DirSize = DirectoryFcb->Entry.DataLengthL; 00482 StreamOffset.QuadPart = (LONGLONG)DirectoryFcb->Entry.ExtentLocationL * (LONGLONG)BLOCKSIZE; 00483 00484 if(!CcMapData(DeviceExt->StreamFileObject, &StreamOffset, 00485 BLOCKSIZE, TRUE, &Context, &Block)) 00486 { 00487 DPRINT("CcMapData() failed\n"); 00488 return(STATUS_UNSUCCESSFUL); 00489 } 00490 00491 Offset = 0; 00492 BlockOffset = 0; 00493 Record = (PDIR_RECORD)Block; 00494 while(TRUE) 00495 { 00496 if (Record->RecordLength == 0) 00497 { 00498 DPRINT("RecordLength == 0 Stopped!\n"); 00499 break; 00500 } 00501 00502 DPRINT("RecordLength %u ExtAttrRecordLength %u NameLength %u\n", 00503 Record->RecordLength, Record->ExtAttrRecordLength, Record->FileIdLength); 00504 00505 NtfsGetDirEntryName(DeviceExt, Record, Name); 00506 DPRINT("Name '%S'\n", Name); 00507 00508 if (wstrcmpjoki(Name, FileToFind)) 00509 { 00510 DPRINT("Match found, %S\n", Name); 00511 Status = NtfsMakeFCBFromDirEntry(DeviceExt, 00512 DirectoryFcb, 00513 Name, 00514 Record, 00515 FoundFCB); 00516 00517 CcUnpinData(Context); 00518 00519 return(Status); 00520 } 00521 00522 Offset += Record->RecordLength; 00523 BlockOffset += Record->RecordLength; 00524 Record = (PDIR_RECORD)(Block + BlockOffset); 00525 if (BlockOffset >= BLOCKSIZE || Record->RecordLength == 0) 00526 { 00527 DPRINT("Map next sector\n"); 00528 CcUnpinData(Context); 00529 StreamOffset.QuadPart += BLOCKSIZE; 00530 Offset = ROUND_UP(Offset, BLOCKSIZE); 00531 BlockOffset = 0; 00532 00533 if (!CcMapData(DeviceExt->StreamFileObject, 00534 &StreamOffset, 00535 BLOCKSIZE, TRUE, 00536 &Context, &Block)) 00537 { 00538 DPRINT("CcMapData() failed\n"); 00539 return(STATUS_UNSUCCESSFUL); 00540 } 00541 Record = (PDIR_RECORD)(Block + BlockOffset); 00542 } 00543 00544 if (Offset >= DirSize) 00545 break; 00546 } 00547 00548 CcUnpinData(Context); 00549 #endif 00550 return(STATUS_OBJECT_NAME_NOT_FOUND); 00551 } 00552 00553 00554 NTSTATUS 00555 NtfsGetFCBForFile(PNTFS_VCB Vcb, 00556 PNTFS_FCB *pParentFCB, 00557 PNTFS_FCB *pFCB, 00558 const PWSTR pFileName) 00559 { 00560 NTSTATUS Status; 00561 WCHAR pathName [MAX_PATH]; 00562 WCHAR elementName [MAX_PATH]; 00563 PWCHAR currentElement; 00564 PNTFS_FCB FCB; 00565 PNTFS_FCB parentFCB; 00566 00567 DPRINT("NtfsGetFCBForFile(%p, %p, %p, '%S')\n", 00568 Vcb, 00569 pParentFCB, 00570 pFCB, 00571 pFileName); 00572 00573 /* Dummy code */ 00574 // FCB = NtfsOpenRootFCB(Vcb); 00575 // *pFCB = FCB; 00576 // *pParentFCB = NULL; 00577 00578 #if 1 00579 /* Trivial case, open of the root directory on volume */ 00580 if (pFileName [0] == L'\0' || wcscmp(pFileName, L"\\") == 0) 00581 { 00582 DPRINT("returning root FCB\n"); 00583 00584 FCB = NtfsOpenRootFCB(Vcb); 00585 *pFCB = FCB; 00586 *pParentFCB = NULL; 00587 00588 return((FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND); 00589 } 00590 else 00591 { 00592 currentElement = pFileName + 1; 00593 wcscpy (pathName, L"\\"); 00594 FCB = NtfsOpenRootFCB (Vcb); 00595 } 00596 parentFCB = NULL; 00597 00598 /* Parse filename and check each path element for existance and access */ 00599 while (NtfsGetNextPathElement(currentElement) != 0) 00600 { 00601 /* Skip blank directory levels */ 00602 if ((NtfsGetNextPathElement(currentElement) - currentElement) == 0) 00603 { 00604 currentElement++; 00605 continue; 00606 } 00607 00608 DPRINT("Parsing, currentElement:%S\n", currentElement); 00609 DPRINT(" parentFCB:%p FCB:%p\n", parentFCB, FCB); 00610 00611 /* Descend to next directory level */ 00612 if (parentFCB) 00613 { 00614 NtfsReleaseFCB(Vcb, parentFCB); 00615 parentFCB = NULL; 00616 } 00617 00618 /* fail if element in FCB is not a directory */ 00619 if (!NtfsFCBIsDirectory(FCB)) 00620 { 00621 DPRINT("Element in requested path is not a directory\n"); 00622 00623 NtfsReleaseFCB(Vcb, FCB); 00624 FCB = 0; 00625 *pParentFCB = NULL; 00626 *pFCB = NULL; 00627 00628 return(STATUS_OBJECT_PATH_NOT_FOUND); 00629 } 00630 parentFCB = FCB; 00631 00632 /* Extract next directory level into dirName */ 00633 NtfsWSubString(pathName, 00634 pFileName, 00635 NtfsGetNextPathElement(currentElement) - pFileName); 00636 DPRINT(" pathName:%S\n", pathName); 00637 00638 FCB = NtfsGrabFCBFromTable(Vcb, pathName); 00639 if (FCB == NULL) 00640 { 00641 NtfsWSubString(elementName, 00642 currentElement, 00643 NtfsGetNextPathElement(currentElement) - currentElement); 00644 DPRINT(" elementName:%S\n", elementName); 00645 00646 Status = NtfsDirFindFile(Vcb, parentFCB, elementName, &FCB); 00647 if (Status == STATUS_OBJECT_NAME_NOT_FOUND) 00648 { 00649 *pParentFCB = parentFCB; 00650 *pFCB = NULL; 00651 currentElement = NtfsGetNextPathElement(currentElement); 00652 if (*currentElement == L'\0' || NtfsGetNextPathElement(currentElement + 1) == 0) 00653 { 00654 return(STATUS_OBJECT_NAME_NOT_FOUND); 00655 } 00656 else 00657 { 00658 return(STATUS_OBJECT_PATH_NOT_FOUND); 00659 } 00660 } 00661 else if (!NT_SUCCESS(Status)) 00662 { 00663 NtfsReleaseFCB(Vcb, parentFCB); 00664 *pParentFCB = NULL; 00665 *pFCB = NULL; 00666 00667 return(Status); 00668 } 00669 } 00670 currentElement = NtfsGetNextPathElement(currentElement); 00671 } 00672 00673 *pParentFCB = parentFCB; 00674 *pFCB = FCB; 00675 #endif 00676 00677 return(STATUS_SUCCESS); 00678 } 00679 00680 /* EOF */ Generated on Sat May 26 2012 04:26:11 for ReactOS by
1.7.6.1
|