🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #11219

Re: CreateFile and ReadFile

#11219
From: Andrue Cope
Date: Fri, 20 Feb 2004 09:41
78 lines
4320 bytes
On Fri, 20 Feb 2004 02:09:41 +0800, ray wrote:

> but i can use C# to do it

C# is a different language and its FileStream() call must be doing what I
said. Certainly /something/ has to do what I said because the hard drive
can only read block by block. Whether a function to read byte-by-byte
exists for C++ Builder I don't personally know.

Actually the API might support this functionality, you might just be going
about it the wrong way. I don't really know since I've never tried (see
below). Even if it does..well see below :)

I develop software for data recovery and computer forensics. Working with
block devices is something I do day in day out. What I can tell you is that
only wanting to read a couple of bytes from a sector is a very unusual
requirement. It is also potentially very inneficient both in storage (the
drive works in blocks so if you only use one byte you waste 511) and in
performance (at some point 512 bytes is going to be transferred to/from the
drive and subsystems).

I'm also concerned about your example code. It makes 100 calls to new[] and
has not one call to delete. This might be okay under C# (but you get hit
with the performance overhead of the allocation on every read) but not at
all good under C++.

Oh and you make 100 calls to fs.Read(). This is not good. Even with file
I/O you'd not want to be doing that. Each call has a lot of overhead.

The way I would code that is:

void getBytes( BYTE * Buffer,
               QWORD  ByteSeekPosn,
               DWORD  ByteTotal )
{
  std::auto_ptr<BYTE> blockBuffer( new BYTE[ 512 ] ); // See note (1) below
  
  do
  {
    if( Read_Block_FromDevice( ByteSeekPosn/512,
                               blockBuffer.get() ) )
    {
      WORD bufferOffset=ByteSeekPosn%512;
    
      WORD bytes2Transfer=std::min( 512-bufferOffset,
                                    ByteTotal );
                                    
      memcpy( Buffer, blockBuffer.get()+bufferOffset, bytes2Transfer );
      
      ByteSeekPosn+=bytes2Transfer;
      ByteTotal-=bytes2Transfer;
      Buffer+=bytes2Transfer;
    }
  }while( ByteTotal );
}

(1)Actually I wouldn't do this here. It can take time to allocate memory. A
better idea would be to make this a class method and have the ctor allocate
the buffer.
(2)I'd also not hard code 512. It's only an industry standard that keeps
most hard drive buffers at 512 bytes. This could change and I think is
likely to soon since AFAIK SCSI has no other way to go beyond 2TB. Some
machines (AS/400) have really odd block sizes. 520 bytes is one example.
Optical media generally use 2kB sectors.
(3)Note use of std::auto_ptr<> to remove the need for a delete[].
(4)Actually our block I/O class calculates how many contiguous blocks it
can read and so reduces the number of calls to Read_Block_FromDevice() to
its minimum but I'll leave that as an exercise for you :)

Lastly:Why are you trying to do this? Reading/writing direct to/from a disk
is dangerous. If you can tell me what your are trying to do I might be able
to come up with a better idea. I've been doing this work for over 11 years
now (written drivers for well over a dozen file systems) and I'm probably a
World expert in file systems and disk storage. Ouch. That's a frightening
thought :)
-- 
Andrue Cope
[Bicester UK]
Technical Details
Message-ID: <7aeaoh9a6g9g.15gt18x45vjm.dlg@40tude.net>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!news.maxwell.syr.edu!nntp-relay.ihug.net!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail
References: <4034e792$1@newsgroups.borland.com> <ih67f05a4bzf.1w8m6acs1eu0e.dlg@40tude.net> <4034fbe4$1@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 10cc67,a2e178d9fedcf99e
X-Google-Attributes: gid10cc67,public
X-Google-ArrivalTime: 2004-02-20 01:47:46 PST
From: Andrue Cope <no.spam@spammy.com>
Subject: Re: CreateFile and ReadFile
Newsgroups: borland.public.cppbuilder.nativeapi
User-Agent: 40tude_Dialog/2.0.10.1
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
References: <4034e792$1@newsgroups.borland.com> <ih67f05a4bzf.1w8m6acs1eu0e.dlg@40tude.net> <4034fbe4$1@newsgroups.borland.com>
Date: Fri, 20 Feb 2004 09:41:10 +0000
Message-ID: <7aeaoh9a6g9g.15gt18x45vjm.dlg@40tude.net>
NNTP-Posting-Host: 217.207.223.34
X-Trace: newsgroups.borland.com 1077270090 217.207.223.34 (20 Feb 2004 01:41:30 -0800)
Lines: 78
Path: arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!news.maxwell.syr.edu!nntp-relay.ihug.net!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail