Esempio n. 1
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;
}
Esempio n. 2
0
NTSTATUS
PvfsCheckDeleteOnClose(
    IN IRP_ARGS_CREATE CreateArgs,
    IN PSTR pszFilename,
    IN ACCESS_MASK GrantedAccess
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    FILE_ATTRIBUTES Attributes = 0;

    if (!(CreateArgs.CreateOptions & FILE_DELETE_ON_CLOSE)) {
        goto cleanup;
    }

    if (!(GrantedAccess & DELETE))
    {
        ntError = STATUS_ACCESS_DENIED;
        BAIL_ON_NT_STATUS(ntError);
    }

    /* ReadOnly is largely ignored by the file system on directories.
       It is used by the Windows explorer.exe to mark folders as "special" */

    if (CreateArgs.CreateOptions & FILE_DIRECTORY_FILE)
    {
        ntError = STATUS_SUCCESS;
        goto cleanup;
    }

    /* Dealing with files from here down */

    if (pszFilename)
    {
        ntError = PvfsGetFilenameAttributes(
                      pszFilename,
                      &Attributes);
        BAIL_ON_NT_STATUS(ntError);
    }

    switch (CreateArgs.CreateDisposition)
    {
    case FILE_OPEN:
    case FILE_OPEN_IF:
    case FILE_SUPERSEDE:
    case FILE_CREATE:
        if (pszFilename)
        {
            if (Attributes & FILE_ATTRIBUTE_READONLY)
            {
                ntError = STATUS_CANNOT_DELETE;
                BAIL_ON_NT_STATUS(ntError);
            }
        }
        else
        {
            if (CreateArgs.FileAttributes & FILE_ATTRIBUTE_READONLY)
            {
                ntError = STATUS_CANNOT_DELETE;
                BAIL_ON_NT_STATUS(ntError);
            }
        }
        break;

    case FILE_OVERWRITE:
    case FILE_OVERWRITE_IF:
        if (pszFilename && (CreateArgs.FileAttributes == 0))
        {
            if (Attributes & FILE_ATTRIBUTE_READONLY)
            {
                ntError = STATUS_CANNOT_DELETE;
                BAIL_ON_NT_STATUS(ntError);
            }
        }
        else
        {
            if (CreateArgs.FileAttributes & FILE_ATTRIBUTE_READONLY)
            {
                ntError = STATUS_CANNOT_DELETE;
                BAIL_ON_NT_STATUS(ntError);
            }
        }
        break;
    }

    ntError = STATUS_SUCCESS;

cleanup:
    return ntError;

error:
    goto cleanup;
}
static NTSTATUS
FillFileIdFullDirInfoBuffer(
    PVOID pBuffer,
    DWORD dwBufLen,
    PSTR pszParent,
    PPVFS_DIRECTORY_ENTRY pEntry,
    PDWORD pdwConsumed
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PFILE_ID_FULL_DIR_INFORMATION pFileInfo = (PFILE_ID_FULL_DIR_INFORMATION)pBuffer;
    PWSTR pwszFilename = NULL;
    PSTR pszFullPath = NULL;
    DWORD dwNeeded = 0;
    size_t W16FilenameLen = 0;
    size_t W16FilenameLenBytes = 0;

    /* Check for enough space for static members */

    if (dwBufLen < sizeof(*pFileInfo))
    {
        ntError = STATUS_BUFFER_TOO_SMALL;
        BAIL_ON_NT_STATUS(ntError);
    }

    /* Build the absolute path and stat() it */

    ntError = RtlCStringAllocatePrintf(
                  &pszFullPath,
                  "%s/%s",
                  pszParent,
                  pEntry->pszFilename);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsSysStat(pszFullPath, &pEntry->Stat);
    BAIL_ON_NT_STATUS(ntError);

    ntError = RtlWC16StringAllocateFromCString(
                  &pwszFilename,
                  pEntry->pszFilename);
    BAIL_ON_NT_STATUS(ntError);

    ntError = FillFileIdFullDirInfoStatic(
                  pFileInfo,
                  pwszFilename,
                  &pEntry->Stat);
    BAIL_ON_NT_STATUS(ntError);

    /* We have more information here to fill in the
       file attributes */

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

    /* Save what we have used so far */

    *pdwConsumed = sizeof(*pFileInfo);

    /* Calculate space */

    W16FilenameLen = RtlWC16StringNumChars(pwszFilename);
    W16FilenameLenBytes = W16FilenameLen * sizeof(WCHAR);
    dwNeeded = sizeof(*pFileInfo) + W16FilenameLenBytes;

    /* alignment on 8 byte boundary */

    if (dwNeeded % 8) {
        dwNeeded += 8 - (dwNeeded % 8);
    }

    if (dwNeeded > dwBufLen)
    {
        ntError = STATUS_BUFFER_TOO_SMALL;
        BAIL_ON_NT_STATUS(ntError);
    }

    pFileInfo->FileNameLength = W16FilenameLenBytes;
    memcpy(pFileInfo->FileName, pwszFilename, W16FilenameLenBytes);

    *pdwConsumed = dwNeeded;
    ntError = STATUS_SUCCESS;

cleanup:
    RtlCStringFree(&pszFullPath);
    RtlWC16StringFree(&pwszFilename);

    return ntError;

error:
    goto cleanup;
}