Beispiel #1
0
NTSTATUS
SrvBuildTreeRelativePath(
    PLWIO_SRV_TREE pTree,
    PWSTR          pwszFilename,
    PIO_FILE_NAME  pFilename
    )
{
    NTSTATUS ntStatus     = STATUS_SUCCESS;
    BOOLEAN  bInLock      = FALSE;
    PWSTR    pwszFilePath = NULL;

    if (SrvTreeIsNamedPipe(pTree))
    {
        LWIO_LOCK_RWMUTEX_SHARED(bInLock, &pTree->pShareInfo->mutex);

        ntStatus = SrvBuildFilePath(
                        pTree->pShareInfo->pwszPath,
                        pwszFilename,
                        &pwszFilePath);
        BAIL_ON_NT_STATUS(ntStatus);
    }
    else
    {
        wchar16_t wszBackslash[] = {'\\', 0};

        if (!IsNullOrEmptyString(pwszFilename) &&
            SMBWc16sCmp(pwszFilename, &wszBackslash[0]))
        {
            ntStatus = SrvBuildFilePath(
                            NULL,
                            pwszFilename,
                            &pwszFilePath);
            BAIL_ON_NT_STATUS(ntStatus);
        }

        LWIO_LOCK_RWMUTEX_SHARED(bInLock, &pTree->pShareInfo->mutex);

        pFilename->RootFileHandle = pTree->hFile;
    }

    pFilename->FileName = pwszFilePath;

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &pTree->pShareInfo->mutex);

    return ntStatus;

error:

    goto cleanup;
}
Beispiel #2
0
static
NTSTATUS
SrvDeleteSingleFile(
    PSRV_EXEC_CONTEXT pExecContext
    )
{
    NTSTATUS                   ntStatus     = STATUS_SUCCESS;
    PSRV_PROTOCOL_EXEC_CONTEXT pCtxProtocol = pExecContext->pProtocolContext;
    PSRV_EXEC_CONTEXT_SMB_V1   pCtxSmb1     = pCtxProtocol->pSmb1Context;
    PSRV_DELETE_STATE_SMB_V1   pDeleteState = NULL;
    wchar16_t                  wszDot[]     = {'.',  0};

    pDeleteState = (PSRV_DELETE_STATE_SMB_V1)pCtxSmb1->hState;

    if (!pDeleteState->bPendingCreate)
    {
        if ((SMBWc16sCmp(pDeleteState->pwszSearchPattern2, wszDot) == 0))
        {
            ntStatus = STATUS_OBJECT_NAME_INVALID;
            BAIL_ON_NT_STATUS(ntStatus);
        }

        ntStatus = SrvBuildFilePath(
                        pDeleteState->pwszFilesystemPath,
                        pDeleteState->pwszSearchPattern2,
                        &pDeleteState->fileName.Name);
        BAIL_ON_NT_STATUS(ntStatus);

        pDeleteState->fileName.RootFileHandle = pDeleteState->pTree->hFile;

        SrvPrepareDeleteStateAsync(pDeleteState, pExecContext);

        pDeleteState->bPendingCreate = TRUE;

        ntStatus = SrvIoCreateFile(
                        pDeleteState->pTree->pShareInfo,
                        &pDeleteState->hFile,
                        pDeleteState->pAcb,
                        &pDeleteState->ioStatusBlock,
                        pDeleteState->pSession->pIoSecurityContext,
                        &pDeleteState->fileName,
                        pDeleteState->pSecurityDescriptor,
                        pDeleteState->pSecurityQOS,
                        DELETE,
                        0,
                        FILE_ATTRIBUTE_NORMAL,
                        FILE_NO_SHARE,
                        FILE_OPEN,
                        FILE_DELETE_ON_CLOSE|FILE_NON_DIRECTORY_FILE,
                        NULL,
                        0,
                        pDeleteState->pEcpList);
        BAIL_ON_NT_STATUS(ntStatus);

        SrvReleaseDeleteStateAsync(pDeleteState); // completed sync
    }

    pDeleteState->bPendingCreate = FALSE;

    ntStatus = pDeleteState->ioStatusBlock.Status;
    BAIL_ON_NT_STATUS(ntStatus);

    if (pDeleteState->hFile)
    {
        IoCloseFile(pDeleteState->hFile);
        pDeleteState->hFile = NULL;
    }

cleanup:

    return ntStatus;

error:

    /* Have to do some error mapping here to match WinXP */

    switch (ntStatus)
    {
        case STATUS_PENDING:
        case STATUS_ACCESS_DENIED:
        case STATUS_FILE_IS_A_DIRECTORY:
        case STATUS_SHARING_VIOLATION:
        case STATUS_OBJECT_NAME_INVALID:

            break;

        case STATUS_OBJECT_NAME_NOT_FOUND:
        case STATUS_NO_SUCH_FILE:

            ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;

            break;

        default:

            ntStatus = STATUS_CANNOT_DELETE;

            break;
    }

    goto cleanup;
}
Beispiel #3
0
static
NTSTATUS
SrvDeleteFiles(
    PSRV_EXEC_CONTEXT pExecContext
    )
{
    NTSTATUS                   ntStatus     = STATUS_SUCCESS;
    PSRV_PROTOCOL_EXEC_CONTEXT pCtxProtocol = pExecContext->pProtocolContext;
    PSRV_EXEC_CONTEXT_SMB_V1   pCtxSmb1     = pCtxProtocol->pSmb1Context;
    PSRV_DELETE_STATE_SMB_V1   pDeleteState = NULL;
    PWSTR                      pwszFilename = NULL;
    wchar16_t wszDot[]                      = {'.',  0};

    pDeleteState = (PSRV_DELETE_STATE_SMB_V1)pCtxSmb1->hState;

    if (pDeleteState->bPendingCreate)
    {
        pDeleteState->bPendingCreate = FALSE;

        ntStatus = pDeleteState->ioStatusBlock.Status;
        BAIL_ON_NT_STATUS(ntStatus);

        IoCloseFile(pDeleteState->hFile);
        pDeleteState->hFile = NULL;

        pDeleteState->bDeletedFile = TRUE;

        pDeleteState->iResult++;
    }

    for (;;)
    {
        for (   ;
                pDeleteState->iResult < pDeleteState->usSearchResultCount;
                pDeleteState->iResult++)
        {
            BOOLEAN bEligibleForDelete = FALSE;
            FILE_ATTRIBUTES ulIncludeAttributes = 0;

            if (!pDeleteState->pResult)
            {
                pDeleteState->pResult =
                    (PSMB_FIND_FILE_BOTH_DIRECTORY_INFO_HEADER)pDeleteState->pData;
            }
            else if (pDeleteState->pResult->NextEntryOffset)
            {
                PBYTE pTmp = (PBYTE)pDeleteState->pResult +
                                pDeleteState->pResult->NextEntryOffset;

                pDeleteState->pResult =
                            (PSMB_FIND_FILE_BOTH_DIRECTORY_INFO_HEADER)pTmp;
            }
            else
            {
                ntStatus = STATUS_INTERNAL_ERROR;
                BAIL_ON_NT_STATUS(ntStatus);
            }

            if (pwszFilename)
            {
                SrvFreeMemory(pwszFilename);
                pwszFilename = NULL;
            }

            ulIncludeAttributes =
                SMB_FILE_ATTRIBUTES_TO_NATIVE(pDeleteState->usSearchAttributes);

            bEligibleForDelete =
                    (IsSetFlag(pDeleteState->pResult->FileAttributes,
                               ulIncludeAttributes & (FILE_ATTRIBUTE_DIRECTORY |
                                                      FILE_ATTRIBUTE_HIDDEN |
                                                      FILE_ATTRIBUTE_SYSTEM))) ||
                    (!IsSetFlag(pDeleteState->pResult->FileAttributes,
                                         (FILE_ATTRIBUTE_DIRECTORY |
                                          FILE_ATTRIBUTE_HIDDEN |
                                          FILE_ATTRIBUTE_SYSTEM)));

            if (!bEligibleForDelete)
            {
                if (!pDeleteState->bPathHasWildCards)
                {
                    if ((SMBWc16sCmp(pDeleteState->pwszSearchPattern2, wszDot) == 0))
                    {
                        ntStatus = STATUS_OBJECT_NAME_INVALID;
                    }
                    else if (IsSetFlag(pDeleteState->pResult->FileAttributes,
                                        FILE_ATTRIBUTE_DIRECTORY))
                    {
                        ntStatus = STATUS_FILE_IS_A_DIRECTORY;
                    }
                    else
                    {
                        ntStatus = STATUS_NO_SUCH_FILE;
                    }
                    BAIL_ON_NT_STATUS(ntStatus);
                }
                continue;
            }

            if (pDeleteState->bUseLongFilenames)
            {
                ntStatus = SrvAllocateMemory(
                                pDeleteState->pResult->FileNameLength + sizeof(wchar16_t),
                                (PVOID*)&pwszFilename);
                BAIL_ON_NT_STATUS(ntStatus);

                memcpy((PBYTE)pwszFilename,
                       (PBYTE)pDeleteState->pResult->FileName,
                       pDeleteState->pResult->FileNameLength);
            }
            else
            {
                ntStatus = SrvAllocateMemory(
                                pDeleteState->pResult->ShortNameLength + sizeof(wchar16_t),
                                (PVOID*)&pwszFilename);
                BAIL_ON_NT_STATUS(ntStatus);

                memcpy((PBYTE)pwszFilename,
                       (PBYTE)pDeleteState->pResult->ShortName,
                       pDeleteState->pResult->ShortNameLength);
            }

            if (SMBWc16sCmp(pwszFilename, wszDot) == 0)
            {
                ntStatus = STATUS_OBJECT_NAME_INVALID;
                BAIL_ON_NT_STATUS(ntStatus);
            }

            SRV_FREE_UNICODE_STRING(&pDeleteState->fileName.Name);

            ntStatus = SrvBuildFilePath(
                            pDeleteState->pwszFilesystemPath,
                            pwszFilename,
                            &pDeleteState->fileName.Name);
            BAIL_ON_NT_STATUS(ntStatus);

            pDeleteState->fileName.RootFileHandle = pDeleteState->pTree->hFile;

            SrvPrepareDeleteStateAsync(pDeleteState, pExecContext);

            pDeleteState->bPendingCreate = TRUE;

            ntStatus = SrvIoCreateFile(
                            pDeleteState->pTree->pShareInfo,
                            &pDeleteState->hFile,
                            pDeleteState->pAcb,
                            &pDeleteState->ioStatusBlock,
                            pDeleteState->pSession->pIoSecurityContext,
                            &pDeleteState->fileName,
                            pDeleteState->pSecurityDescriptor,
                            pDeleteState->pSecurityQOS,
                            DELETE,
                            0,
                            FILE_ATTRIBUTE_NORMAL,
                            FILE_NO_SHARE,
                            FILE_OPEN,
                            FILE_DELETE_ON_CLOSE|FILE_NON_DIRECTORY_FILE,
                            NULL,
                            0,
                            pDeleteState->pEcpList);
            BAIL_ON_NT_STATUS(ntStatus);

            SrvReleaseDeleteStateAsync(pDeleteState); // completed sync

            pDeleteState->bPendingCreate = FALSE;

            IoCloseFile(pDeleteState->hFile);
            pDeleteState->hFile = NULL;

            pDeleteState->bDeletedFile = TRUE;
        }

        if (pDeleteState->bEndOfSearch)
        {
            break;
        }

        if (pDeleteState->pData)
        {
            SrvFreeMemory(pDeleteState->pData);
            pDeleteState->pData = NULL;
        }

        pDeleteState->iResult = 0;
        pDeleteState->pResult = NULL;

        ntStatus = SrvFinderGetSearchResults(
                        pDeleteState->hSearchSpace,
                        FALSE,                 /* bReturnSingleEntry   */
                        FALSE,                 /* bRestartScan         */
                        10,                    /* Desired search count */
                        UINT16_MAX,            /* Max data count       */
                        pDeleteState->usDataOffset,
                        &pDeleteState->pData,
                        &pDeleteState->usDataLen,
                        &pDeleteState->usSearchResultCount,
                        &pDeleteState->bEndOfSearch);

        if (ntStatus == STATUS_NO_MORE_MATCHES)
        {
            ntStatus = STATUS_ASSERTION_FAILURE;
            BAIL_ON_NT_STATUS(ntStatus);
        }

        if (ntStatus == STATUS_NO_SUCH_FILE)
        {
            ntStatus = STATUS_SUCCESS;
            break;
        }
    }

    if (!pDeleteState->bDeletedFile)
    {
        if (pDeleteState->bPathHasWildCards)
        {
            ntStatus = STATUS_NO_SUCH_FILE;
        }
        else
        {
            ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
        }
        BAIL_ON_NT_STATUS(ntStatus);
    }

cleanup:

    if (pwszFilename)
    {
        SrvFreeMemory(pwszFilename);
    }

    return ntStatus;

error:

    /* Have to do some error mapping here to match WinXP */

    switch (ntStatus)
    {
        case STATUS_PENDING:
        case STATUS_ACCESS_DENIED:
        case STATUS_FILE_IS_A_DIRECTORY:
        case STATUS_SHARING_VIOLATION:
        case STATUS_OBJECT_NAME_NOT_FOUND:
        case STATUS_OBJECT_NAME_INVALID:
        case STATUS_NO_SUCH_FILE:

            break;

        default:

            ntStatus = STATUS_CANNOT_DELETE;

            break;
    }

    goto cleanup;
}