VirtualBox

Changeset 77211 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 8, 2019 1:31:17 AM (6 years ago)
Author:
vboxsync
Message:

IPRT: Specialized RTFileWriteAt and RTFileReadAt for windows. bugref:9172

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r77210 r77211  
    815815        generic/RTDirExists-generic.cpp \
    816816        generic/RTDirSetTimes-generic.cpp \
    817         generic/fileio-at-generic.cpp \
    818817        generic/fileio-sg-generic.cpp \
    819818        generic/RTFileExists-generic.cpp \
     
    18571856        generic/RTDirExists-generic.cpp \
    18581857        generic/RTDirSetTimes-generic.cpp \
    1859         generic/fileio-at-generic.cpp \
    18601858        generic/RTFileExists-generic.cpp \
    18611859        generic/RTFileSetAllocationSize-generic.cpp \
  • trunk/src/VBox/Runtime/r3/win/fileio-win.cpp

    r76902 r77211  
    496496
    497497
     498RTDECL(int)  RTFileReadAt(RTFILE hFile, RTFOFF off, void *pvBuf, size_t cbToRead, size_t *pcbRead)
     499{
     500    ULONG cbToReadAdj = (ULONG)cbToRead;
     501    AssertReturn(cbToReadAdj == cbToRead, VERR_NUMBER_TOO_BIG);
     502
     503    OVERLAPPED Overlapped;
     504    Overlapped.Offset       = (uint32_t)off;
     505    Overlapped.OffsetHigh   = (uint32_t)(off >> 32);
     506    Overlapped.hEvent       = NULL;
     507    Overlapped.Internal     = 0;
     508    Overlapped.InternalHigh = 0;
     509
     510    ULONG cbRead = 0;
     511    if (ReadFile((HANDLE)RTFileToNative(hFile), pvBuf, cbToReadAdj, &cbRead, &Overlapped))
     512    {
     513        if (pcbRead)
     514            /* Caller can handle partial reads. */
     515            *pcbRead = cbRead;
     516        else
     517        {
     518            /* Caller expects everything to be read. */
     519            while (cbToReadAdj > cbRead)
     520            {
     521                Overlapped.Offset       = (uint32_t)(off + cbRead);
     522                Overlapped.OffsetHigh   = (uint32_t)((off + cbRead) >> 32);
     523                Overlapped.hEvent       = NULL;
     524                Overlapped.Internal     = 0;
     525                Overlapped.InternalHigh = 0;
     526
     527                ULONG cbReadPart = 0;
     528                if (!ReadFile((HANDLE)RTFileToNative(hFile), (char *)pvBuf + cbRead, cbToReadAdj - cbRead,
     529                              &cbReadPart, &Overlapped))
     530                    return RTErrConvertFromWin32(GetLastError());
     531                if (cbReadPart == 0)
     532                    return VERR_EOF;
     533                cbRead += cbReadPart;
     534            }
     535        }
     536        return VINF_SUCCESS;
     537    }
     538    return RTErrConvertFromWin32(GetLastError());
     539}
     540
     541
    498542RTR3DECL(int)  RTFileWrite(RTFILE hFile, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
    499543{
     
    584628
    585629    int rc = RTErrConvertFromWin32(dwErr);
     630    if (   rc == VERR_DISK_FULL
     631        && IsBeyondLimit(hFile, cbToWriteAdj - cbWritten, FILE_CURRENT))
     632        rc = VERR_FILE_TOO_BIG;
     633    return rc;
     634}
     635
     636
     637RTDECL(int)  RTFileWriteAt(RTFILE hFile, RTFOFF off, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
     638{
     639    ULONG const cbToWriteAdj = (ULONG)cbToWrite;
     640    AssertReturn(cbToWriteAdj == cbToWrite, VERR_NUMBER_TOO_BIG);
     641
     642    OVERLAPPED Overlapped;
     643    Overlapped.Offset       = (uint32_t)off;
     644    Overlapped.OffsetHigh   = (uint32_t)(off >> 32);
     645    Overlapped.hEvent       = NULL;
     646    Overlapped.Internal     = 0;
     647    Overlapped.InternalHigh = 0;
     648
     649    ULONG cbWritten = 0;
     650    if (WriteFile((HANDLE)RTFileToNative(hFile), pvBuf, cbToWriteAdj, &cbWritten, &Overlapped))
     651    {
     652        if (pcbWritten)
     653            /* Caller can handle partial writes. */
     654            *pcbWritten = RT_MIN(cbWritten, cbToWriteAdj); /* paranoia^3 */
     655        else
     656        {
     657            /* Caller expects everything to be written. */
     658            while (cbWritten < cbToWriteAdj)
     659            {
     660                Overlapped.Offset       = (uint32_t)(off + cbWritten);
     661                Overlapped.OffsetHigh   = (uint32_t)((off + cbWritten) >> 32);
     662                Overlapped.hEvent       = NULL;
     663                Overlapped.Internal     = 0;
     664                Overlapped.InternalHigh = 0;
     665
     666                ULONG cbWrittenPart = 0;
     667                if (!WriteFile((HANDLE)RTFileToNative(hFile), (char*)pvBuf + cbWritten,
     668                               cbToWriteAdj - cbWritten, &cbWrittenPart, &Overlapped))
     669                {
     670                    int rc = RTErrConvertFromWin32(GetLastError());
     671                    if (   rc == VERR_DISK_FULL
     672                        && IsBeyondLimit(hFile, cbToWriteAdj - cbWritten, FILE_CURRENT)
     673                       )
     674                        rc = VERR_FILE_TOO_BIG;
     675                    return rc;
     676                }
     677                if (cbWrittenPart == 0)
     678                    return VERR_WRITE_ERROR;
     679                cbWritten += cbWrittenPart;
     680            }
     681        }
     682        return VINF_SUCCESS;
     683    }
     684
     685    int rc = RTErrConvertFromWin32(GetLastError());
    586686    if (   rc == VERR_DISK_FULL
    587687        && IsBeyondLimit(hFile, cbToWriteAdj - cbWritten, FILE_CURRENT))
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