1   /************************************************************************
  2           Copy Handler 1.x - program for copying data in Microsoft Windows
  3                                                    systems.
  4           Copyright (C) 2001-2004 Ixen Gerthannes (copyhandler@o2.pl)
  5  
  6           This program is free software; you can redistribute it and/or modify
  7           it under the terms of the GNU General Public License as published by
  8           the Free Software Foundation; either version 2 of the License, or
  9           (at your option) any later version.
  10  
  11           This program is distributed in the hope that it will be useful,
  12           but WITHOUT ANY WARRANTY; without even the implied warranty of
  13           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14           GNU General Public License for more details.
  15  
  16           You should have received a copy of the GNU General Public License
  17           along with this program; if not, write to the Free Software
  18           Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19   *************************************************************************/
  20   #include "stdafx.h"
  21   #include "DataBuffer.h"
  22  
  23   bool BUFFERSIZES::operator==(const BUFFERSIZES& bsSizes) const
  24   {
  25           return (m_uiDefaultSize == bsSizes.m_uiDefaultSize
  26                           && m_uiOneDiskSize == bsSizes.m_uiOneDiskSize
  27                           && m_uiTwoDisksSize == bsSizes.m_uiTwoDisksSize
  28                           && m_uiCDSize == bsSizes.m_uiCDSize
  29                           && m_uiLANSize == bsSizes.m_uiLANSize);
  30   }
  31  
  32   void BUFFERSIZES::Serialize(CArchive& ar)
  33   {
  34           if (ar.IsStoring())
  35           {
  36                   ar<<m_uiDefaultSize;
  37                   ar<<m_uiOneDiskSize;
  38                   ar<<m_uiTwoDisksSize;
  39                   ar<<m_uiCDSize;
  40                   ar<<m_uiLANSize;
  41                   ar<<static_cast<unsigned char>(m_bOnlyDefault);
  42           }
  43           else
  44           {
  45                   ar>>m_uiDefaultSize;
  46                   ar>>m_uiOneDiskSize;
  47                   ar>>m_uiTwoDisksSize;
  48                   ar>>m_uiCDSize;
  49                   ar>>m_uiLANSize;
  50                   unsigned char ucTemp;
  51                   ar>>ucTemp;
  52                   m_bOnlyDefault=(ucTemp != 0);
  53           }
  54   }
  55  
  56   const BUFFERSIZES* CDataBuffer::Create(const BUFFERSIZES* pbsSizes)
  57   {
  58           // if trying to set 0-size buffer
  59           BUFFERSIZES bsSizes=*pbsSizes;  // copy - not to mix in the def. param
  60  
  61           if (bsSizes.m_uiDefaultSize == 0)
  62                   bsSizes.m_uiDefaultSize=DEFAULT_SIZE;
  63           if (bsSizes.m_uiOneDiskSize == 0)
  64                   bsSizes.m_uiOneDiskSize=DEFAULT_SIZE;
  65           if (bsSizes.m_uiTwoDisksSize == 0)
  66                   bsSizes.m_uiTwoDisksSize=DEFAULT_SIZE;
  67           if (bsSizes.m_uiCDSize == 0)
  68                   bsSizes.m_uiCDSize=DEFAULT_SIZE;
  69           if (bsSizes.m_uiLANSize == 0)
  70                   bsSizes.m_uiLANSize=DEFAULT_SIZE;
  71           
  72           // max value from the all
  73           UINT uiLargest;
  74           if (bsSizes.m_bOnlyDefault)
  75                   uiLargest=bsSizes.m_uiDefaultSize;
  76           else
  77           {
  78                   uiLargest=(bsSizes.m_uiDefaultSize > bsSizes.m_uiOneDiskSize ? bsSizes.m_uiDefaultSize : bsSizes.m_uiOneDiskSize);
  79                   if (uiLargest < bsSizes.m_uiTwoDisksSize)
  80                           uiLargest=bsSizes.m_uiTwoDisksSize;
  81                   if (uiLargest < bsSizes.m_uiCDSize)
  82                           uiLargest=bsSizes.m_uiCDSize;
  83                   if (uiLargest < bsSizes.m_uiLANSize)
  84                           uiLargest=bsSizes.m_uiLANSize;
  85           }
  86           
  87           // modify buffer size to the next 64k boundary
  88           UINT uiRealSize=ROUNDTODS(uiLargest);
  89           TRACE("Size: %lu, rounded: %lu\n", uiLargest, uiRealSize);
  90  
  91           if (m_uiRealSize == uiRealSize)
  92           {
  93                   // real buffersize doesn't changed
  94                   m_bsSizes=bsSizes;
  95                   
  96                   return &m_bsSizes;
  97           }
  98  
  99           // try to allocate
  100           LPVOID pBuffer=VirtualAlloc(NULL, uiRealSize, MEM_COMMIT, PAGE_READWRITE);
  101           if (pBuffer == NULL)
  102           {
  103                   if (m_pBuffer == NULL)
  104                   {
  105                           // try safe buffesize
  106                           pBuffer=VirtualAlloc(NULL, DEFAULT_SIZE, MEM_COMMIT, PAGE_READWRITE);
  107                           if (pBuffer == NULL)
  108                                   return &m_bsSizes;              // do not change anything
  109                           
  110                           // delete old buffer
  111                           Delete();
  112                           
  113                           // store data
  114                           m_pBuffer=static_cast<unsigned char*>(pBuffer);
  115                           m_uiRealSize=DEFAULT_SIZE;
  116                           m_bsSizes.m_bOnlyDefault=bsSizes.m_bOnlyDefault;
  117                           m_bsSizes.m_uiDefaultSize=DEFAULT_SIZE;
  118                           m_bsSizes.m_uiOneDiskSize=DEFAULT_SIZE;
  119                           m_bsSizes.m_uiTwoDisksSize=DEFAULT_SIZE;
  120                           m_bsSizes.m_uiCDSize=DEFAULT_SIZE;
  121                           m_bsSizes.m_uiLANSize=DEFAULT_SIZE;
  122                           
  123                           return &m_bsSizes;
  124                   }
  125                   else
  126                   {
  127                           // no new buffer could be created - leave the old one
  128                           return &m_bsSizes;
  129                   }
  130           }
  131           else
  132           {
  133                   // succeeded
  134                   Delete();       // get rid of old buffer
  135                   
  136                   // store data
  137                   m_pBuffer=static_cast<unsigned char*>(pBuffer);
  138                   m_uiRealSize=uiRealSize;
  139                   m_bsSizes=bsSizes;
  140                   
  141                   return &m_bsSizes;
  142           }
  143   }
  144  
  145   void CDataBuffer::Delete()
  146   {
  147           if (m_pBuffer != NULL)
  148           {
  149                   VirtualFree(static_cast<LPVOID>(m_pBuffer), m_uiRealSize, MEM_DECOMMIT);
  150                   m_pBuffer=NULL;
  151                   m_uiRealSize=0;
  152                   m_bsSizes.m_uiDefaultSize=0;
  153                   m_bsSizes.m_uiOneDiskSize=0;
  154                   m_bsSizes.m_uiTwoDisksSize=0;
  155                   m_bsSizes.m_uiCDSize=0;
  156                   m_bsSizes.m_uiLANSize=0;
  157           }
  158   }