VirtualBox

Changeset 78553 in vbox for trunk/src/VBox/Additions/WINNT


Ignore:
Timestamp:
May 17, 2019 12:55:39 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
130600
Message:

winnt/vboxsf: More VBoxMRxCreate related cleanups. bugref:9172

Location:
trunk/src/VBox/Additions/WINNT/SharedFolders/driver
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/SharedFolders/driver/info.cpp

    r78551 r78553  
    20122012            {
    20132013                Status = vbsfNtVBoxStatusToNt(vrc);
    2014                 Log(("VBOXSF: vbsfNtRename: VbglR0SfRename failed with %Rrc (Status=%#x)\n", vrc, Status));
     2014                Log(("VBOXSF: vbsfNtRename: VbglR0SfHostReqRenameWithSrcBuf failed with %Rrc (Status=%#x)\n", vrc, Status));
    20152015            }
    20162016
  • trunk/src/VBox/Additions/WINNT/SharedFolders/driver/path.cpp

    r78552 r78553  
    3030
    3131
    32 static NTSTATUS vbsfNtCreateWorkerBail(NTSTATUS Status, VBOXSFCREATEREQ *pReq, PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension)
     32/**
     33 * Handles failure scenarios where we may have to close the handle.
     34 */
     35DECL_NO_INLINE(static, NTSTATUS) vbsfNtCreateWorkerBail(NTSTATUS Status, VBOXSFCREATEREQ *pReq,
     36                                                        PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension)
    3337{
    3438    Log(("VBOXSF: vbsfNtCreateWorker: Returns %#x (Handle was %#RX64)\n", Status, pReq->CreateParms.Handle));
    35     AssertCompile(sizeof(VBOXSFCLOSEREQ) <= RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms));
    36     VbglR0SfHostReqClose(pNetRootExtension->map.root, (VBOXSFCLOSEREQ *)pReq, pReq->CreateParms.Handle);
     39    if (pReq->CreateParms.Handle != SHFL_HANDLE_NIL)
     40    {
     41        AssertCompile(sizeof(VBOXSFCLOSEREQ) <= RT_UOFFSETOF(VBOXSFCREATEREQ, CreateParms));
     42        VbglR0SfHostReqClose(pNetRootExtension->map.root, (VBOXSFCLOSEREQ *)pReq, pReq->CreateParms.Handle);
     43    }
    3744    return Status;
    3845}
    3946
    4047
     48/**
     49 * Worker for VBoxMRxCreate that converts parameters and calls the host.
     50 *
     51 * The caller takes care of freeing the request buffer, so this function is free
     52 * to just return at will.
     53 */
    4154static NTSTATUS vbsfNtCreateWorker(PRX_CONTEXT RxContext, VBOXSFCREATEREQ *pReq, ULONG *pulCreateAction,
    4255                                   PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension, PMRX_FCB pFcb)
    4356{
    44     /* Mask out unsupported attribute bits. */
    45     UCHAR       FileAttributes = (UCHAR)(RxContext->Create.NtCreateParameters.FileAttributes & ~FILE_ATTRIBUTE_NORMAL); /** @todo why UCHAR? */
    46     FileAttributes &= (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE);
    47     if (FileAttributes == 0)
    48         FileAttributes = FILE_ATTRIBUTE_NORMAL;
    49 
    50     ACCESS_MASK const DesiredAccess  = RxContext->Create.NtCreateParameters.DesiredAccess;
    51     ULONG       const Options        = RxContext->Create.NtCreateParameters.CreateOptions & FILE_VALID_OPTION_FLAGS;
    52     ULONG       const ShareAccess    = RxContext->Create.NtCreateParameters.ShareAccess;
    53 
    54     /* Various boolean flags. */
    55     struct
    56     {
    57         ULONG CreateDirectory :1;
    58         ULONG OpenDirectory :1;
    59         ULONG DirectoryFile :1;
    60         ULONG NonDirectoryFile :1;
    61         ULONG DeleteOnClose :1;
    62         ULONG TemporaryFile :1;
    63         ULONG SlashHack :1;
    64     } bf;
    65     RT_ZERO(bf);
    66 
    67     bf.DirectoryFile = BooleanFlagOn(Options, FILE_DIRECTORY_FILE);
    68     bf.NonDirectoryFile = BooleanFlagOn(Options, FILE_NON_DIRECTORY_FILE);
    69     bf.DeleteOnClose = BooleanFlagOn(Options, FILE_DELETE_ON_CLOSE);
    70     if (bf.DeleteOnClose)
    71         Log(("VBOXSF: vbsfProcessCreate: Delete on close!\n"));
    72 
    73     ULONG CreateDisposition = RxContext->Create.NtCreateParameters.Disposition;
    74 
    75     bf.CreateDirectory = (bf.DirectoryFile && ((CreateDisposition == FILE_CREATE) || (CreateDisposition == FILE_OPEN_IF)));
    76     bf.OpenDirectory = (bf.DirectoryFile && ((CreateDisposition == FILE_OPEN) || (CreateDisposition == FILE_OPEN_IF)));
    77     bf.TemporaryFile = BooleanFlagOn(RxContext->Create.NtCreateParameters.FileAttributes, FILE_ATTRIBUTE_TEMPORARY);
    78 
    79     if (FlagOn(pFcb->FcbState, FCB_STATE_TEMPORARY))
    80         bf.TemporaryFile = TRUE;
    81 
    82     bf.SlashHack = RxContext->CurrentIrpSp
    83                 && (RxContext->CurrentIrpSp->Parameters.Create.ShareAccess & VBOX_MJ_CREATE_SLASH_HACK);
    84 
    85     Log(("VBOXSF: vbsfProcessCreate: bf.TemporaryFile %d, bf.CreateDirectory %d, bf.DirectoryFile = %d, bf.SlashHack = %d\n",
    86          bf.TemporaryFile, bf.CreateDirectory, bf.DirectoryFile, bf.SlashHack));
     57    /*
     58     * Check out the options.
     59     */
     60    ULONG const fOptions            = RxContext->Create.NtCreateParameters.CreateOptions & FILE_VALID_OPTION_FLAGS;
     61    ULONG const CreateDisposition   = RxContext->Create.NtCreateParameters.Disposition;
     62    bool const  fCreateDir          = (fOptions & FILE_DIRECTORY_FILE)
     63                                   && (CreateDisposition == FILE_CREATE || CreateDisposition == FILE_OPEN_IF);
     64    bool const  fTemporaryFile      = (RxContext->Create.NtCreateParameters.FileAttributes & FILE_ATTRIBUTE_TEMPORARY)
     65                                   || (pFcb->FcbState & FCB_STATE_TEMPORARY);
     66
     67    Log(("VBOXSF: vbsfNtCreateWorker: fTemporaryFile %d, fCreateDir %d%s%s%s\n", fTemporaryFile, fCreateDir,
     68         fOptions & FILE_DIRECTORY_FILE ? ", FILE_DIRECTORY_FILE" : "",
     69         fOptions & FILE_NON_DIRECTORY_FILE ? ", FILE_NON_DIRECTORY_FILE" : "",
     70         fOptions & FILE_DELETE_ON_CLOSE ? ", FILE_DELETE_ON_CLOSE" : ""));
    8771
    8872    /* Check consistency in specified flags. */
    89     if (bf.TemporaryFile && bf.CreateDirectory) /* Directories with temporary flag set are not allowed! */
    90     {
    91         Log(("VBOXSF: vbsfProcessCreate: Not allowed: Temporary directories!\n"));
     73    if (fTemporaryFile && fCreateDir) /* Directories with temporary flag set are not allowed! */
     74    {
     75        Log(("VBOXSF: vbsfNtCreateWorker: Not allowed: Temporary directories!\n"));
    9276        return STATUS_INVALID_PARAMETER;
    9377    }
    9478
    95     if (bf.DirectoryFile && bf.NonDirectoryFile)
     79    if ((fOptions & (FILE_DIRECTORY_FILE | FILE_NON_DIRECTORY_FILE)) == (FILE_DIRECTORY_FILE | FILE_NON_DIRECTORY_FILE))
    9680    {
    9781        /** @todo r=bird: Check if FILE_DIRECTORY_FILE+FILE_NON_DIRECTORY_FILE really is illegal in all combinations... */
    98         Log(("VBOXSF: vbsfProcessCreate: Unsupported combination: dir && !dir\n"));
     82        Log(("VBOXSF: vbsfNtCreateWorker: Unsupported combination: dir && !dir\n"));
    9983        return STATUS_INVALID_PARAMETER;
    10084    }
     
    11094     * Directory.
    11195     */
    112     if (bf.DirectoryFile)
     96    if (fOptions & FILE_DIRECTORY_FILE)
    11397    {
    11498        if (CreateDisposition != FILE_CREATE && CreateDisposition != FILE_OPEN && CreateDisposition != FILE_OPEN_IF)
    11599        {
    116             Log(("VBOXSF: vbsfProcessCreate: Invalid disposition 0x%08X for directory!\n",
     100            Log(("VBOXSF: vbsfNtCreateWorker: Invalid disposition 0x%08X for directory!\n",
    117101                 CreateDisposition));
    118102            return STATUS_INVALID_PARAMETER;
    119103        }
    120104
    121         Log(("VBOXSF: vbsfProcessCreate: CreateFlags |= SHFL_CF_DIRECTORY\n"));
     105        Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_DIRECTORY\n"));
    122106        pReq->CreateParms.CreateFlags |= SHFL_CF_DIRECTORY;
    123107    }
     
    130114        case FILE_SUPERSEDE:
    131115            pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_REPLACE_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW;
    132             Log(("VBOXSF: vbsfProcessCreate: CreateFlags |= SHFL_CF_ACT_REPLACE_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW\n"));
     116            Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACT_REPLACE_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW\n"));
    133117            break;
    134118
    135119        case FILE_OPEN:
    136120            pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW;
    137             Log(("VBOXSF: vbsfProcessCreate: CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW\n"));
     121            Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW\n"));
    138122            break;
    139123
    140124        case FILE_CREATE:
    141125            pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW;
    142             Log(("VBOXSF: vbsfProcessCreate: CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW\n"));
     126            Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW\n"));
    143127            break;
    144128
    145129        case FILE_OPEN_IF:
    146130            pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW;
    147             Log(("VBOXSF: vbsfProcessCreate: CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW\n"));
     131            Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW\n"));
    148132            break;
    149133
    150134        case FILE_OVERWRITE:
    151135            pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW;
    152             Log(("VBOXSF: vbsfProcessCreate: CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW\n"));
     136            Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW\n"));
    153137            break;
    154138
    155139        case FILE_OVERWRITE_IF:
    156140            pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW;
    157             Log(("VBOXSF: vbsfProcessCreate: CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW\n"));
     141            Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW\n"));
    158142            break;
    159143
    160144        default:
    161             Log(("VBOXSF: vbsfProcessCreate: Unexpected create disposition: 0x%08X\n", CreateDisposition));
     145            Log(("VBOXSF: vbsfNtCreateWorker: Unexpected create disposition: 0x%08X\n", CreateDisposition));
    162146            return STATUS_INVALID_PARAMETER;
    163147    }
     
    166150     * Access mode.
    167151     */
     152    ACCESS_MASK const DesiredAccess = RxContext->Create.NtCreateParameters.DesiredAccess;
    168153    if (DesiredAccess & FILE_READ_DATA)
    169154    {
    170         Log(("VBOXSF: vbsfProcessCreate: FILE_READ_DATA\n"));
     155        Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACCESS_READ\n"));
    171156        pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_READ;
    172157    }
     
    176161    if (DesiredAccess & FILE_WRITE_DATA)
    177162    {
    178         Log(("VBOXSF: vbsfProcessCreate: FILE_WRITE_DATA\n"));
     163        Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACCESS_WRITE\n"));
    179164        pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_WRITE;
    180165    }
     
    183168        /* Both write and append access flags are required for shared folders,
    184169         * as on Windows FILE_APPEND_DATA implies write access. */
    185         Log(("VBOXSF: vbsfProcessCreate: FILE_APPEND_DATA\n"));
     170        Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACCESS_WRITE | SHFL_CF_ACCESS_APPEND\n"));
    186171        pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_WRITE | SHFL_CF_ACCESS_APPEND;
    187172    }
    188173
    189174    if (DesiredAccess & FILE_READ_ATTRIBUTES)
     175    {
     176        Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACCESS_ATTR_READ\n"));
    190177        pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_ATTR_READ;
     178    }
    191179    if (DesiredAccess & FILE_WRITE_ATTRIBUTES)
     180    {
     181        Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACCESS_ATTR_WRITE\n"));
    192182        pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_ATTR_WRITE;
    193 
     183    }
     184
     185    /*
     186     * Sharing.
     187     */
     188    ULONG const ShareAccess = RxContext->Create.NtCreateParameters.ShareAccess;
    194189    if (ShareAccess & (FILE_SHARE_READ | FILE_SHARE_WRITE))
     190    {
     191        Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACCESS_DENYNONE\n"));
    195192        pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_DENYNONE;
     193    }
    196194    else if (ShareAccess & FILE_SHARE_READ)
     195    {
     196        Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACCESS_DENYWRITE\n"));
    197197        pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_DENYWRITE;
     198    }
    198199    else if (ShareAccess & FILE_SHARE_WRITE)
     200    {
     201        Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACCESS_DENYREAD\n"));
    199202        pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_DENYREAD;
     203    }
    200204    else
     205    {
     206        Log(("VBOXSF: vbsfNtCreateWorker: CreateFlags |= SHFL_CF_ACCESS_DENYALL\n"));
    201207        pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_DENYALL;
     208    }
    202209
    203210    /*
    204211     * Set initial allocation size and attributes.
     212     * There aren't too many attributes that need to be passed over.
    205213     */
    206214    pReq->CreateParms.Info.cbObject   = RxContext->Create.NtCreateParameters.AllocationSize.QuadPart;
    207     pReq->CreateParms.Info.Attr.fMode = NTToVBoxFileAttributes(FileAttributes);
     215    pReq->CreateParms.Info.Attr.fMode = NTToVBoxFileAttributes(  RxContext->Create.NtCreateParameters.FileAttributes
     216                                                               & (  FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN
     217                                                                  | FILE_ATTRIBUTE_SYSTEM   | FILE_ATTRIBUTE_ARCHIVE));
    208218
    209219    /*
    210220     * Call the host.
    211221     */
    212     Log(("VBOXSF: vbsfProcessCreate: Calling VbglR0SfHostReqCreate...\n"));
     222    Log(("VBOXSF: vbsfNtCreateWorker: Calling VbglR0SfHostReqCreate(fCreate=%#RX32)...\n", pReq->CreateParms.CreateFlags));
    213223    int vrc = VbglR0SfHostReqCreate(pNetRootExtension->map.root, pReq);
    214     Log(("VBOXSF: vbsfProcessCreate: VbglR0SfCreate returns vrc = %Rrc, Result = 0x%x\n", vrc, pReq->CreateParms.Result));
    215 
    216     if (RT_FAILURE(vrc))
    217     {
    218         /* Map some VBoxRC to STATUS codes expected by the system. */
    219         switch (vrc)
     224    Log(("VBOXSF: vbsfNtCreateWorker: VbglR0SfHostReqCreate returns vrc = %Rrc, Result = 0x%x\n", vrc, pReq->CreateParms.Result));
     225
     226    if (RT_SUCCESS(vrc))
     227    {
     228        /*
     229         * The request succeeded. Analyze host response,
     230         */
     231        switch (pReq->CreateParms.Result)
    220232        {
    221             case VERR_ALREADY_EXISTS:
    222                 Log(("VBOXSF: vbsfProcessCreate: VERR_ALREADY_EXISTS -> STATUS_OBJECT_NAME_COLLISION + FILE_EXISTS\n"));
    223                 *pulCreateAction = FILE_EXISTS;
    224                 return STATUS_OBJECT_NAME_COLLISION;
    225 
    226             /* On POSIX systems, the "mkdir" command returns VERR_FILE_NOT_FOUND when
    227                doing a recursive directory create. Handle this case.
    228 
    229                bird: We end up here on windows systems too if opening a dir that doesn't
    230                      exists.  Thus, I've changed the SHFL_PATH_NOT_FOUND to SHFL_FILE_NOT_FOUND
    231                      so that FsPerf is happy. */
    232             case VERR_FILE_NOT_FOUND: /** @todo r=bird: this is a host bug, isn't it? */
    233                 pReq->CreateParms.Result = SHFL_FILE_NOT_FOUND;
    234                 pReq->CreateParms.Handle = SHFL_HANDLE_NIL;
     233            case SHFL_PATH_NOT_FOUND:
     234                /* Path to the object does not exist. */
     235                Log(("VBOXSF: vbsfNtCreateWorker: Path not found -> STATUS_OBJECT_PATH_NOT_FOUND + FILE_DOES_NOT_EXIST\n"));
    235236                *pulCreateAction = FILE_DOES_NOT_EXIST;
    236                 Log(("VBOXSF: vbsfProcessCreate: VERR_FILE_NOT_FOUND -> STATUS_OBJECT_NAME_NOT_FOUND + FILE_DOES_NOT_EXIST\n"));
    237                 return STATUS_OBJECT_NAME_NOT_FOUND;
     237                return STATUS_OBJECT_PATH_NOT_FOUND;
     238
     239            case SHFL_FILE_NOT_FOUND:
     240                *pulCreateAction = FILE_DOES_NOT_EXIST;
     241                if (pReq->CreateParms.Handle == SHFL_HANDLE_NIL)
     242                {
     243                    Log(("VBOXSF: vbsfNtCreateWorker: File not found -> STATUS_OBJECT_NAME_NOT_FOUND + FILE_DOES_NOT_EXIST\n"));
     244                    return STATUS_OBJECT_NAME_NOT_FOUND;
     245                }
     246                AssertMsgFailed(("VBOXSF: vbsfNtCreateWorker: WTF? File not found but have a handle!\n"));
     247                return vbsfNtCreateWorkerBail(STATUS_UNSUCCESSFUL, pReq, pNetRootExtension);
     248
     249            case SHFL_FILE_EXISTS:
     250                Log(("VBOXSF: vbsfNtCreateWorker: File exists, Handle = %#RX64\n", pReq->CreateParms.Handle));
     251                if (pReq->CreateParms.Handle == SHFL_HANDLE_NIL)
     252                {
     253                    *pulCreateAction = FILE_EXISTS;
     254                    if (CreateDisposition == FILE_CREATE)
     255                    {
     256                        /* File was not opened because we requested a create. */
     257                        Log(("VBOXSF: vbsfNtCreateWorker: File exists already, create failed -> STATUS_OBJECT_NAME_COLLISION\n"));
     258                        return STATUS_OBJECT_NAME_COLLISION;
     259                    }
     260
     261                    /* Actually we should not go here, unless we have no rights to open the object. */
     262                    Log(("VBOXSF: vbsfNtCreateWorker: Existing file was not opened! -> STATUS_ACCESS_DENIED\n"));
     263                    return STATUS_ACCESS_DENIED;
     264                }
     265
     266                /* An existing file was opened. */
     267                *pulCreateAction = FILE_OPENED;
     268                break;
     269
     270            case SHFL_FILE_CREATED:
     271                Log(("VBOXSF: vbsfNtCreateWorker: File created (Handle=%#RX64) / FILE_CREATED\n", pReq->CreateParms.Handle));
     272                /* A new file was created. */
     273                Assert(pReq->CreateParms.Handle != SHFL_HANDLE_NIL);
     274                *pulCreateAction = FILE_CREATED;
     275                break;
     276
     277            case SHFL_FILE_REPLACED:
     278                /* An existing file was replaced or overwritten. */
     279                Assert(pReq->CreateParms.Handle != SHFL_HANDLE_NIL);
     280                if (CreateDisposition == FILE_SUPERSEDE)
     281                {
     282                    Log(("VBOXSF: vbsfNtCreateWorker: File replaced (Handle=%#RX64) / FILE_SUPERSEDED\n", pReq->CreateParms.Handle));
     283                    *pulCreateAction = FILE_SUPERSEDED;
     284                }
     285                else
     286                {
     287                    Log(("VBOXSF: vbsfNtCreateWorker: File replaced (Handle=%#RX64) / FILE_OVERWRITTEN\n", pReq->CreateParms.Handle));
     288                    *pulCreateAction = FILE_OVERWRITTEN;
     289                }
     290                break;
    238291
    239292            default:
    240             {
     293                Log(("VBOXSF: vbsfNtCreateWorker: Invalid CreateResult from host (0x%08X)\n", pReq->CreateParms.Result));
    241294                *pulCreateAction = FILE_DOES_NOT_EXIST;
    242                 NTSTATUS Status = vbsfNtVBoxStatusToNt(vrc);
    243                 Log(("VBOXSF: vbsfProcessCreate: %Rrc -> %#010x + FILE_DOES_NOT_EXIST\n", vrc, Status));
    244                 return Status;
    245             }
     295                return vbsfNtCreateWorkerBail(STATUS_OBJECT_PATH_NOT_FOUND, pReq, pNetRootExtension);
    246296        }
    247     }
    248 
    249     /*
    250      * The request succeeded. Analyze host response,
    251      */
    252     switch (pReq->CreateParms.Result)
    253     {
    254         case SHFL_PATH_NOT_FOUND:
    255             /* Path to the object does not exist. */
    256             Log(("VBOXSF: vbsfProcessCreate: Path not found -> STATUS_OBJECT_PATH_NOT_FOUND + FILE_DOES_NOT_EXIST\n"));
     297
     298        /*
     299         * Check flags.
     300         */
     301        if (!(fOptions & FILE_NON_DIRECTORY_FILE) || !FlagOn(pReq->CreateParms.Info.Attr.fMode, RTFS_DOS_DIRECTORY))
     302        { /* likely */ }
     303        else
     304        {
     305            /* Caller wanted only a file, but the object is a directory. */
     306            Log(("VBOXSF: vbsfNtCreateWorker: -> STATUS_FILE_IS_A_DIRECTORY!\n"));
     307            return vbsfNtCreateWorkerBail(STATUS_FILE_IS_A_DIRECTORY, pReq, pNetRootExtension);
     308        }
     309
     310        if (!(fOptions & FILE_DIRECTORY_FILE) || FlagOn(pReq->CreateParms.Info.Attr.fMode, RTFS_DOS_DIRECTORY))
     311        { /* likely */ }
     312        else
     313        {
     314            /* Caller wanted only a directory, but the object is not a directory. */
     315            Log(("VBOXSF: vbsfNtCreateWorker: -> STATUS_NOT_A_DIRECTORY!\n"));
     316            return vbsfNtCreateWorkerBail(STATUS_NOT_A_DIRECTORY, pReq, pNetRootExtension);
     317        }
     318
     319        return STATUS_SUCCESS;
     320    }
     321
     322    /*
     323     * Failed. Map some VBoxRC to STATUS codes expected by the system.
     324     */
     325    switch (vrc)
     326    {
     327        case VERR_ALREADY_EXISTS:
     328            Log(("VBOXSF: vbsfNtCreateWorker: VERR_ALREADY_EXISTS -> STATUS_OBJECT_NAME_COLLISION + FILE_EXISTS\n"));
     329            *pulCreateAction = FILE_EXISTS;
     330            return STATUS_OBJECT_NAME_COLLISION;
     331
     332        /* On POSIX systems, the "mkdir" command returns VERR_FILE_NOT_FOUND when
     333           doing a recursive directory create. Handle this case.
     334
     335           bird: We end up here on windows systems too if opening a dir that doesn't
     336                 exists.  Thus, I've changed the SHFL_PATH_NOT_FOUND to SHFL_FILE_NOT_FOUND
     337                 so that FsPerf is happy. */
     338        case VERR_FILE_NOT_FOUND: /** @todo r=bird: this is a host bug, isn't it? */
     339            pReq->CreateParms.Result = SHFL_FILE_NOT_FOUND;
     340            pReq->CreateParms.Handle = SHFL_HANDLE_NIL;
    257341            *pulCreateAction = FILE_DOES_NOT_EXIST;
    258             return STATUS_OBJECT_PATH_NOT_FOUND;
    259 
    260         case SHFL_FILE_NOT_FOUND:
     342            Log(("VBOXSF: vbsfNtCreateWorker: VERR_FILE_NOT_FOUND -> STATUS_OBJECT_NAME_NOT_FOUND + FILE_DOES_NOT_EXIST\n"));
     343            return STATUS_OBJECT_NAME_NOT_FOUND;
     344
     345        default:
     346        {
    261347            *pulCreateAction = FILE_DOES_NOT_EXIST;
    262             if (pReq->CreateParms.Handle == SHFL_HANDLE_NIL)
    263             {
    264                 Log(("VBOXSF: vbsfProcessCreate: File not found -> STATUS_OBJECT_NAME_NOT_FOUND + FILE_DOES_NOT_EXIST\n"));
    265                 return STATUS_OBJECT_NAME_NOT_FOUND;
    266             }
    267             AssertMsgFailed(("VBOXSF: vbsfProcessCreate: WTF? File not found but have a handle!\n"));
    268             return vbsfNtCreateWorkerBail(STATUS_UNSUCCESSFUL, pReq, pNetRootExtension);
    269 
    270         case SHFL_FILE_EXISTS:
    271             Log(("VBOXSF: vbsfProcessCreate: File exists, Handle = %#RX64\n", pReq->CreateParms.Handle));
    272             if (pReq->CreateParms.Handle == SHFL_HANDLE_NIL)
    273             {
    274                 *pulCreateAction = FILE_EXISTS;
    275                 if (CreateDisposition == FILE_CREATE)
    276                 {
    277                     /* File was not opened because we requested a create. */
    278                     Log(("VBOXSF: vbsfProcessCreate: File exists already, create failed -> STATUS_OBJECT_NAME_COLLISION\n"));
    279                     return STATUS_OBJECT_NAME_COLLISION;
    280                 }
    281 
    282                 /* Actually we should not go here, unless we have no rights to open the object. */
    283                 Log(("VBOXSF: vbsfProcessCreate: Existing file was not opened! -> STATUS_ACCESS_DENIED\n"));
    284                 return STATUS_ACCESS_DENIED;
    285             }
    286 
    287             /* An existing file was opened. */
    288             *pulCreateAction = FILE_OPENED;
    289             break;
    290 
    291         case SHFL_FILE_CREATED:
    292             /* A new file was created. */
    293             Assert(pReq->CreateParms.Handle != SHFL_HANDLE_NIL);
    294             *pulCreateAction = FILE_CREATED;
    295             break;
    296 
    297         case SHFL_FILE_REPLACED:
    298             /* An existing file was replaced or overwritten. */
    299             Assert(pReq->CreateParms.Handle != SHFL_HANDLE_NIL);
    300             if (CreateDisposition == FILE_SUPERSEDE)
    301                 *pulCreateAction = FILE_SUPERSEDED;
    302             else
    303                 *pulCreateAction = FILE_OVERWRITTEN;
    304             break;
    305 
    306         default:
    307             Log(("VBOXSF: vbsfProcessCreate: Invalid CreateResult from host (0x%08X)\n",
    308                  pReq->CreateParms.Result));
    309             *pulCreateAction = FILE_DOES_NOT_EXIST;
    310             return vbsfNtCreateWorkerBail(STATUS_OBJECT_PATH_NOT_FOUND, pReq, pNetRootExtension);
    311     }
    312 
    313     /*
    314      * Check flags.
    315      */
    316     if (bf.NonDirectoryFile && FlagOn(pReq->CreateParms.Info.Attr.fMode, RTFS_DOS_DIRECTORY))
    317     {
    318         /* Caller wanted only a file, but the object is a directory. */
    319         Log(("VBOXSF: vbsfProcessCreate: File is a directory!\n"));
    320         return vbsfNtCreateWorkerBail(STATUS_FILE_IS_A_DIRECTORY, pReq, pNetRootExtension);
    321     }
    322 
    323     if (bf.DirectoryFile && !FlagOn(pReq->CreateParms.Info.Attr.fMode, RTFS_DOS_DIRECTORY))
    324     {
    325         /* Caller wanted only a directory, but the object is not a directory. */
    326         Log(("VBOXSF: vbsfProcessCreate: File is not a directory!\n"));
    327         return vbsfNtCreateWorkerBail(STATUS_NOT_A_DIRECTORY, pReq, pNetRootExtension);
    328     }
    329 
    330     return STATUS_SUCCESS;
     348            NTSTATUS Status = vbsfNtVBoxStatusToNt(vrc);
     349            Log(("VBOXSF: vbsfNtCreateWorker: %Rrc -> %#010x + FILE_DOES_NOT_EXIST\n", vrc, Status));
     350            return Status;
     351        }
     352    }
    331353}
    332354
     
    354376     * Log stuff and make some small adjustments to empty paths and caching flags.
    355377     */
    356     Log(("VBOXSF: VBoxMRxCreate: FileAttributes = %#010x\n", RxContext->Create.NtCreateParameters.FileAttributes));
     378    Log(("VBOXSF: VBoxMRxCreate:  CreateOptions = %#010x\n", RxContext->Create.NtCreateParameters.CreateOptions));
     379    Log(("VBOXSF: VBoxMRxCreate:    Disposition = %#010x\n", RxContext->Create.NtCreateParameters.Disposition));
    357380    Log(("VBOXSF: VBoxMRxCreate:  DesiredAccess = %#010x\n", RxContext->Create.NtCreateParameters.DesiredAccess));
    358381    Log(("VBOXSF: VBoxMRxCreate:    ShareAccess = %#010x\n", RxContext->Create.NtCreateParameters.ShareAccess));
    359     Log(("VBOXSF: VBoxMRxCreate:    Disposition = %#010x\n", RxContext->Create.NtCreateParameters.Disposition));
    360     Log(("VBOXSF: VBoxMRxCreate:  CreateOptions = %#010x\n", RxContext->Create.NtCreateParameters.CreateOptions));
     382    Log(("VBOXSF: VBoxMRxCreate: FileAttributes = %#010x\n", RxContext->Create.NtCreateParameters.FileAttributes));
    361383    Log(("VBOXSF: VBoxMRxCreate: AllocationSize = %#RX64\n", RxContext->Create.NtCreateParameters.AllocationSize.QuadPart));
    362384    Log(("VBOXSF: VBoxMRxCreate: name ptr %p length=%d, SrvOpen->Flags %#010x\n",
     
    562584            Log(("VBOXSF: VBoxMRxCreate: NetRoot is %p, Fcb is %p, pSrvOpen is %p, Fobx is %p\n",
    563585                 pNetRoot, capFcb, pSrvOpen, RxContext->pFobx));
    564             Log(("VBOXSF: VBoxMRxCreate: returns %#010x\n", Status));
     586            Log(("VBOXSF: VBoxMRxCreate: returns STATUS_SUCCESS\n"));
    565587        }
    566588        else
     
    574596    }
    575597    else
    576         Log(("VBOXSF: VBoxMRxCreate: vbsfProcessCreate failed %#010x\n", Status));
     598        Log(("VBOXSF: VBoxMRxCreate: vbsfNtCreateWorker failed %#010x\n", Status));
    577599    VbglR0PhysHeapFree(pReq);
    578600    return Status;
     
    891913    else
    892914    {
    893         Log(("VBOXSF: vbsfNtRemove: VbglR0SfRemove failed with %Rrc\n", vrc));
     915        Log(("VBOXSF: vbsfNtRemove: %s failed with %Rrc\n",
     916             g_uSfLastFunction >= SHFL_FN_CLOSE_AND_REMOVE ? "VbglR0SfHostReqCloseAndRemove" : "VbglR0SfHostReqRemove", vrc));
    894917        Status = vbsfNtVBoxStatusToNt(vrc);
    895918    }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette