VirtualBox

Changeset 33437 in vbox for trunk


Ignore:
Timestamp:
Oct 25, 2010 4:28:14 PM (14 years ago)
Author:
vboxsync
Message:

iprt: Made tstRTSymlink work on Windows.

Location:
trunk/src/VBox/Runtime
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/fs.cpp

    r30365 r33437  
    9191        }
    9292    }
     93
     94    /* Is it really a symbolic link? */
     95    if (fMode & RTFS_DOS_NT_REPARSE_POINT)
     96        fMode = (fMode & ~RTFS_TYPE_MASK) | RTFS_TYPE_SYMLINK;
     97
    9398    /* writable? */
    9499    if (!(fMode & RTFS_DOS_READONLY))
  • trunk/src/VBox/Runtime/r3/win/path-win.cpp

    r33337 r33437  
    55
    66/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2006-2010 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    224224            }
    225225            FindClose(hDir);
    226             Data.dwFileAttributes = FindData.dwFileAttributes;
    227             Data.ftCreationTime = FindData.ftCreationTime;
    228             Data.ftLastAccessTime = FindData.ftLastAccessTime;
    229             Data.ftLastWriteTime = FindData.ftLastWriteTime;
    230             Data.nFileSizeHigh = FindData.nFileSizeHigh;
    231             Data.nFileSizeLow = FindData.nFileSizeLow;
     226
     227            Data.dwFileAttributes   = FindData.dwFileAttributes;
     228            Data.ftCreationTime     = FindData.ftCreationTime;
     229            Data.ftLastAccessTime   = FindData.ftLastAccessTime;
     230            Data.ftLastWriteTime    = FindData.ftLastWriteTime;
     231            Data.nFileSizeHigh      = FindData.nFileSizeHigh;
     232            Data.nFileSizeLow       = FindData.nFileSizeLow;
    232233        }
    233234        else
     
    238239        }
    239240    }
    240     RTUtf16Free(pwszPath);
     241
     242    /*
     243     * Getting the information for the link target is a bit annoying and
     244     * subject to the same access violation mess as above.. :/
     245     */
     246    /** @todo we're too lazy wrt to error paths here... */
    241247    if (   (fFlags & RTPATH_F_FOLLOW_LINK)
    242248        && (Data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))
    243249    {
    244 #ifndef DEBUG_sandervl
    245         AssertFailed();
    246 #endif
    247         /** @todo Symlinks: RTPathQueryInfoEx is not handling symbolic links
    248          *        correctly on Windows.  (Both GetFileAttributesEx and FileFindFirst
    249          *        will return info about the symlink.) */
    250     }
     250        HANDLE hFinal = CreateFileW(pwszPath,
     251                                    GENERIC_READ,
     252                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     253                                    NULL,
     254                                    OPEN_EXISTING,
     255                                    FILE_FLAG_BACKUP_SEMANTICS,
     256                                    NULL);
     257        if (hFinal != INVALID_HANDLE_VALUE)
     258        {
     259            BY_HANDLE_FILE_INFORMATION FileData;
     260            if (GetFileInformationByHandle(hFinal, &FileData))
     261            {
     262                Data.dwFileAttributes   = FileData.dwFileAttributes;
     263                Data.ftCreationTime     = FileData.ftCreationTime;
     264                Data.ftLastAccessTime   = FileData.ftLastAccessTime;
     265                Data.ftLastWriteTime    = FileData.ftLastWriteTime;
     266                Data.nFileSizeHigh      = FileData.nFileSizeHigh;
     267                Data.nFileSizeLow       = FileData.nFileSizeLow;
     268            }
     269            CloseHandle(hFinal);
     270        }
     271        else if (GetLastError() != ERROR_SHARING_VIOLATION)
     272        {
     273            rc = RTErrConvertFromWin32(GetLastError());
     274            RTUtf16Free(pwszPath);
     275            return rc;
     276        }
     277    }
     278
     279    RTUtf16Free(pwszPath);
    251280
    252281    /*
  • trunk/src/VBox/Runtime/r3/win/symlink-win.cpp

    r33429 r33437  
    4444
    4545
     46/*******************************************************************************
     47*   Structures and Typedefs                                                    *
     48*******************************************************************************/
     49typedef struct MY_REPARSE_DATA_BUFFER
     50{
     51    ULONG           ReparseTag;
     52#define MY_IO_REPARSE_TAG_SYMLINK       0xa000000c
     53#define MY_IO_REPARSE_TAG_MOUNT_POINT   0xa0000003
     54
     55    USHORT          ReparseDataLength;
     56    USHORT          Reserved;
     57    union
     58    {
     59        struct
     60        {
     61            USHORT  SubstituteNameOffset;
     62            USHORT  SubstituteNameLength;
     63            USHORT  PrintNameOffset;
     64            USHORT  PrintNameLength;
     65            ULONG   Flags;
     66#define MY_SYMLINK_FLAG_RELATIVE 1
     67            WCHAR   PathBuffer[1];
     68        } SymbolicLinkReparseBuffer;
     69        struct
     70        {
     71            USHORT  SubstituteNameOffset;
     72            USHORT  SubstituteNameLength;
     73            USHORT  PrintNameOffset;
     74            USHORT  PrintNameLength;
     75            WCHAR   PathBuffer[1];
     76        } MountPointReparseBuffer;
     77        struct
     78        {
     79            UCHAR   DataBuffer[1];
     80        } GenericReparseBuffer;
     81    };
     82} MY_REPARSE_DATA_BUFFER;
     83#define MY_FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
     84
     85
    4686RTDECL(bool) RTSymlinkExists(const char *pszSymlink)
    4787{
     
    68108        {
    69109            rc = RTPathQueryInfoEx(pszSymlink, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
    70             fRc = RT_SUCCESS(rc);
     110            fRc = !RT_SUCCESS_NP(rc);
    71111        }
    72112    }
     
    126166            size_t cchTarget        = strlen(pszTarget);
    127167            size_t cchVolSpecTarget = rtPathVolumeSpecLen(pszTarget);
     168#if 0 /* looks like this isn't needed after all. That makes everything much simper :-) */
    128169            if (   cchTarget > RT_MIN(cchVolSpecTarget, 1)
    129170                && RTPATH_IS_SLASH(pszTarget[cchTarget - 1]))
     
    140181                }
    141182            }
     183#endif
    142184
    143185            if (enmType == RTSYMLINKTYPE_UNKNOWN)
     
    148190                else if (cchVolSpecTarget)
    149191                {
     192                    /** @todo this is subject to sharing violations. */
    150193                    DWORD dwAttr = GetFileAttributesW(pwszNativeTarget);
    151194                    if (   dwAttr != INVALID_FILE_ATTRIBUTES
     
    247290                                      NULL,
    248291                                      OPEN_EXISTING,
    249                                       FILE_FLAG_OPEN_REPARSE_POINT,
     292                                      FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
    250293                                      NULL);
    251294        if (hSymlink != INVALID_HANDLE_VALUE)
    252295        {
    253             /** @todo what do we do next? FSCTL_GET_REPARSE_POINT? */
    254             rc = VERR_NOT_IMPLEMENTED;
    255 
     296            DWORD cbReturned = 0;
     297            union
     298            {
     299                MY_REPARSE_DATA_BUFFER  Buf;
     300                uint8_t                 abBuf[16*_1K + sizeof(WCHAR)];
     301            } u;
     302            if (DeviceIoControl(hSymlink,
     303                                MY_FSCTL_GET_REPARSE_POINT,
     304                                NULL /*pInBuffer */,
     305                                0 /*cbInBuffer */,
     306                                &u.Buf,
     307                                sizeof(u) - sizeof(WCHAR),
     308                                &cbReturned,
     309                                NULL /*pOverlapped*/))
     310            {
     311                if (u.Buf.ReparseTag == MY_IO_REPARSE_TAG_SYMLINK)
     312                {
     313                    PWCHAR pwszTarget = &u.Buf.SymbolicLinkReparseBuffer.PathBuffer[0];
     314                    pwszTarget += u.Buf.SymbolicLinkReparseBuffer.SubstituteNameOffset / 2;
     315                    pwszTarget[u.Buf.SymbolicLinkReparseBuffer.SubstituteNameLength / 2] = 0;
     316                    if (   !(u.Buf.SymbolicLinkReparseBuffer.Flags & MY_SYMLINK_FLAG_RELATIVE)
     317                        && pwszTarget[0] == '\\'
     318                        && pwszTarget[1] == '?'
     319                        && pwszTarget[2] == '?'
     320                        && pwszTarget[3] == '\\'
     321                        && pwszTarget[4] != 0
     322                       )
     323                        pwszTarget += 4;
     324                    rc = RTUtf16ToUtf8(pwszTarget, ppszTarget);
     325                }
     326                else
     327                    rc = VERR_NOT_SYMLINK;
     328            }
     329            else
     330                rc = RTErrConvertFromWin32(GetLastError());
    256331            CloseHandle(hSymlink);
    257332        }
  • trunk/src/VBox/Runtime/win/RTErrConvertFromWin32.cpp

    r30093 r33437  
    396396        //case WSANO_RECOVERY          (WSABASEERR+1003)
    397397        //case WSANO_DATA              (WSABASEERR+1004)
     398
     399
     400#ifndef ERROR_NOT_A_REPARSE_POINT
     401# define ERROR_NOT_A_REPARSE_POINT 0x1126
     402#endif
     403        case ERROR_NOT_A_REPARSE_POINT: return VERR_NOT_SYMLINK;
     404
    398405    }
    399406
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