VirtualBox

Changeset 36367 in vbox for trunk/src/VBox/Runtime/r3/win


Ignore:
Timestamp:
Mar 23, 2011 3:04:52 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
70713
Message:

fileio-win.cpp: Handle ERROR_NOT_ENOUGH_MEMORY conditions occuring when console handles are pased to RTFileWrite and RTFileRead.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/win/fileio-win.cpp

    r36123 r36367  
    404404        return VINF_SUCCESS;
    405405    }
    406     return RTErrConvertFromWin32(GetLastError());
     406
     407    /*
     408     * If it's a console, we might bump into out of memory conditions in the
     409     * ReadConsole call. 
     410     */
     411    DWORD dwErr = GetLastError();
     412    if (dwErr == ERROR_NOT_ENOUGH_MEMORY)
     413    {
     414        ULONG cbChunk = cbToReadAdj / 2;
     415        if (cbChunk > 16*_1K)
     416            cbChunk = 16*_1K;
     417        else
     418            cbChunk = RT_ALIGN_32(cbChunk, 256);
     419
     420        cbRead = 0;
     421        while (cbToReadAdj > cbRead)
     422        {
     423            ULONG cbToRead   = RT_MIN(cbChunk, cbToReadAdj - cbRead);
     424            ULONG cbReadPart = 0;
     425            if (!ReadFile((HANDLE)File, (char *)pvBuf + cbRead, cbToRead, &cbReadPart, NULL))
     426            {
     427                /* If we failed because the buffer is too big, shrink it and
     428                   try again. */
     429                dwErr = GetLastError();
     430                if (   dwErr == ERROR_NOT_ENOUGH_MEMORY
     431                    && cbChunk > 8)
     432                {
     433                    cbChunk /= 2;
     434                    continue;
     435                }
     436                return RTErrConvertFromWin32(dwErr);
     437            }
     438            cbRead += cbReadPart;
     439
     440            /* Return if the caller can handle partial reads, otherwise try
     441               fill the buffer all the way up. */
     442            if (pcbRead)
     443            {
     444                *pcbRead = cbRead;
     445                break;
     446            }
     447            if (cbReadPart == 0)
     448                return VERR_EOF;
     449        }
     450        return VINF_SUCCESS;
     451    }
     452   
     453    return RTErrConvertFromWin32(dwErr);
    407454}
    408455
     
    443490        return VINF_SUCCESS;
    444491    }
    445     int rc = RTErrConvertFromWin32(GetLastError());
     492
     493    /*
     494     * If it's a console, we might bump into out of memory conditions in the
     495     * WriteConsole call. 
     496     */
     497    DWORD dwErr = GetLastError();
     498    if (dwErr == ERROR_NOT_ENOUGH_MEMORY)
     499    {
     500        ULONG cbChunk = cbToWriteAdj / 2;
     501        if (cbChunk > _32K)
     502            cbChunk = _32K;
     503        else
     504            cbChunk = RT_ALIGN_32(cbChunk, 256);
     505
     506        cbWritten = 0;
     507        while (cbToWriteAdj > cbWritten)
     508        {
     509            ULONG cbToWrite     = RT_MIN(cbChunk, cbToWriteAdj - cbWritten);
     510            ULONG cbWrittenPart = 0;
     511            if (!WriteFile((HANDLE)File, (const char *)pvBuf + cbWritten, cbToWrite, &cbWrittenPart, NULL))
     512            {
     513                /* If we failed because the buffer is too big, shrink it and
     514                   try again. */
     515                dwErr = GetLastError();
     516                if (   dwErr == ERROR_NOT_ENOUGH_MEMORY
     517                    && cbChunk > 8)
     518                {
     519                    cbChunk /= 2;
     520                    continue;
     521                }
     522                int rc = RTErrConvertFromWin32(dwErr);
     523                if (   rc == VERR_DISK_FULL
     524                    && IsBeyondLimit(File, cbToWriteAdj - cbWritten, FILE_CURRENT))
     525                    rc = VERR_FILE_TOO_BIG;
     526                return rc;
     527            }
     528            cbWritten += cbWrittenPart;
     529
     530            /* Return if the caller can handle partial writes, otherwise try
     531               write out everything. */
     532            if (pcbWritten)
     533            {
     534                *pcbWritten = cbWritten;
     535                break;
     536            }
     537            if (cbWrittenPart == 0)
     538                return VERR_WRITE_ERROR;
     539        }
     540        return VINF_SUCCESS;
     541    }
     542
     543    int rc = RTErrConvertFromWin32(dwErr);
    446544    if (   rc == VERR_DISK_FULL
    447545        && IsBeyondLimit(File, 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