예제 #1
0
파일: file.c 프로젝트: Strongc/reactos
NTSTATUS
BlFileOpen (
    _In_ ULONG DeviceId,
    _In_ PWCHAR FileName,
    _In_ ULONG Flags,
    _Out_ PULONG FileId
    )
{
    NTSTATUS Status;
    PBL_FILE_ENTRY FileEntry;
    BL_DEVICE_INFORMATION DeviceInformation;

    /* Make sure we have a valid file name, access flags and parameters */
    if (!(FileName) ||
        (*FileName != OBJ_NAME_PATH_SEPARATOR) ||
        !(FileId) ||
        !(Flags & (BL_FILE_READ_ACCESS | BL_FILE_WRITE_ACCESS)))
    {
        EfiPrintf(L"Invalid file options\r\n");
        return STATUS_INVALID_PARAMETER;
    }

    /* Get information on the underlying device */
    Status = BlDeviceGetInformation(DeviceId, &DeviceInformation);
    if (!NT_SUCCESS(Status))
    {
        EfiPrintf(L"Get device info failed: %lx\r\n", Status);
        return Status;
    }

    /* Make sure it's a device that can host files */
    if ((DeviceInformation.DeviceType != DiskDevice) &&
        (DeviceInformation.DeviceType != LegacyPartitionDevice) &&
        (DeviceInformation.DeviceType != UdpDevice))
    {
        EfiPrintf(L"Invalid device type\r\n");
        return STATUS_INVALID_PARAMETER;
    }

    /* Open a file on this device, creating one if needed */
    Status = FileIoOpen(DeviceId,
                        FileName,
                        Flags,
                        0,
                        FileTableCompareWithSameAttributes,
                        &FileEntry);
    if (NT_SUCCESS(Status))
    {
        /* Return the file ID back to the caller */
        EfiPrintf(L"File opened: %lx\r\n", FileEntry->FileId);
        *FileId = FileEntry->FileId;
    }

    /* All good */
    return Status;
}
예제 #2
0
NS_IMETHODIMP
morkStdioFile::Steal(nsIMdbEnv* ev, nsIMdbFile* ioThief)
  // If this file is a file version branch created by calling AcquireBud(),
  // BecomeTrunk() causes this file's content to replace the original
  // file's content, typically by assuming the original file's identity.
{
  morkEnv *mev = morkEnv::FromMdbEnv(ev);
  if ( mStdioFile_File && FileActive() && FileIoOpen() )
  {
    FILE* file = (FILE*) mStdioFile_File;
    if ( MORK_FILECLOSE(file) < 0 )
      new_stdio_file_fault(mev);
    
    mStdioFile_File = 0;
  }
  SetThief(mev, ioThief);
  return NS_OK;
}
예제 #3
0
파일: file.c 프로젝트: Strongc/reactos
NTSTATUS
FileIoOpen (
    _In_ ULONG DeviceId,
    _In_ PWCHAR FileName,
    _In_ ULONG Flags,
    _In_ ULONG Unknown,
    _In_ PBL_TBL_LOOKUP_ROUTINE CompareRoutine,
    _Out_opt_ PBL_FILE_ENTRY *NewFileEntry
    )
{
    PWCHAR FileNameCopy, ParentFileName;
    NTSTATUS Status;
    PBL_DEVICE_ENTRY DeviceEntry;
    PBL_FILE_SYSTEM_ENTRY FileSystem;
    ULONG FileId, CheckFlags;
    PBL_FILE_ENTRY DirectoryEntry, FileEntry;
    PLIST_ENTRY NextEntry, ListHead;

    /* Preinitialize variables for failure */
    DirectoryEntry = NULL;
    FileNameCopy = NULL;
    ParentFileName = NULL;
    Status = STATUS_SUCCESS;

    /* Bail out if the device ID is invalid */
    if (DmTableEntries <= DeviceId)
    {
        return STATUS_ACCESS_DENIED;
    }

    /* Bail out if there's no device entry */
    DeviceEntry = DmDeviceTable[DeviceId];
    if (!DeviceEntry)
    {
        return STATUS_ACCESS_DENIED;
    }

    /* Read access is always required for touching the device */
    CheckFlags = Flags | BL_FILE_READ_ACCESS;

    /* Check if the device is granting us read access */
    if ((CheckFlags & BL_FILE_READ_ACCESS) &&
        (!(DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED) ||
         !(DeviceEntry->Flags & BL_DEVICE_ENTRY_READ_ACCESS)))
    {
        EfiPrintf(L"Access denied\r\n");
        return STATUS_ACCESS_DENIED;
    }

    /* Check if the device is granting us write access */
    if ((CheckFlags & BL_FILE_WRITE_ACCESS) &&
        (!(DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED) ||
         !(DeviceEntry->Flags & BL_DEVICE_ENTRY_WRITE_ACCESS)))
    {
        EfiPrintf(L"Access denied2\r\n");
        return STATUS_ACCESS_DENIED;
    }

    /* Check if we already have this file open */
    FileEntry = (PBL_FILE_ENTRY )BlTblFindEntry(FileTable,
                                                FileEntries,
                                                &FileId,
                                                CompareRoutine,
                                                &DeviceId,
                                                FileName,
                                                &Flags,
                                                &Unknown);
    if (FileEntry)
    {
        EfiPrintf(L"Entry exists: %p\n", FileEntry);
        goto FileOpened;
    }

    /* Check if we are opening the root drive or an actual file/directory */
    if ((*FileName != OBJ_NAME_PATH_SEPARATOR) || (FileName[1]))
    {
        /* Get the name of the directory */
        ParentFileName = FileIoCopyParentDirectoryPath(FileName);
        if (!ParentFileName)
        {
            Status = STATUS_NO_MEMORY;
            goto Quickie;
        }

        /* Open it */
        Status = FileIoOpen(DeviceId,
                            ParentFileName,
                            BL_FILE_READ_ACCESS | BL_DIRECTORY_ACCESS,
                            Unknown,
                            FileTableCompareWithSubsetAttributes,
                            &DirectoryEntry);
        if (!NT_SUCCESS(Status))
        {
            goto Quickie;
        }

        /* Now get the the file name itself */
        FileNameCopy = FileIoCopyFileName(FileName);
        if (!FileNameCopy)
        {
            Status = STATUS_NO_MEMORY;
            goto Quickie;
        }

        /* Open it */
        Status = DirectoryEntry->Callbacks.Open(DirectoryEntry,
                                                FileNameCopy,
                                                Flags,
                                                &FileEntry);
    }
    else
    {
        /* We're opening the root, scan through all the file systems */
        Status = STATUS_UNSUCCESSFUL;
        ListHead = &RegisteredFileSystems;
        NextEntry = ListHead->Flink;
        while (NextEntry != ListHead)
        {
            /* Try to mount this one */
            FileSystem = CONTAINING_RECORD(NextEntry, BL_FILE_SYSTEM_ENTRY, ListEntry);
            Status = FileSystem->MountCallback(DeviceId, Unknown, &FileEntry);
            if (NT_SUCCESS(Status))
            {
                /* Mount successful */
                break;
            }

            /* Try the next file system */
            NextEntry = NextEntry->Flink;
        }

        /* Nothing to free on this path */
        FileNameCopy = NULL;
    }

    /* Handle failure */
    if (!NT_SUCCESS(Status))
    {
        EfiPrintf(L"Could not open file!: %lx\r\n", Status);
        goto Quickie;
    }

    /* Save the unknown */
    FileEntry->Unknown = Unknown;

    /* Convert open flags into entry flags */
    if (Flags & BL_FILE_READ_ACCESS)
    {
        FileEntry->Flags |= BL_FILE_ENTRY_READ_ACCESS;
    }
    if (Flags & BL_FILE_WRITE_ACCESS)
    {
        FileEntry->Flags |= BL_FILE_ENTRY_WRITE_ACCESS;
    }

    /* Save the file into the file table */
    Status = BlTblSetEntry(&FileTable,
                           &FileEntries,
                           (PVOID)FileEntry,
                           &FileId,
                           FileTablePurgeEntry);
    if (!NT_SUCCESS(Status))
    {
        /* Close it if that failed */
        FileEntry->Callbacks.Close(FileEntry);
        goto Quickie;
    }

    /* Add a reference on the device, and save our file ID  */
    ++DeviceEntry->ReferenceCount;
    Status = STATUS_SUCCESS;
    FileEntry->FileId = FileId;

    EfiPrintf(L"File %s opened with ID: %lx\r\n", FileEntry->FilePath, FileId);

FileOpened:
    /* Add a reference to the file entry, and see if this is the first one */
    if (++FileEntry->ReferenceCount == 1)
    {
        /* Reset unknowns */
        FileEntry->TotalBytesRead = 0;
        FileEntry->Unknown2 = 0;
    }

    /* Set the file as opened */
    FileEntry->Flags |= BL_FILE_ENTRY_OPENED;

    /* Not sure what this flag does */
    if (Flags & BL_UNKNOWN_ACCESS)
    {
        FileEntry->Flags |= BL_FILE_ENTRY_UNKNOWN_ACCESS;
    }

    /* If the caller wanted the entry back, return it */
    if (NewFileEntry)
    {
        *NewFileEntry = FileEntry;
    }

Quickie:
    /* Close the parent */
    if (DirectoryEntry)
    {
        BlFileClose(DirectoryEntry->FileId);
    }

    /* Free the parent name copy */
    if (ParentFileName)
    {
        BlMmFreeHeap(ParentFileName);
    }

    /* Free the file name copy */
    if (FileNameCopy)
    {
        BlMmFreeHeap(FileNameCopy);
    }

    /* Return back to caller */
    return Status;
}