/*************************************************************************
 *
 *  $RCSfile: strmos2.cxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 17:03:09 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <string.h>
#include <limits.h>

#define INCL_PM
#define INCL_DOS
#include <svpm.h>
#include <bseerr.h>

#include <debug.hxx>
#include <fsys.hxx>
#include <stream.hxx>
#include <fastfsys.hxx>

// -----------------------------------------------------------------------

// --------------
// - StreamData -
// --------------

class StreamData
{
public:
    HFILE   hFile;
    BOOL    bIsEof;

            StreamData()
            {
                hFile = 0;
                bIsEof = TRUE;
            }
};

// -----------------------------------------------------------------------

ULONG GetSvError( APIRET nPMError )
{
    static struct { APIRET pm; ULONG sv; } errArr[] =
    {
        { ERROR_FILE_NOT_FOUND,         SVSTREAM_FILE_NOT_FOUND },
        { ERROR_PATH_NOT_FOUND,         SVSTREAM_PATH_NOT_FOUND },
        { ERROR_TOO_MANY_OPEN_FILES,    SVSTREAM_TOO_MANY_OPEN_FILES },
        { ERROR_ACCESS_DENIED,          SVSTREAM_ACCESS_DENIED },
        { ERROR_INVALID_ACCESS,         SVSTREAM_INVALID_ACCESS },
        { ERROR_SHARING_VIOLATION,      SVSTREAM_SHARING_VIOLATION },
        { ERROR_SHARING_BUFFER_EXCEEDED,SVSTREAM_SHARE_BUFF_EXCEEDED },
        { ERROR_CANNOT_MAKE,            SVSTREAM_CANNOT_MAKE },
        { ERROR_INVALID_PARAMETER,      SVSTREAM_INVALID_PARAMETER },
        { ERROR_DRIVE_LOCKED,           SVSTREAM_LOCKING_VIOLATION },
        { ERROR_LOCK_VIOLATION,      SVSTREAM_LOCKING_VIOLATION },
        { ERROR_FILENAME_EXCED_RANGE,   SVSTREAM_INVALID_PARAMETER },
        { ERROR_ATOMIC_LOCK_NOT_SUPPORTED, SVSTREAM_INVALID_PARAMETER },
        { ERROR_READ_LOCKS_NOT_SUPPORTED, SVSTREAM_INVALID_PARAMETER },


        { 0xFFFF, SVSTREAM_GENERALERROR }
    };

    ULONG nRetVal = SVSTREAM_GENERALERROR;    // Standardfehler
    int i=0;
    do
    {
        if( errArr[i].pm == nPMError )
        {
            nRetVal = errArr[i].sv;
            break;
        }
        i++;
    }
    while( errArr[i].pm != 0xFFFF );
    return nRetVal;
}

/*************************************************************************
|*
|*    SvFileStream::SvFileStream()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/

SvFileStream::SvFileStream( const String& rFileName, StreamMode nOpenMode )
{
    bIsOpen             = FALSE;
    nLockCounter        = 0;
    bIsWritable         = FALSE;
    pInstanceData       = new StreamData;

    SetBufferSize( 8192 );
    Open( rFileName, nOpenMode );
}

/*************************************************************************
|*
|*    SvFileStream::SvFileStream()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 22.11.94
|*    Letzte Aenderung  OV 22.11.94
|*
*************************************************************************/

SvFileStream::SvFileStream()
{
    bIsOpen             = FALSE;
    nLockCounter        = 0;
    bIsWritable         = FALSE;
    pInstanceData       = new StreamData;
    SetBufferSize( 8192 );
}

/*************************************************************************
|*
|*    SvFileStream::~SvFileStream()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 14.06.94
|*    Letzte Aenderung  OV 14.06.94
|*
*************************************************************************/

SvFileStream::~SvFileStream()
{
    Close();
    if( pInstanceData )
        delete pInstanceData;
}

/*************************************************************************
|*
|*    SvFileStream::GetFileHandle()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 14.06.94
|*    Letzte Aenderung  OV 14.06.94
|*
*************************************************************************/

ULONG SvFileStream::GetFileHandle() const
{
    return (ULONG)pInstanceData->hFile;
}

/*************************************************************************
|*
|*    SvFileStream::IsA()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 14.06.94
|*    Letzte Aenderung  OV 14.06.94
|*
*************************************************************************/

USHORT SvFileStream::IsA() const
{
    return ID_FILESTREAM;
}

/*************************************************************************
|*
|*    SvFileStream::GetData()
|*
|*    Beschreibung      STREAM.SDW, Prueft nicht Eof; IsEof danach rufbar
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/

ULONG SvFileStream::GetData( char* pData, ULONG nSize )
{
#ifdef DBG_UTIL
    String aTraceStr( "SvFileStream::GetData(): " );
    aTraceStr += nSize;
    aTraceStr += " Bytes from ";
    aTraceStr += aFilename;
    DBG_TRACE( aTraceStr );
#endif

    ULONG nCount = 0L;
    if( IsOpen() )
    {
        APIRET nResult;
        nResult = DosRead( pInstanceData->hFile,(PVOID)pData,nSize,&nCount );
        if( nResult )
            SetError(::GetSvError(nResult) );
    }
    return nCount;
}

/*************************************************************************
|*
|*    SvFileStream::PutData()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/

ULONG SvFileStream::PutData( const char* pData, ULONG nSize )
{
#ifdef DBG_UTIL
    String aTraceStr( "SvFileStrean::PutData: " );
    aTraceStr += nSize;
    aTraceStr += " Bytes to ";
    aTraceStr += aFilename;
    DBG_TRACE( aTraceStr );
#endif

    ULONG nCount = 0L;
    if( IsOpen() )
    {
        APIRET nResult;
        nResult = DosWrite( pInstanceData->hFile,(PVOID)pData,nSize,&nCount );
        if( nResult )
            SetError(::GetSvError(nResult) );
        else if( !nCount )
            SetError( SVSTREAM_DISK_FULL );
    }
    return nCount;
}

/*************************************************************************
|*
|*    SvFileStream::SeekPos()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/

ULONG SvFileStream::SeekPos( ULONG nPos )
{
    ULONG nNewPos = 0L;
    if( IsOpen() )
    {
        APIRET nResult;

        if( nPos != STREAM_SEEK_TO_END )
            nResult = DosSetFilePtr( pInstanceData->hFile,(long)nPos,
                 FILE_BEGIN, &nNewPos );
        else
            nResult = DosSetFilePtr( pInstanceData->hFile,0L,
                 FILE_END, &nNewPos );

        if( nResult )
            SetError(::GetSvError(nResult) );
    }
    else
        SetError( SVSTREAM_GENERALERROR );
    return nNewPos;
}

/*************************************************************************
|*
|*    SvFileStream::Tell()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/
/*
ULONG SvFileStream::Tell()
{
    ULONG nPos = 0L;

    if( IsOpen() )
    {
        APIRET nResult;
        nResult = DosSetFilePtr(pInstanceData->hFile,0L,FILE_CURRENT,&nPos);
        if( nResult )
            SetError(::GetSvError(nResult) );
    }
    return nPos;
}
*/

/*************************************************************************
|*
|*    SvFileStream::FlushData()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/

void SvFileStream::FlushData()
{
    if( IsOpen() )
    {
        APIRET nResult;
        nResult = DosResetBuffer(pInstanceData->hFile );
        if( nResult )
            SetError(::GetSvError(nResult) );
    }
}

/*************************************************************************
|*
|*    SvFileStream::LockRange()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/

BOOL SvFileStream::LockRange( ULONG nByteOffset, ULONG nBytes )
{
    BOOL bRetVal = FALSE;
    if( IsOpen() )
    {
        APIRET   nResult;
        FILELOCK aLockArea, aUnlockArea;
        aUnlockArea.lOffset = 0L;
        aUnlockArea.lRange      = 0L;
        aLockArea.lOffset       = (long)nByteOffset;
        aLockArea.lRange        = (long)nBytes;

        nResult = DosSetFileLocks(pInstanceData->hFile,
            &aUnlockArea, &aLockArea,
            1000UL,  // Zeit in ms bis Abbruch
            0L       // kein Atomic-Lock
        );

        if( nResult )
            SetError(::GetSvError(nResult) );
        else
            bRetVal = TRUE;
    }
    return bRetVal;
}

/*************************************************************************
|*
|*    SvFileStream::UnlockRange()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/

BOOL SvFileStream::UnlockRange( ULONG nByteOffset, ULONG nBytes )
{
    BOOL bRetVal = FALSE;
    if( IsOpen() )
    {
        APIRET   nResult;
        FILELOCK aLockArea, aUnlockArea;
        aLockArea.lOffset       = 0L;
        aLockArea.lRange        = 0L;
        aUnlockArea.lOffset = (long)nByteOffset;
        aUnlockArea.lRange      = (long)nBytes;

        nResult = DosSetFileLocks(pInstanceData->hFile,
            &aUnlockArea, &aLockArea,
            1000UL,  // Zeit in ms bis Abbruch
            0L       // kein Atomic-Lock
        );

        if( nResult )
            SetError(::GetSvError(nResult) );
        else
            bRetVal = TRUE;
    }
    return bRetVal;
}

/*************************************************************************
|*
|*    SvFileStream::LockFile()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/

BOOL SvFileStream::LockFile()
{
    BOOL bRetVal = FALSE;
    if( !nLockCounter )
    {
        if( LockRange( 0L, LONG_MAX ) )
        {
            nLockCounter = 1;
            bRetVal = TRUE;
        }
    }
    else
    {
        nLockCounter++;
        bRetVal = TRUE;
    }
    return bRetVal;
}

/*************************************************************************
|*
|*    SvFileStream::UnlockFile()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/

BOOL SvFileStream::UnlockFile()
{
    BOOL bRetVal = FALSE;
    if( nLockCounter > 0)
    {
        if( nLockCounter == 1)
        {
            if( UnlockRange( 0L, LONG_MAX ) )
            {
                nLockCounter = 0;
                bRetVal = TRUE;
            }
        }
        else
        {
            nLockCounter--;
            bRetVal = TRUE;
        }
    }
    return bRetVal;
}

/*************************************************************************
|*
|*    SvFileStream::Open()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/

BOOL createLongNameEA   ( const PCSZ pszPath, ULONG ulAttributes, const String& aLongName );

void SvFileStream::Open( const String& rFilename, StreamMode nOpenMode )
{
        String aParsedFilename;

        if      ( Folder::IsAvailable() && (rFilename.Search("{") < 9) )
        {
                String          aVirtualPart;
                String          aRealPart;
                String          aVirtualPath;
                ItemIDPath      aVirtualURL;
                ULONG           nDivider = 0;

                String          aVirtualString(rFilename);

                for (int x=aVirtualString.Len(); x>0; x--)
                {
                        if (aVirtualString.Copy(x,1).Compare("}")==COMPARE_EQUAL)
                        {
                                nDivider = x;
                                break;
                        }
                }

                aVirtualPart = aVirtualString.Copy(0,nDivider+1);
                aRealPart = aVirtualString.Copy(nDivider+2);

                aVirtualURL  = aVirtualPart;
                aVirtualPath = aVirtualURL.GetHostNotationPath();

                DirEntry aTempDirEntry(aVirtualPath);

                aTempDirEntry += aRealPart;

                aParsedFilename = aTempDirEntry.GetFull();
        }
        else
        {
                aParsedFilename = rFilename;
        }

    Close();
    SvStream::ClearBuffer();

    ULONG   nActionTaken;
    ULONG   nOpenAction     = 0L;
    ULONG   nShareBits      = 0L;
    ULONG   nReadWriteBits  = 0L;

    eStreamMode = nOpenMode;
    eStreamMode &= ~STREAM_TRUNC; // beim ReOpen nicht cutten

    nOpenMode |= STREAM_SHARE_DENYNONE;  // definierten Zustand garantieren

    // ********* Zugriffsflags ***********
    if( nOpenMode & STREAM_SHARE_DENYNONE)
        nShareBits = OPEN_SHARE_DENYNONE;

    if( nOpenMode & STREAM_SHARE_DENYREAD)
        nShareBits = OPEN_SHARE_DENYREAD;

    if( nOpenMode & STREAM_SHARE_DENYWRITE)
        nShareBits = OPEN_SHARE_DENYWRITE;

    if( nOpenMode & STREAM_SHARE_DENYALL)
        nShareBits = OPEN_SHARE_DENYREADWRITE;

        if( (nOpenMode & STREAM_READ) )
    {
        if( nOpenMode & STREAM_WRITE )
            nReadWriteBits |= OPEN_ACCESS_READWRITE;
        else
        {
            nReadWriteBits |= OPEN_ACCESS_READONLY;
            nOpenMode |= STREAM_NOCREATE;
        }
    }
    else
        nReadWriteBits |= OPEN_ACCESS_WRITEONLY;


    if( nOpenMode & STREAM_NOCREATE )
    {
        // Datei nicht erzeugen
        nOpenAction = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
    }
    else
    {
        // Datei erzeugen, wenn nicht vorhanden
        nOpenAction = OPEN_ACTION_CREATE_IF_NEW;
        if( nOpenMode & STREAM_TRUNC )
            // Auf Nullaenge kuerzen, wenn existiert
            nOpenAction |= OPEN_ACTION_REPLACE_IF_EXISTS;
        else
            // Inhalt der Datei nicht wegwerfen
            nOpenAction |= OPEN_ACTION_OPEN_IF_EXISTS;
    }

    //
    // resolves long FAT names used by OS2
    //
    BOOL bIsLongOS2=FALSE;
    if (Folder::IsAvailable())
    {
        DirEntry aDirEntry(rFilename);
        if  (aDirEntry.IsLongNameOnFAT())
        {
            // in kurzen Pfad wandeln
            ItemIDPath      aItemIDPath(rFilename);
            aParsedFilename = aItemIDPath.GetHostNotationPath();
            bIsLongOS2 = TRUE;
        }
    }

    aFilename = aParsedFilename;
    FSysRedirector::DoRedirect( aFilename );

#ifdef DBG_UTIL
    String aTraceStr( "SvFileStream::Open(): " );
    aTraceStr += aFilename;
    DBG_TRACE( aTraceStr );
#endif

    APIRET nRet = DosOpen( (const char*)aFilename, &pInstanceData->hFile,
    &nActionTaken, 0L, FILE_NORMAL, nOpenAction,
    nReadWriteBits | nShareBits | OPEN_FLAGS_NOINHERIT, 0L);

    if( nRet == ERROR_TOO_MANY_OPEN_FILES )
    {
        long nToAdd = 10;
        ULONG nCurMaxFH;
        nRet = DosSetRelMaxFH( &nToAdd, &nCurMaxFH );
        nRet = DosOpen( (const char*)aFilename, &pInstanceData->hFile,
        &nActionTaken, 0L, FILE_NORMAL, nOpenAction,
        nReadWriteBits | nShareBits | OPEN_FLAGS_NOINHERIT, 0L);
    }

    // Bei Fehler pruefen, ob wir lesen duerfen
    if( nRet==ERROR_ACCESS_DENIED || nRet==ERROR_SHARING_VIOLATION )
    {
        nReadWriteBits = OPEN_ACCESS_READONLY;
        nRet = DosOpen( (const char*)aFilename, &pInstanceData->hFile,
            &nActionTaken, 0L, FILE_NORMAL, nOpenAction,
            nReadWriteBits | nShareBits | OPEN_FLAGS_NOINHERIT, 0L);
    }

        if( nRet )
    {
        bIsOpen = FALSE;
        SetError(::GetSvError(nRet) );
    }
    else
    {
        bIsOpen     = TRUE;
        pInstanceData->bIsEof = FALSE;
        if( nReadWriteBits != OPEN_ACCESS_READONLY )
            bIsWritable = TRUE;
    }

    if (bIsOpen && bIsLongOS2)
    {
        //file schlie�en, da sonst createLongName u.U. nicht m�glich
        Close();

        // erzeugtem File langen Namen geben
        DirEntry aDirEntry(rFilename);
        createLongNameEA((const char*)aFilename,  FILE_NORMAL, aDirEntry.GetName());

        // und wieder oeffnen
        ReOpen();
    }

}

/*************************************************************************
|*
|*    SvFileStream::ReOpen()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/

void SvFileStream::ReOpen()
{
    if( !bIsOpen && aFilename.Len() )
        Open( aFilename, eStreamMode );
}

/*************************************************************************
|*
|*    SvFileStream::Close()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/

void SvFileStream::Close()
{
    if( IsOpen() )
    {
#ifdef DBG_UTIL
        String aTraceStr( "SvFileStream::Close(): " );
        aTraceStr += aFilename;
        DBG_TRACE( aTraceStr );
#endif

        if( nLockCounter )
        {
            nLockCounter = 1;
            UnlockFile();
        }
        Flush();
        DosClose( pInstanceData->hFile );
    }

    bIsOpen     = FALSE;
    nLockCounter= 0;
    bIsWritable = FALSE;
    pInstanceData->bIsEof = TRUE;
    SvStream::ClearBuffer();
    SvStream::ClearError();
}

/*************************************************************************
|*
|*    SvFileStream::ResetError()
|*
|*    Beschreibung      STREAM.SDW; Setzt Filepointer auf Dateianfang
|*    Ersterstellung    OV 15.06.94
|*    Letzte Aenderung  OV 15.06.94
|*
*************************************************************************/

void SvFileStream::ResetError()
{
    SvStream::ClearError();
}

/*************************************************************************
|*
|*    SvFileStream::SetSize()
|*
|*    Beschreibung
|*    Ersterstellung    OV 19.10.95
|*    Letzte Aenderung  OV 19.10.95
|*
*************************************************************************/

void SvFileStream::SetSize( ULONG nSize )
{
    if( IsOpen() )
    {
        APIRET nRet = DosSetFileSize( pInstanceData->hFile, nSize );
        if( nRet )
            SetError( ::GetSvError( nRet ) );
    }
}

/*************************************************************************
|*
|*    SvSharedMemoryStream::AllocateMemory()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    CL 05.05.95
|*    Letzte Aenderung  CL 05.05.95
|*
*************************************************************************/

BOOL SvSharedMemoryStream::AllocateMemory( ULONG nNewSize )
{
        DBG_ASSERT(aHandle==0,"Keine Handles unter OS/2");
        DBG_ASSERT(nNewSize,"Cannot allocate zero Bytes");
        APIRET nRet = DosAllocSharedMem( (void**)&pBuf, (PSZ)NULL, nNewSize,
                                     PAG_READ | PAG_WRITE | PAG_COMMIT |
                                     OBJ_GIVEABLE | OBJ_GETTABLE );
    return( nRet == 0 );
}

/*************************************************************************
|*
|*    SvSharedMemoryStream::ReAllocateMemory()   (Bozo-Algorithmus)
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    CL 05.05.95
|*    Letzte Aenderung  CL 05.05.95
|*
*************************************************************************/

BOOL SvSharedMemoryStream::ReAllocateMemory( long nDiff )
{
        DBG_ASSERT(aHandle==0,"Keine Handles unter OS/2");
        BOOL bRetVal    = FALSE;
    ULONG nNewSize  = nSize + nDiff;
        if( nNewSize )
        {
                // neuen Speicher nicht ueber AllocateMemory holen, da wir den
                // alten Speicher behalten wollen, falls nicht genuegend Platz
                // fuer den neuen Block da ist
                char* pNewBuf;
            APIRET nRet = DosAllocSharedMem( (void**)&pNewBuf,(PSZ)NULL,nNewSize,
                                PAG_READ | PAG_WRITE | PAG_COMMIT |
                                OBJ_GIVEABLE | OBJ_GETTABLE );
            DBG_ASSERT(!nRet,"DosAllocSharedMem failed");

            if( !nRet )
            {
                bRetVal = TRUE; // Success!
                if( nNewSize < nSize )      // Verkleinern ?
                {
                    memcpy( pNewBuf, pBuf, (size_t)nNewSize );
                    if( nPos > nNewSize )
                        nPos = 0L;
                    if( nEndOfData >= nNewSize )
                        nEndOfData = nNewSize-1L;
                }
                else
                    memcpy( pNewBuf, pBuf, (size_t)nSize );

                FreeMemory(); // den alten Block loeschen ...

                        // und den neuen Block in Dienst stellen
                        pBuf  = pNewBuf;
                nSize = nNewSize;
            }
        }
        else
        {
                bRetVal = TRUE;
                FreeMemory();
                pBuf = 0;
                nSize = 0;
                nEndOfData = 0;
        }
    return bRetVal;
}

void SvSharedMemoryStream::FreeMemory()
{
        DBG_ASSERT(aHandle==0,"Keine Handles unter OS/2");
    DosFreeMem( pBuf );
}

/*************************************************************************
|*
|*    SvSharedMemoryStream::SetHandle()
|*
|*    Beschreibung      STREAM.SDW
|*    Ersterstellung    OV 05.10.95
|*    Letzte Aenderung  OV 05.10.95
|*
*************************************************************************/

void* SvSharedMemoryStream::SetHandle( void*, ULONG,BOOL, ULONG )
{
        DBG_ERROR("OS/2 does not support memory handles");
    // return SetBuffer(aNewHandle, nSize, bOwnsData, nEOF );
        return 0;
}