Ejemplo n.º 1
0
/*-----------------------------------------------------------------------------
*  Zeichen in Empfangspuffer zurückschreiben
*/
uint8_t SioUnRead(int handle, uint8_t *pBuf, uint8_t bufSize) {

   unsigned int free;
   unsigned int used;
   unsigned int i;
   unsigned int rdIdx;
   unsigned int wrIdx;

   if (HandleValid(handle)) {
      wrIdx = sSio[handle].unRead.bufIdxWr;
      used = UnReadBufLen(handle);
      free = UNREAD_BUF_SIZE - 1 - used;

      for (i = 0; i < bufSize; i++) {
         sSio[handle].unRead.buf[wrIdx] = *(pBuf + i);
         wrIdx++;
         wrIdx &= (UNREAD_BUF_SIZE - 1);
      }
      // falls alte Daten im unread-buf überschrieben wurden: rdIdx korr.
      if (free < bufSize) {
         rdIdx = (wrIdx + 1) & (UNREAD_BUF_SIZE - 1);
         sSio[handle].unRead.bufIdxRd = rdIdx;
      }
      sSio[handle].unRead.bufIdxWr = wrIdx;
   }
   return bufSize;
}
Ejemplo n.º 2
0
/*-----------------------------------------------------------------------------
*  Sio Empfangspuffer lesen
*/
uint8_t SioRead(int handle, uint8_t *pBuf, uint8_t bufSize) {

   bool fSuccess;
   unsigned long bytesRead = 0;
   uint8_t readUnread;

   if (!HandleValid(handle)) {
      return 0;
   }

   readUnread = ReadUnRead(handle, pBuf, bufSize);
   if (readUnread < bufSize) {
      // noch Platz im Buffer
      fSuccess = ReadFile(sSio[handle].hCom, pBuf + readUnread,
                          bufSize - readUnread, &bytesRead ,NULL);
      if (!fSuccess) {
         CommErrorClear(handle);
      }
   }

#if 0
if (bytesRead != 0) {
   printf("sioread");
   for (int i = 0; i < bytesRead; i++) {
      printf(" %02x", *(pBuf + i));
   }
   printf("\r\n");
}
#endif

   return (uint8_t)(bytesRead + readUnread);
}
Ejemplo n.º 3
0
/*-----------------------------------------------------------------------------
*  trigger tx of buffer
*/
bool SioSendBuffer(int handle) {

    bool fSuccess;
   unsigned long bytesWritten = 123;
   TSioDesc      *pSio;
   bool          rc = false;

    if (!HandleValid(handle)) {
        return 0;
    }
    pSio = &sSio[handle];

    fSuccess = WriteFile(pSio->hCom, pSio->bufferedTx.buf, pSio->bufferedTx.pos, &bytesWritten ,NULL);
    if (!fSuccess) {
        printf("comm err\n");
        CommErrorClear(handle);
    } else {
        if (bytesWritten == pSio->bufferedTx.pos) {
            rc = true;
        }
    }
    pSio->bufferedTx.pos = 0;

    return rc;
}
Ejemplo n.º 4
0
/*-----------------------------------------------------------------------------
*  Schnittstelle zurücksetzen
*/
static void CommErrorClear(int handle) {

   if (HandleValid(handle)) {
      COMSTAT  comStat;
      DWORD    dwErrorFlags;
      ClearCommError(sSio[handle].hCom, &dwErrorFlags, &comStat);
   }
}
Ejemplo n.º 5
0
/*-----------------------------------------------------------------------------
*  Belegung des unread-buf
*/
static unsigned int UnReadBufLen(int handle) {

   unsigned int used = UNREAD_BUF_SIZE;

   if (HandleValid(handle)) {
      used = (sSio[handle].unRead.bufIdxWr - sSio[handle].unRead.bufIdxRd) &
             (UNREAD_BUF_SIZE - 1);
   }
   return used;
}
Ejemplo n.º 6
0
/*-----------------------------------------------------------------------------
*  Schnittstelle schließen
*/
int SioClose(int handle) {

   if (!HandleValid(handle)) {
      return -1;
   }

   sSio[handle].used = false;
   CloseHandle(sSio[handle].hCom);

   return 0;
}
Ejemplo n.º 7
0
/*-----------------------------------------------------------------------------
*  Sio Sendepuffer schreiben
*/
uint8_t SioWrite(int handle, uint8_t *pBuf, uint8_t bufSize) {

   bool fSuccess;
   unsigned long bytesWritten;

   if (!HandleValid(handle)) {
      return 0;
   }

   fSuccess = WriteFile(sSio[handle].hCom, pBuf, bufSize, &bytesWritten ,NULL);
   if (!fSuccess) {
      CommErrorClear(handle);
   }
   return (uint8_t)bytesWritten;
}
Ejemplo n.º 8
0
/*-----------------------------------------------------------------------------
*  Anzahl der Zeichen im Empfangspuffer
*/
uint8_t SioGetNumRxChar(int handle) {

   DWORD inLen;
   DWORD numRxChar = 0;

   if (HandleValid(handle)) {
      COMSTAT  comStat;
      DWORD    dwErrorFlags;
      ClearCommError(sSio[handle].hCom, &dwErrorFlags, &comStat);
      inLen = comStat.cbInQue;
      numRxChar = inLen + UnReadBufLen(handle);
      if (numRxChar > 255) {
         numRxChar = 255;
      }
   }
   return numRxChar;
}
Ejemplo n.º 9
0
/*-----------------------------------------------------------------------------
*  write data to tx buffer - do not yet start with tx
*/
uint8_t SioWriteBuffered(int handle, uint8_t *pBuf, uint8_t bufSize) {

   uint8_t   len;
   TSioDesc  *pSio;

   if (!HandleValid(handle)) {
      return 0;
   }
   pSio = &sSio[handle];

   len = sizeof(pSio->bufferedTx.buf) - pSio->bufferedTx.pos;
   len = min(len, bufSize);
   memcpy(&pSio->bufferedTx.buf[pSio->bufferedTx.pos], pBuf, len);
   pSio->bufferedTx.pos += len;

   return (uint8_t)len;
}
Ejemplo n.º 10
0
/*-----------------------------------------------------------------------------
*  Zeichen in Empfangspuffer zurückschreiben
*/
static uint8_t ReadUnRead(int handle, uint8_t *pBuf, uint8_t bufSize) {

   unsigned int len = 0;
   unsigned int used;
   unsigned int i;
   unsigned int rdIdx;

   if (HandleValid(handle)) {
      rdIdx = sSio[handle].unRead.bufIdxRd;
      used = UnReadBufLen(handle);
      len = min(bufSize, used);
      for (i = 0; i < len; i++) {
         *(pBuf + i) = sSio[handle].unRead.buf[rdIdx];
         rdIdx++;
         rdIdx &= (UNREAD_BUF_SIZE - 1);
      }
      sSio[handle].unRead.bufIdxRd = rdIdx;
   }
   return (uint8_t)len;
}
Ejemplo n.º 11
0
/**
    Write some data to the device.

    @param  aPos     media position in bytes
    @param  aLength  how many bytes to read
    @param  aDataDes data descriptor

    @return KErrNone on success, standard Epoc error code otherwise
*/
TInt CWinImgFileDevice::Write(TInt64 aPos, TInt aLength, const TDesC8& aDataDes)
{
    //__PRINT3(_L("#-- CWinImgFileDevice::Write, pos:%LU, len:%u, desLen:%u" ), aPos, aLength, aDataDes.Length());

    ASSERT(HandleValid());


    if(aLength == 0 || aDataDes.Length() == 0)
        return KErrNone;

    if(aLength > aDataDes.Length())
    {
        ASSERT(0);
        return KErrArgument;
    }

    //-- check position on the volume
    const TInt64 maxPos = iDrvGeometry.TotalSizeInBytes();
    if(aPos < 0 || aPos > maxPos)
        return KErrArgument;

    const TInt64 lastPos = aPos+aLength;

    if(lastPos > maxPos)
        return KErrArgument;

    TUint32 dataLen = aLength;


    DWORD dwRes;
    DWORD dwBytes = 0;
    
    const TUint8 *pData = aDataDes.Ptr();

    try
    {
        //-- 1. position to the media
        LONG  mediaPosHi = I64HIGH(aPos);
        const TUint32 mediaPosLo = I64LOW(aPos);
        dwRes = SetFilePointer(iDevHandle, mediaPosLo, &mediaPosHi, FILE_BEGIN);
        if(dwRes == INVALID_SET_FILE_POINTER)
        {    
            throw KDiskOpError;
        }
    
        //-- 2. write data to the media
        //-- check if the pointer is word-aligned
        const DWORD dwPtrMask = 0x01;
        
        if( (DWORD)pData & dwPtrMask)
        {//-- data pointer isn't aligned, write non-aligned bytes through buffer
            ASSERT(dataLen);

            const int oddCnt = 1;
            ipScratchBuf[0] = *pData;

            ++pData;
            --dataLen;

            if(!WriteFile(iDevHandle, ipScratchBuf, oddCnt, &dwBytes, NULL))
                throw KDiskOpError;
        }
        
        ASSERT(!((DWORD)pData & dwPtrMask));
        if(dataLen > 0)
        {
            if(!WriteFile(iDevHandle, pData, dataLen, &dwBytes, NULL))
                throw KDiskOpError;
        }
    
    }
    catch(TInt nErrId)
    {//-- some disk operation finished with the error
        (void)nErrId;
        ASSERT(nErrId == KDiskOpError);
        const DWORD dwWinErr = GetLastError();
        const TInt  epocErr = MapWinError(dwWinErr);
        
        __PRINT2(_L("#-- CWinImgFileDevice::Write() error! WinErr:%d, EpocErr:%d"), dwWinErr, epocErr);
        ASSERT(epocErr != KErrNone);
        return epocErr;
    }


    
    return KErrNone;
}
Ejemplo n.º 12
0
/**
    Read a portion of data from the device.
    Note: at present it _APPENDS_ data to the aDataDes, so the caller must take care of setting its length

    @param  aPos     media position in bytes
    @param  aLength  how many bytes to read
    @param  aDataDes data descriptor

    @return KErrNone on success, standard Epoc error code otherwise

*/
TInt CWinImgFileDevice::Read(TInt64 aPos,TInt aLength, TDes8& aDataDes)
{
    
    //__PRINT3(_L("#-- CWinImgFileDevice::Read, pos:%LU, len:%u, desMaxLen:%u"), aPos, aLength, aDataDes.MaxLength());

    ASSERT(HandleValid());
    ASSERT(aLength <= aDataDes.MaxLength());

    //-- check position on the volume
    const TInt64 maxPos = iDrvGeometry.TotalSizeInBytes();
    if(aPos < 0 || aPos > maxPos)
        return KErrArgument;

    const TInt64 lastPos = aPos+aLength;
    if(lastPos > maxPos)
        return KErrArgument;

    TUint32 dataLen = aLength;

    if(dataLen == 0)
        return KErrNone;

    DWORD dwRes;
    DWORD dwBytesRead = 0;

    //aDataDes.SetLength(0);

    try
    {
        //-- 1. position to the media 
        LONG  mediaPosHi = I64HIGH(aPos);
        const TUint32 mediaPosLo = I64LOW(aPos);

        dwRes = SetFilePointer(iDevHandle, mediaPosLo, &mediaPosHi, FILE_BEGIN);
        if(dwRes == INVALID_SET_FILE_POINTER)
            throw KDiskOpError;


        //-- 2. read data to the scratch buffer and copy it to the descriptor.
        ASSERT(ipScratchBuf);

        TUint32 rem = dataLen;
        
        while(rem)
        {
            const TUint32 bytesToRead = Min(KScratchBufSz, rem);
            if(!ReadFile(iDevHandle, ipScratchBuf, bytesToRead, &dwBytesRead, NULL))
                throw KDiskOpError;

            aDataDes.Append(ipScratchBuf, bytesToRead);
            rem-=bytesToRead;
        }

    }
    catch(TInt nErrId)
    {//-- some disk operation finished with the error
        (void)nErrId;
        ASSERT(nErrId == KDiskOpError);
        const DWORD dwWinErr = GetLastError();
        const TInt  epocErr = MapWinError(dwWinErr);
        
        __PRINT2(_L("#-- CWinImgFileDevice::Read() error! WinErr:%d, EpocErr:%d"), dwWinErr, epocErr);
        ASSERT(epocErr != KErrNone);

        return epocErr;
    }


    return KErrNone;
}
Ejemplo n.º 13
0
/**
    Open the device and do some initalisation work.
    
    @param  aParams device parameters
    @return Epoc error code, KErrNone if everything is OK
*/
TInt CWinImgFileDevice::Connect(const TMediaDeviceParams& aParams)
{
    __PRINT(_L("#-- CWinImgFileDevice::Connect()"));    
    
    if(!aParams.ipDevName)
    {
        __LOG(_L("#-- CWinImgFileDevice::Connect() device name is not set!"));    
        return KErrBadName;
    }
    __PRINTF(aParams.ipDevName);
    ASSERT(!HandleValid());

    //-- 1. try to locate an image file by given name.
    WIN32_FIND_DATAA wfd;
    iDevHandle = FindFirstFileA(aParams.ipDevName, &wfd);

    const TBool ImgFileAlreadyExists = HandleValid(iDevHandle);
    
    FindClose(iDevHandle);
    iDevHandle = NULL;
    
    //-- sector size we will use within image file
    const TUint32   sectorSizeToUse = (aParams.iDrvGeometry.iBytesPerSector == 0) ? KDefaultSectorSz : aParams.iDrvGeometry.iBytesPerSector; 
          TUint32   fileSzInSectorsToUse = 0;

    const TUint32   reqSizeSec = aParams.iDrvGeometry.iSizeInSectors; //-- required size in sectors
    const DWORD     dwAccessMode = (aParams.iReadOnly) ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE;  

    if(ImgFileAlreadyExists)
    {//-- if the image file already exists, try to open it and optionally adjust its size
        const TInt64    ImgFileSize = MAKE_TINT64(wfd.nFileSizeHigh, wfd.nFileSizeLow);
        const TUint32   ImgFileSectors = (TUint32)(ImgFileSize / sectorSizeToUse);
        const TBool     ImgFileIsRO = wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY;
        
        DWORD dwFileCreationMode = 0;
        TBool bNeedToAdjustFileSize = EFalse;

        if(reqSizeSec == 0 || reqSizeSec == ImgFileSectors)
        {//-- the required size is either not specified (auto) or the same as the existing file has.
         //-- we can just open this file
         dwFileCreationMode = OPEN_EXISTING;
         fileSzInSectorsToUse = ImgFileSectors;
        }
        else
        {//-- we will have to overwrite the image file
            if(ImgFileIsRO)
            {//-- we won't be able to overwrite existing file.
                __LOG(_L("#-- CWinImgFileDevice::Connect() unable to adjust image file size!"));    
                return KErrAccessDenied;
            }

         fileSzInSectorsToUse = reqSizeSec;
         dwFileCreationMode = CREATE_ALWAYS;
         bNeedToAdjustFileSize = ETrue;
        }

        iDevHandle = CreateFileA(aParams.ipDevName,
                                dwAccessMode, 
                                FILE_SHARE_READ,
                                (LPSECURITY_ATTRIBUTES)NULL,
                                dwFileCreationMode,
                                FILE_ATTRIBUTE_NORMAL,
                                NULL);

        if(!HandleValid(iDevHandle))
        {
            const DWORD winErr = GetLastError();
            __LOG1(_L("#-- CWinImgFileDevice::Connect() Error opening/creating file! WinErr:%d"), winErr);
            return MapWinError(winErr);
        }     

        //-- adjust file size if we need
        if(bNeedToAdjustFileSize)
        {
            const TInt64 newFileSize = (TInt64)reqSizeSec * sectorSizeToUse;
            ASSERT(newFileSize);

            LONG  newFSzHi = I64HIGH(newFileSize);
            DWORD dwRes = SetFilePointer(iDevHandle, I64LOW(newFileSize), &newFSzHi, FILE_BEGIN);
            if(dwRes == INVALID_SET_FILE_POINTER || !SetEndOfFile(iDevHandle))
            {
                const DWORD winErr = GetLastError();
                Disconnect();
                __LOG1(_L("#-- CWinImgFileDevice::Connect() unable to set file size! WinErr:%d"), winErr);
                return MapWinError(winErr);
            }
        }

    }
    else //if(ImgFileAlreadyExists)
    {//-- if the image file does not exist or its size differs from required. try to create it
       
        if(reqSizeSec == 0)
        {
            __LOG(_L("#-- CWinImgFileDevice::Connect() The image file doesn't exist ant its size isn't specified!"));    
            return KErrArgument;
        }
       
        fileSzInSectorsToUse = reqSizeSec;

        //-- create a new image file
        iDevHandle = CreateFileA(aParams.ipDevName,
                                GENERIC_READ | GENERIC_WRITE, 
                                FILE_SHARE_READ,
                                (LPSECURITY_ATTRIBUTES)NULL,
                                CREATE_ALWAYS,
                                FILE_ATTRIBUTE_NORMAL,
                                NULL);

        if(!HandleValid(iDevHandle))
        {
            const DWORD winErr = GetLastError();
            __LOG1(_L("#-- CWinImgFileDevice::Connect() can not create file! WinErr:%d"), winErr);
            return MapWinError(winErr);
        }     

        //-- set its size
        const TInt64 newFileSize = (TInt64)reqSizeSec * sectorSizeToUse;
        ASSERT(newFileSize);

        LONG  newFSzHi = I64HIGH(newFileSize);
        DWORD dwRes = SetFilePointer(iDevHandle, I64LOW(newFileSize), &newFSzHi, FILE_BEGIN);
        if(dwRes == INVALID_SET_FILE_POINTER || !SetEndOfFile(iDevHandle))
        {
            const DWORD winErr = GetLastError();
            Disconnect();
            __LOG1(_L("#-- CWinImgFileDevice::Connect() unable to set file size! WinErr:%d"), winErr);
            return MapWinError(winErr);
        }

        //-- if parametrs require a read-only file, reopen it in RO mode, it doesn't make a lot of sense though...
        if(aParams.iReadOnly)
        {
            CloseHandle(iDevHandle);
            iDevHandle = NULL;

            iDevHandle = CreateFileA(aParams.ipDevName,
                                GENERIC_READ , 
                                FILE_SHARE_READ,
                                (LPSECURITY_ATTRIBUTES)NULL,
                                OPEN_EXISTING,
                                FILE_ATTRIBUTE_NORMAL,
                                NULL);

            if(!HandleValid(iDevHandle))
            {
                const DWORD winErr = GetLastError();
                __LOG1(_L("#-- CWinImgFileDevice::Connect() Can't reopen a file in RO mode! WinErr:%d"), winErr);
                return MapWinError(winErr);
            }     
            
        }//if(aParams.iReadOnly)

    }//else if(ImgFileAlreadyExists)
    
    //-- here we must have the image file created/opened and with correct size
    ASSERT(HandleValid());
    ASSERT(sectorSizeToUse);

    if(fileSzInSectorsToUse < KMinMediaSizeInSectors)
    {
        __LOG1(_L("#-- CWinImgFileDevice::Connect() Image file is too small!  sectors:%d"), fileSzInSectorsToUse);
        Disconnect();
        return KErrGeneral;     
    }

    iDrvGeometry.iBytesPerSector = sectorSizeToUse;
    iDrvGeometry.iSizeInSectors  = fileSzInSectorsToUse;
    
    //-- map the image file into memory.
    ASSERT(!HandleValid(ihFileMapping));
    ASSERT(!ipImageFile);
    
    /*
    don't map image file, because it can be > 4G.
    ihFileMapping = CreateFileMapping(Handle(), NULL,
                                      aParams.iReadOnly ? PAGE_READONLY : PAGE_READWRITE,
                                      0, 0, NULL);
    if(HandleValid(ihFileMapping))
    {
    ipImageFile = (TUint8*)MapViewOfFile(ihFileMapping, 
                                         aParams.iReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE,
                                         0,0,0);
    }

    if(!ipImageFile)
    {
        __PRINT1(_L("#-- CWinImgFileDevice::Connect() Error mapping file! WinErr:%d"), GetLastError());
        Disconnect();
        return KErrGeneral;
    }
    */

    return KErrNone;
}
Ejemplo n.º 14
0
/**
    Write some data to the device.

    @param  aPos     media position in bytes
    @param  aLength  how many bytes to read
    @param  aDataDes data descriptor

    @return KErrNone on success, standard Epoc error code otherwise
*/
TInt CWinVolumeDevice::Write(TInt64 aPos, TInt aLength, const TDesC8& aDataDes)
{
    //__PRINT2(_L("#-- CWinVolumeDevice::Write, pos:%LU, len:%u"), aPos, aLength);

    ASSERT(HandleValid());
    
    if(aLength == 0 || aDataDes.Length() == 0)
        return KErrNone;

    if(aLength > aDataDes.Length())
    {
        ASSERT(0);
        return KErrArgument;
    }

    //-- check position on the volume
    const TInt64 maxPos = iDrvGeometry.TotalSizeInBytes();
    if(aPos < 0 || aPos > maxPos)
        return KErrArgument;

    const TInt64 lastPos = aPos+aLength;
    if(lastPos > maxPos)
        return KErrArgument;

    TUint32 dataLen = aLength;

    DWORD dwRes;
    DWORD dwBytes = 0;
    
    const TUint32 KSectorSize = BytesPerSector();
    const TUint8 *pData = aDataDes.Ptr();
    
    try
    {
        LONG    mediaPosHi = I64HIGH(aPos);
        const TUint32 mediaPosLo = I64LOW(aPos);
        const TUint32 startPosOffset = mediaPosLo & (KSectorSize-1);
        const TUint32 sectorPos = mediaPosLo-startPosOffset;

        //-- 1. position to the media with sector size granularity 
        dwRes = SetFilePointer(iDevHandle, sectorPos, &mediaPosHi, FILE_BEGIN);
        if(dwRes == INVALID_SET_FILE_POINTER)
        {    
            throw KDiskOpError;
        }

        if(startPosOffset || dataLen <= KSectorSize)
        {//-- need a read-modify-write here.
            //-- 1.1 read first sector
            if(!ReadFile(iDevHandle, ipScratchBuf, KSectorSize, &dwBytes, NULL))
                throw KDiskOpError;

            dwRes = SetFilePointer(iDevHandle, sectorPos, &mediaPosHi, FILE_BEGIN);
            if(dwRes == INVALID_SET_FILE_POINTER)
            {    
                throw KDiskOpError;
            }


            if(dwRes == INVALID_SET_FILE_POINTER)
                throw KDiskOpError;

            //-- 1.2 copy chunk of data there
            const TUint32 firstChunkLen = Min(dataLen, KSectorSize - startPosOffset);
            Mem::Copy(ipScratchBuf+startPosOffset, pData, firstChunkLen);
            
            //-- 1.3 write sector
            if(!WriteFile(iDevHandle, ipScratchBuf, KSectorSize, &dwBytes, NULL))
                throw KDiskOpError;


            dataLen-=firstChunkLen;
            pData+=firstChunkLen;

            if(dataLen == 0)
                return KErrNone; //-- no more data to write
        }

        //-- 2. write whole number of sectors to the media
        const TUint32 KBytesTail = dataLen & (KSectorSize-1); //-- number of bytes in the incomplete last sector
        TUint32 KMainChunkBytes = dataLen - KBytesTail;

        ASSERT((KMainChunkBytes % KSectorSize) == 0);

        //-- the pointer to the data shall be 2-bytes aligned, otherwise WriteFile will fail
        if(!((DWORD)pData & 0x01))
        {//-- data pointer aligned, ok
            if(!WriteFile(iDevHandle, pData, KMainChunkBytes, &dwBytes, NULL))
                throw KDiskOpError;
        
            pData+=KMainChunkBytes;
            dataLen-=KMainChunkBytes;

        }
        else
        {//-- data pointer is odd, we need to copy data to the aligned buffer
            TUint32 rem = KMainChunkBytes;
            while(rem)
            {
                const TUint32 nBytesToWrite = Min(KScratchBufSz, rem);
                Mem::Copy(ipScratchBuf, pData, nBytesToWrite);
            
                if(!WriteFile(iDevHandle, ipScratchBuf, nBytesToWrite, &dwBytes, NULL))
                    throw KDiskOpError;
        
                rem-=nBytesToWrite;
                pData+=nBytesToWrite;
                dataLen-=nBytesToWrite;
            }

        }


        //-- 3. write the rest of the bytes into the incomplete last sector
        if(KBytesTail)
        {
            //-- 3.1 read last sector
            if(!ReadFile(iDevHandle, ipScratchBuf, KSectorSize, &dwBytes, NULL))
                throw KDiskOpError;    

            LARGE_INTEGER liRelOffset;
            liRelOffset.QuadPart = -(LONG)KSectorSize;

            //dwRes = SetFilePointer(iDevHandle, -(LONG)KSectorSize, NULL, FILE_CURRENT);
            
            dwRes = SetFilePointer(iDevHandle, liRelOffset.LowPart, &liRelOffset.HighPart, FILE_CURRENT);
            if(dwRes == INVALID_SET_FILE_POINTER)
                throw KDiskOpError;

            //-- 1.2 copy chunk of data there
            Mem::Copy(ipScratchBuf, pData, KBytesTail);

            //-- 1.3 write sector
            if(!WriteFile(iDevHandle, ipScratchBuf, KSectorSize, &dwBytes, NULL))
                throw KDiskOpError;
            
        }


    }//try
    catch(TInt nErrId)
    {//-- some disk operation finished with the error
        (void)nErrId;
        ASSERT(nErrId == KDiskOpError);
        const DWORD dwWinErr = GetLastError();
        const TInt  epocErr = MapWinError(dwWinErr);
        
        __PRINT2(_L("#-- CWinVolumeDevice::Write() error! WinErr:%d, EpocErr:%d"), dwWinErr, epocErr);
        ASSERT(epocErr != KErrNone);
        return epocErr;
    }
 
    return KErrNone;
}
Ejemplo n.º 15
0
/**
    Read a portion of data from the device. 
    Note: at present it _APPENDS_ data to the aDataDes, so the caller must take care of setting its length

    @param  aPos     media position in bytes
    @param  aLength  how many bytes to read
    @param  aDataDes data descriptor

    @return KErrNone on success, standard Epoc error code otherwise

*/
TInt CWinVolumeDevice::Read(TInt64 aPos, TInt aLength, TDes8& aDataDes)
{
    //__PRINT2(_L("#-- CWinVolumeDevice::Read, pos:%LU, len:%u"), aPos, aLength);
 
    ASSERT(HandleValid());
    ASSERT(aLength <= aDataDes.MaxLength());

    //-- check position on the volume
    const TInt64 maxPos = iDrvGeometry.TotalSizeInBytes();
    if(aPos < 0 || aPos > maxPos)
        return KErrArgument;

    const TInt64 lastPos = aPos+aLength;

    if(lastPos > maxPos)
        return KErrArgument;
    //--


    TUint32 dataLen = aLength;

    if(dataLen == 0)
        return KErrNone;

    DWORD dwRes;
    DWORD dwBytesRead = 0;

    //aDataDes.SetLength(0);

    const TUint32 KSectorSize = BytesPerSector();
    
    try
    {
        LONG    mediaPosHi = I64HIGH(aPos);
        const TUint32 mediaPosLo = I64LOW(aPos);
        const TUint32 startPosOffset = mediaPosLo & (KSectorSize-1);
        
        //-- 1. position to the media with sector size granularity and read 1st sector
        dwRes = SetFilePointer(iDevHandle, mediaPosLo-startPosOffset, &mediaPosHi, FILE_BEGIN);
        if(dwRes == INVALID_SET_FILE_POINTER)
            throw KDiskOpError;

        //-- 1.1 read 1st sector
        if(!ReadFile(iDevHandle, ipScratchBuf, KSectorSize, &dwBytesRead, NULL))
            throw KDiskOpError;
        
        const TUint32 firstChunkLen = Min(dataLen, KSectorSize - startPosOffset);
        aDataDes.Append(ipScratchBuf+startPosOffset, firstChunkLen);
        dataLen-=firstChunkLen;

        if(dataLen == 0)
            return KErrNone; //-- no more data to read
    
        //-- 2. read whole number of sectors from the meida
        const TUint32 KBytesTail = dataLen & (KSectorSize-1); //-- number of bytes in the incomplete last sector
    
        ASSERT((KScratchBufSz % KSectorSize) == 0);

        TUint32 rem = dataLen - KBytesTail;
        while(rem)
        {
            const TUint32 bytesToRead = Min(KScratchBufSz, rem);
    
            if(!ReadFile(iDevHandle, ipScratchBuf, bytesToRead, &dwBytesRead, NULL))
                throw KDiskOpError;        
 
            aDataDes.Append(ipScratchBuf, bytesToRead);
            rem-=bytesToRead;
        }

        //-- 3. read the rest of the bytes in the incomplete last sector
        if(KBytesTail)
        {
            if(!ReadFile(iDevHandle, ipScratchBuf, KSectorSize, &dwBytesRead, NULL))
                throw KDiskOpError;    

            aDataDes.Append(ipScratchBuf, KBytesTail);
        }

    }//try
    catch(TInt nErrId)
    {//-- some disk operation finished with the error
        (void)nErrId;
        ASSERT(nErrId == KDiskOpError);
        const DWORD dwWinErr = GetLastError();
        const TInt  epocErr = MapWinError(dwWinErr);
        
        __PRINT2(_L("#-- CWinVolumeDevice::Read() error! WinErr:%d, EpocErr:%d"), dwWinErr, epocErr);
        ASSERT(epocErr != KErrNone);

        return epocErr;
    }

    return KErrNone;
}
Ejemplo n.º 16
0
/**
    Open the device and do some initalisation work.
    
    @param  aParams device parameters
    @return Epoc error code, KErrNone if everything is OK
*/
TInt CWinVolumeDevice::Connect(const TMediaDeviceParams& aParams)
{
    
    __PRINT(_L("#-- CWinVolumeDevice::Connect()"));    
    
    if(!aParams.ipDevName)
    {
        __LOG(_L("#-- CWinVolumeDevice::Connect() device name is not set!"));    
        return KErrBadName;
    }

    __PRINTF(aParams.ipDevName);
    
    ASSERT(!HandleValid() && ipScratchBuf);

    //-- open the device
    DWORD dwAccess = GENERIC_READ;
    
    if(!aParams.iReadOnly)
        dwAccess |= GENERIC_WRITE;  
    
    iDevHandle = CreateFileA(aParams.ipDevName,
                             dwAccess, 
                             FILE_SHARE_READ,
                             (LPSECURITY_ATTRIBUTES)NULL,
                             OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL,
                             NULL);

    if(!HandleValid())
    {
        __LOG1(_L("#-- CWinVolumeDevice::Connect() Error creating device handle! WinErr:%d"), GetLastError());
        return KErrGeneral;
    }     
    
    //-- find out device geometry
    iMediaType = Unknown;
    iDrvGeometry.iBytesPerSector = KDefaultSectorSz;

    DWORD junk; 

    //-- 1. try to query disk geometry, but it can produce wrong results for partitioned media
    BOOL bResult = DeviceIoControl(Handle(),
                                   IOCTL_DISK_GET_DRIVE_GEOMETRY,
                                   NULL, 0,
                                   ipScratchBuf, KScratchBufSz,
                                   &junk, (LPOVERLAPPED)NULL);

    if(bResult)
    {
        const DISK_GEOMETRY& dg = (const DISK_GEOMETRY&)*ipScratchBuf;
        
        iDrvGeometry.iBytesPerSector = dg.BytesPerSector;
        iMediaType = dg.MediaType;

        __PRINT3(_L("#-- dev geometry: Cyl:%d Heads:%d Sectors:%d"), dg.Cylinders.LowPart, dg.TracksPerCylinder, dg.SectorsPerTrack);    
        __PRINT2(_L("#-- dev geometry: MediaType:%d, bps:%d"), dg.MediaType, dg.BytesPerSector);    

    }
    else
    {
        iMediaType = Unknown;
        iDrvGeometry.iBytesPerSector = KDefaultSectorSz;

        __LOG1(_L("#-- CWinVolumeDevice::Connect() IOCTL_DISK_GET_DRIVE_GEOMETRY WinError:%d !"), GetLastError());
    }

    //-- 1.1 check "bytes per sector" value and how it corresponds to the request from parameters
    if(aParams.iDrvGeometry.iBytesPerSector == 0)
    {//-- do nothing, this parameter is not set in config file, use media's
    } 
    else if(aParams.iDrvGeometry.iBytesPerSector != iDrvGeometry.iBytesPerSector)
    {//-- we can't set "SectorSize" value for the physical media
        __LOG1(_L("#-- CWinVolumeDevice::Connect() can not use 'Sec. Size' value from config:%d !"), aParams.iDrvGeometry.iBytesPerSector);
        Disconnect();
        return KErrArgument;
    }


    ASSERT(IsPowerOf2(BytesPerSector()) && BytesPerSector() >= KDefaultSectorSz && BytesPerSector() < 4096);

    //-- find out partition information in order to determine volume size. 
    bResult = DeviceIoControl(Handle(),
                              IOCTL_DISK_GET_PARTITION_INFO,
                              NULL, 0,
                              ipScratchBuf, KScratchBufSz,
                              &junk, (LPOVERLAPPED)NULL);

    if(!bResult)
    {//-- this is a fatal error
        __LOG1(_L("#-- CWinVolumeDevice::Connect() IOCTL_DISK_GET_PARTITION_INFO WinError:%d !"), GetLastError());
        Disconnect();
        return KErrBadHandle;    
    }

    //-- get partition informaton
    const PARTITION_INFORMATION& pi = (const PARTITION_INFORMATION&)*ipScratchBuf;
    TInt64 volSz = MAKE_TINT64(pi.PartitionLength.HighPart, pi.PartitionLength.LowPart);
    iDrvGeometry.iSizeInSectors = (TUint32)(volSz / iDrvGeometry.iBytesPerSector);
            
    __LOG3(_L("#-- partition size, bytes:%LU (%uMB), sectors:%u"), volSz, (TUint32)(volSz>>20), iDrvGeometry.iSizeInSectors);
   
    //-- check if the media size is set in coonfig and if we can use this setting.
    if(aParams.iDrvGeometry.iSizeInSectors == 0)
    {//-- do nothing, the media size is not set in the ini file, use existing media parameters
    }
    else if(aParams.iDrvGeometry.iSizeInSectors > iDrvGeometry.iSizeInSectors)
    {//-- requested media size in ini file is bigger than physical media, error.
     //-- we can't increase physical media size
    __LOG2(_L("#-- CWinVolumeDevice::Connect() 'MediaSizeSectors' value from config:%d > than physical:%d !"), aParams.iDrvGeometry.iSizeInSectors, iDrvGeometry.iSizeInSectors);
    Disconnect();
    return KErrArgument;
    }
    else if(aParams.iDrvGeometry.iSizeInSectors < iDrvGeometry.iSizeInSectors)
    {//-- settings specify smaller media than physical one, adjust the size
    __PRINT1(_L("#-- reducing media size to %d sectors"), aParams.iDrvGeometry.iSizeInSectors);
    iDrvGeometry.iSizeInSectors = aParams.iDrvGeometry.iSizeInSectors;
    }


    ASSERT(iDrvGeometry.iSizeInSectors > KMinMediaSizeInSectors);
    return KErrNone;
}