Example #1
0
static
VOID
PvfsCleanupFailedCreate(
    int fd,
    PCSTR pszPath,
    BOOLEAN bWasCreated
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PVFS_STAT Stat1 = {0};
    PVFS_STAT Stat2 = {0};

    /* Remove the file if it was created and the Dev/Inode matches our fd */

    if (bWasCreated && (pszPath != NULL))
    {
        ntError = PvfsSysFstat(fd, &Stat1);
        if (ntError == STATUS_SUCCESS)
        {
            ntError = PvfsSysStat(pszPath, &Stat2);
            if (ntError == STATUS_SUCCESS)
            {
                if ((Stat1.s_dev == Stat1.s_dev) &&
                    (Stat2.s_ino == Stat2.s_ino))
                {
                    ntError = PvfsSysRemove(pszPath);
                }
            }
        }
    }

    ntError = PvfsSysClose(fd);

    return;
}
Example #2
0
NTSTATUS
PvfsCcbQueryFileBasicInformation(
    PPVFS_CCB pCcb,
    PFILE_BASIC_INFORMATION pFileInfo
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PVFS_STAT Stat = {0};
    PVFS_FILE_NAME baseObjectFileName = { 0 };

    if (PvfsIsDefaultStream(pCcb->pScb))
    {
        ntError = PvfsGetFileAttributes(pCcb, &pFileInfo->FileAttributes);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsSysFstat(pCcb->fd, &Stat);
        BAIL_ON_NT_STATUS(ntError);
    }
    else
    {
        // Named Streams share meta-data with the owning FCB
        ntError = PvfsBuildFileNameFromCString(
                      &baseObjectFileName,
                      pCcb->pScb->pOwnerFcb->pszFilename,
                      0);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsGetFilenameAttributes(
                      PvfsGetCStringBaseFileName(&baseObjectFileName),
                      &pFileInfo->FileAttributes);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsSysStatByFileName(&baseObjectFileName, &Stat);
        BAIL_ON_NT_STATUS(ntError);
    }

    ntError = PvfsUnixToWinTime(&pFileInfo->LastAccessTime, Stat.s_atime);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsUnixToWinTime(&pFileInfo->LastWriteTime, Stat.s_mtime);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsUnixToWinTime(&pFileInfo->ChangeTime, Stat.s_ctime);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsUnixToWinTime(&pFileInfo->CreationTime, Stat.s_crtime);
    BAIL_ON_NT_STATUS(ntError);


error:
    PvfsDestroyFileName(&baseObjectFileName);

    return ntError;
}
Example #3
0
NTSTATUS
PvfsCcbQueryFileStandardInformation(
    PPVFS_CCB pCcb,
    PFILE_STANDARD_INFORMATION pFileInfo
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PVFS_STAT Stat = {0};
    BOOLEAN bDeletePending = FALSE;
    LONG64 allocationSize = 0;

    ntError = PvfsSysFstat(pCcb->fd, &Stat);
    BAIL_ON_NT_STATUS(ntError);

    bDeletePending = PvfsScbIsPendingDelete(pCcb->pScb);

    if (PVFS_IS_DIR(pCcb))
    {
        /* NTFS reports the allocation and end-of-file on
           directories as 0.  smbtorture cares about this even
           if no apps that I know of do. */

        pFileInfo->AllocationSize = 0;
        pFileInfo->EndOfFile      = 0;

        pFileInfo->NumberOfLinks  = bDeletePending ? 0 : 1;
    }
    else
    {
        allocationSize = PvfsGetScbAllocationSize(pCcb->pScb);

        pFileInfo->EndOfFile      = Stat.s_size;
        pFileInfo->AllocationSize = PVFS_MAX((Stat.s_alloc > Stat.s_size ?
                                              Stat.s_alloc : Stat.s_size),
                                             allocationSize);

        pFileInfo->NumberOfLinks  = bDeletePending ?
                                    Stat.s_nlink - 1 :
                                    Stat.s_nlink;
    }

    pFileInfo->DeletePending  = bDeletePending;
    pFileInfo->Directory      = S_ISDIR(Stat.s_mode) ? TRUE : FALSE;

cleanup:

    return ntError;

error:

    goto cleanup;

}
static NTSTATUS
PvfsQueryFileInternalInfo(
    PPVFS_IRP_CONTEXT pIrpContext
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PIRP pIrp = pIrpContext->pIrp;
    PPVFS_CCB pCcb = NULL;
    PFILE_INTERNAL_INFORMATION pFileInfo = NULL;
    IRP_ARGS_QUERY_SET_INFORMATION Args = pIrpContext->pIrp->Args.QuerySetInformation;
    PVFS_STAT Stat = {0};

    /* Sanity checks */

    ntError =  PvfsAcquireCCB(pIrp->FileHandle, &pCcb);
    BAIL_ON_NT_STATUS(ntError);

    BAIL_ON_INVALID_PTR(Args.FileInformation, ntError);

    if (Args.Length < sizeof(*pFileInfo))
    {
        ntError = STATUS_BUFFER_TOO_SMALL;
        BAIL_ON_NT_STATUS(ntError);
    }

    pFileInfo = (PFILE_INTERNAL_INFORMATION)Args.FileInformation;

    /* Real work starts here */

    ntError = PvfsSysFstat(pCcb->fd, &Stat);
    BAIL_ON_NT_STATUS(ntError);

    /* Just let this be the inode number */

    pFileInfo->IndexNumber = Stat.s_ino;

    pIrp->IoStatusBlock.BytesTransferred = sizeof(*pFileInfo);
    ntError = STATUS_SUCCESS;

cleanup:
    if (pCcb) {
        PvfsReleaseCCB(pCcb);
    }

    return ntError;

error:
    goto cleanup;
}
Example #5
0
NTSTATUS
PvfsSaveFileDeviceInfo(
    PPVFS_CCB pCcb
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PVFS_STAT Stat = {0};
    PPVFS_SCB pScb = pCcb->pScb;
    PPVFS_FCB pFcb = pCcb->pScb->pOwnerFcb;
    BOOLEAN scbLocked = FALSE;
    BOOLEAN fcbLocked = FALSE;

    ntError = PvfsSysFstat(pCcb->fd, &Stat);
    BAIL_ON_NT_STATUS(ntError);

    pCcb->FileId.Device = Stat.s_dev;
    pCcb->FileId.Inode  = Stat.s_ino;
    pCcb->FileSize = Stat.s_size;

    LWIO_LOCK_MUTEX(scbLocked, &pScb->BaseControlBlock.Mutex);

    // Have to set the FileID on the Stream Block
    pScb->FileId = pCcb->FileId;

    if (PvfsIsDefaultStream(pScb))
    {
        // Push the FIleId through to the File Block if unset
        LWIO_LOCK_MUTEX(fcbLocked, &pFcb->BaseControlBlock.Mutex);

        pFcb->FileId = pScb->FileId;

        LWIO_UNLOCK_MUTEX(fcbLocked, &pFcb->BaseControlBlock.Mutex);
    }

    LWIO_UNLOCK_MUTEX(scbLocked, &pScb->BaseControlBlock.Mutex);

error:

    return ntError;
}
Example #6
0
NTSTATUS
PvfsCcbSetFileBasicInformation(
    PPVFS_CCB pCcb,
    PFILE_BASIC_INFORMATION pFileInfo
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    LONG64 WriteTime = 0;
    LONG64 AccessTime = 0;
    FILE_NOTIFY_CHANGE NotifyFilter = FILE_NOTIFY_CHANGE_LAST_WRITE |
                                      FILE_NOTIFY_CHANGE_LAST_ACCESS;
    PVFS_STAT Stat = {0};
    BOOLEAN fcbControlLocked = FALSE;
    PPVFS_FCB pFcb = PvfsReferenceFCB(pCcb->pScb->pOwnerFcb);

    if (PvfsIsDefaultStream(pCcb->pScb))
    {
        ntError = PvfsValidatePathSCB(pCcb->pScb, &pCcb->FileId);
    }
    else
    {
        // Have to grab the base file object
        LWIO_LOCK_MUTEX(fcbControlLocked, &pFcb->BaseControlBlock.Mutex);

        ntError = PvfsValidatePathFCB(pFcb, &pFcb->FileId);
        BAIL_ON_NT_STATUS(ntError);

        LWIO_UNLOCK_MUTEX(fcbControlLocked, &pFcb->BaseControlBlock.Mutex);
    }

    /* We cant's set the Change Time so ignore it */

    WriteTime  = pFileInfo->LastWriteTime;
    AccessTime = pFileInfo->LastAccessTime;

    /* Ignore 0xffffffff */

    if (WriteTime == (LONG64)-1) {
        WriteTime = 0;
    }

    if (AccessTime == (LONG64)-1) {
        AccessTime = 0;
    }

    /* Save for "sticky" WriteTime sematics */

    if (WriteTime != 0)
    {
        PvfsSetLastWriteTimeFCB(pFcb, WriteTime);
    }

    /* Check if we need to preserve any original timestamps */

    if (WriteTime == 0 || AccessTime == 0)
    {
        if (PvfsIsDefaultStream(pCcb->pScb))
        {
            ntError = PvfsSysFstat(pCcb->fd, &Stat);
        }
        else
        {
            // Have to grab the stat() on the base file object
            ntError = PvfsSysStatByFcb(pFcb, &Stat);
        }
        BAIL_ON_NT_STATUS(ntError);

        if (WriteTime == 0)
        {
            NotifyFilter &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;

            ntError = PvfsUnixToWinTime(&WriteTime, Stat.s_mtime);
            BAIL_ON_NT_STATUS(ntError);
        }

        if (AccessTime == 0)
        {
            NotifyFilter &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;

            ntError = PvfsUnixToWinTime(&AccessTime, Stat.s_atime);
            BAIL_ON_NT_STATUS(ntError);
        }
    }

    ntError = PvfsSysUtimeByFcb(pFcb, WriteTime, AccessTime);
    BAIL_ON_NT_STATUS(ntError);

    if (pFileInfo->FileAttributes != 0)
    {
        ntError = PvfsSetFileAttributes(pCcb, pFileInfo->FileAttributes);
        BAIL_ON_NT_STATUS(ntError);
    }

    if (NotifyFilter != 0)
    {
        PvfsNotifyScheduleFullReport(
            pFcb,
            NotifyFilter,
            FILE_ACTION_MODIFIED,
            pFcb->pszFilename);
    }

error:
    LWIO_UNLOCK_MUTEX(fcbControlLocked, &pFcb->BaseControlBlock.Mutex);

    if (pFcb)
    {
        PvfsReleaseFCB(&pFcb);
    }

    return ntError;
}
Example #7
0
static
NTSTATUS
PvfsQueryFileFsVolInfo(
    PPVFS_IRP_CONTEXT pIrpContext
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PIRP pIrp = pIrpContext->pIrp;
    PPVFS_CCB pCcb = NULL;
    PFILE_FS_VOLUME_INFORMATION pFileInfo = NULL;
    IRP_ARGS_QUERY_SET_VOLUME_INFORMATION Args = pIrpContext->pIrp->Args.QuerySetVolumeInformation;
    PWSTR pwszVolumeName = NULL;
    PCSTR pszVolName = "LIKEWISE";
    size_t VolNameLenBytes = RtlCStringNumChars(pszVolName) * sizeof(WCHAR);
    PVFS_STAT stat = { 0 };

    /* Sanity checks */

    ntError =  PvfsAcquireCCB(pIrp->FileHandle, &pCcb);
    BAIL_ON_NT_STATUS(ntError);

    /* not sure exact access rights to check for here */

    ntError = PvfsAccessCheckFileHandle(pCcb, FILE_READ_ATTRIBUTES);
    BAIL_ON_NT_STATUS(ntError);

    BAIL_ON_INVALID_PTR(Args.FsInformation, ntError);

    if (Args.Length < sizeof(*pFileInfo) + VolNameLenBytes)
    {
        ntError = STATUS_BUFFER_TOO_SMALL;
        BAIL_ON_NT_STATUS(ntError);
    }

    pFileInfo = (PFILE_FS_VOLUME_INFORMATION)Args.FsInformation;

    /* Real work starts here */

    ntError = PvfsSysFstat(pCcb->fd, &stat);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsUnixToWinTime(&pFileInfo->VolumeCreationTime, stat.s_crtime);
    BAIL_ON_NT_STATUS(ntError);

    pFileInfo->VolumeSerialNumber = 0x009a9a03;
    pFileInfo->SupportsObjects = FALSE;

    ntError = RtlWC16StringAllocateFromCString(&pwszVolumeName, pszVolName);
    BAIL_ON_NT_STATUS(ntError);

    pFileInfo->VolumeLabelLength = VolNameLenBytes;
    memcpy(pFileInfo->VolumeLabel, pwszVolumeName, VolNameLenBytes);

    pIrp->IoStatusBlock.BytesTransferred = sizeof(*pFileInfo);
    ntError = STATUS_SUCCESS;

cleanup:
    if (pCcb) {
        PvfsReleaseCCB(pCcb);
    }

    PVFS_FREE(&pwszVolumeName);

    return ntError;

error:
    goto cleanup;
}