/* FUNCTIONS ****************************************************************/
-static PWCHAR
-CdfsGetNextPathElement(PWCHAR FileName)
+static BOOLEAN
+CdfsGetNextPathElement(PCUNICODE_STRING CurrentElement, PUNICODE_STRING NextElement)
{
- if (*FileName == L'\0')
- {
- return(NULL);
- }
+ *NextElement = *CurrentElement;
+
+ if (NextElement->Length == 0)
+ return FALSE;
- while (*FileName != L'\0' && *FileName != L'\\')
+ while ((NextElement->Length) && (NextElement->Buffer[0] != L'\\'))
{
- FileName++;
+ NextElement->Buffer++;
+ NextElement->Length -= sizeof(WCHAR);
+ NextElement->MaximumLength -= sizeof(WCHAR);
}
- return(FileName);
-}
-
-
-static VOID
-CdfsWSubString(LPWSTR pTarget, LPCWSTR pSource, size_t pLength)
-{
- wcsncpy (pTarget, pSource, pLength);
- pTarget [pLength] = L'\0';
+ return TRUE;
}
Fcb->RFCB.Resource = &Fcb->MainResource;
Fcb->RFCB.IsFastIoPossible = FastIoIsNotPossible;
InitializeListHead(&Fcb->ShortNameList);
+ FsRtlInitializeFileLock(&Fcb->FileLock, NULL, NULL);
return(Fcb);
}
{
PLIST_ENTRY Entry;
+ FsRtlUninitializeFileLock(&Fcb->FileLock);
ExDeleteResourceLite(&Fcb->PagingIoResource);
ExDeleteResourceLite(&Fcb->MainResource);
{
KIRQL oldIrql;
- DPRINT("grabbing FCB at %p: %S, refCount:%d\n",
+ DPRINT("grabbing FCB at %p: %wZ, refCount:%d\n",
Fcb,
- Fcb->PathName,
+ &Fcb->PathName,
Fcb->RefCount);
KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
{
Fcb = CONTAINING_RECORD(current_entry, FCB, FcbListEntry);
- DPRINT("Comparing '%wZ' and '%wZ'\n", FileName, &Fcb->PathName);
+ // Disabled the DPRINT! Can't be called at DISPATCH_LEVEL!
+ //DPRINT("Comparing '%wZ' and '%wZ'\n", FileName, &Fcb->PathName);
if (RtlCompareUnicodeString(FileName, &Fcb->PathName, TRUE) == 0)
{
Fcb->RefCount++;
}
-static VOID
-CdfsGetDirEntryName(PDEVICE_EXTENSION DeviceExt,
- PDIR_RECORD Record,
- PWSTR Name)
- /*
- * FUNCTION: Retrieves the file name from a directory record.
- */
-{
- if (Record->FileIdLength == 1 && Record->FileId[0] == 0)
- {
- wcscpy(Name, L".");
- }
- else if (Record->FileIdLength == 1 && Record->FileId[0] == 1)
- {
- wcscpy(Name, L"..");
- }
- else
- {
- if (DeviceExt->CdInfo.JolietLevel == 0)
- {
- ULONG i;
-
- for (i = 0; i < Record->FileIdLength && Record->FileId[i] != ';'; i++)
- Name[i] = (WCHAR)Record->FileId[i];
- Name[i] = 0;
- }
- else
- {
- CdfsSwapString(Name,
- Record->FileId,
- Record->FileIdLength);
- }
- }
-
- DPRINT("Name '%S'\n", Name);
-}
-
-
NTSTATUS
CdfsMakeFCBFromDirEntry(PVCB Vcb,
PFCB DirectoryFCB,
DirSize = DirectoryFcb->Entry.DataLengthL;
StreamOffset.QuadPart = (LONGLONG)DirectoryFcb->Entry.ExtentLocationL * (LONGLONG)BLOCKSIZE;
- if (!CcMapData(DeviceExt->StreamFileObject,
- &StreamOffset,
- BLOCKSIZE,
- TRUE,
- &Context,
- &Block))
+ _SEH2_TRY
+ {
+ CcMapData(DeviceExt->StreamFileObject, &StreamOffset, BLOCKSIZE, MAP_WAIT, &Context, &Block);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
DPRINT("CcMapData() failed\n");
- return STATUS_UNSUCCESSFUL;
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
+ _SEH2_END;
Offset = 0;
BlockOffset = 0;
DPRINT("RecordLength %u ExtAttrRecordLength %u NameLength %u\n",
Record->RecordLength, Record->ExtAttrRecordLength, Record->FileIdLength);
+ if (!CdfsIsRecordValid(DeviceExt, Record))
+ {
+ RtlFreeUnicodeString(&FileToFindUpcase);
+ CcUnpinData(Context);
+ return STATUS_DISK_CORRUPT_ERROR;
+ }
+
CdfsGetDirEntryName(DeviceExt, Record, Name);
DPRINT ("Name '%S'\n", Name);
DPRINT ("Sector %lu\n", DirectoryFcb->Entry.ExtentLocationL);
Offset = ROUND_UP(Offset, BLOCKSIZE);
BlockOffset = 0;
- if (!CcMapData(DeviceExt->StreamFileObject,
- &StreamOffset,
- BLOCKSIZE, TRUE,
- &Context, &Block))
+ _SEH2_TRY
+ {
+ CcMapData(DeviceExt->StreamFileObject, &StreamOffset, BLOCKSIZE, MAP_WAIT, &Context, &Block);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
DPRINT("CcMapData() failed\n");
RtlFreeUnicodeString(&FileToFindUpcase);
- return(STATUS_UNSUCCESSFUL);
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
+ _SEH2_END;
Record = (PDIR_RECORD)((ULONG_PTR)Block + BlockOffset);
}
PUNICODE_STRING FileName)
{
UNICODE_STRING PathName;
- UNICODE_STRING ElementName;
+ UNICODE_STRING NextElement;
+ UNICODE_STRING CurrentElement;
NTSTATUS Status;
- WCHAR pathName [MAX_PATH];
- WCHAR elementName [MAX_PATH];
- PWCHAR currentElement;
PFCB FCB;
PFCB parentFCB;
FileName);
/* Trivial case, open of the root directory on volume */
- if (FileName->Buffer[0] == L'\0' || wcscmp(FileName->Buffer, L"\\") == 0)
+ if (FileName->Length == 0 ||
+ ((FileName->Buffer[0] == '\\') && (FileName->Length == sizeof(WCHAR))))
{
DPRINT("returning root FCB\n");
}
else
{
- currentElement = &FileName->Buffer[1];
- wcscpy (pathName, L"\\");
+ /* Start with empty path */
+ PathName = *FileName;
+ PathName.Length = 0;
+ CurrentElement = *FileName;
+
FCB = CdfsOpenRootFCB (Vcb);
}
parentFCB = NULL;
- /* Parse filename and check each path element for existance and access */
- while (CdfsGetNextPathElement(currentElement) != 0)
+ /* Parse filename and check each path element for existence and access */
+ while (CdfsGetNextPathElement(&CurrentElement, &NextElement))
{
/* Skip blank directory levels */
- if ((CdfsGetNextPathElement(currentElement) - currentElement) == 0)
+ if (CurrentElement.Buffer[0] == L'\\')
{
- currentElement++;
+ CurrentElement.Buffer++;
+ CurrentElement.Length -= sizeof(WCHAR);
+ CurrentElement.MaximumLength -= sizeof(WCHAR);
continue;
}
- DPRINT("Parsing, currentElement:%S\n", currentElement);
+ DPRINT("Parsing, currentElement:%wZ\n", &CurrentElement);
DPRINT(" parentFCB:%p FCB:%p\n", parentFCB, FCB);
/* Descend to next directory level */
}
parentFCB = FCB;
- /* Extract next directory level into dirName */
- CdfsWSubString(pathName,
- FileName->Buffer,
- CdfsGetNextPathElement(currentElement) - FileName->Buffer);
- DPRINT(" pathName:%S\n", pathName);
-
- RtlInitUnicodeString(&PathName, pathName);
+ /* Extract next directory level */
+ PathName.Length = (NextElement.Buffer - FileName->Buffer) * sizeof(WCHAR);
+ DPRINT(" PathName:%wZ\n", &PathName);
FCB = CdfsGrabFCBFromTable(Vcb, &PathName);
if (FCB == NULL)
{
- CdfsWSubString(elementName,
- currentElement,
- CdfsGetNextPathElement(currentElement) - currentElement);
- DPRINT(" elementName:%S\n", elementName);
+ UNICODE_STRING ChildElement = CurrentElement;
+ ChildElement.Length = (NextElement.Buffer - CurrentElement.Buffer) * sizeof(WCHAR);
- RtlInitUnicodeString(&ElementName, elementName);
Status = CdfsDirFindFile(Vcb,
parentFCB,
- &ElementName,
+ &ChildElement,
&FCB);
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
{
*pParentFCB = parentFCB;
*pFCB = NULL;
- currentElement = CdfsGetNextPathElement(currentElement);
- if (*currentElement == L'\0' || CdfsGetNextPathElement(currentElement + 1) == 0)
+
+ if (NextElement.Length == 0)
{
return(STATUS_OBJECT_NAME_NOT_FOUND);
}
return(Status);
}
}
- currentElement = CdfsGetNextPathElement(currentElement);
+ CurrentElement = NextElement;
}
*pParentFCB = parentFCB;