PRB: Unexpected Result of SetFilePointer() with Devices

Last reviewed: November 2, 1995
Article ID: Q98892
The information in this article applies to:
  • Microsoft Win32 Application Programming Interface (API) included with:

        - Microsoft Windows NT version 3.1
    

SYMPTOMS

Open a floppy drive with CreateFile():

   h = CreateFile( "\\\\.\\a:", ... );

Use SetFilePointer() to advance the file pointer associated with the file handle returned from CreateFile():

   SetFilePointer( h,    // file handle
                   5,    // distance (in bytes) to move file pointer
                NULL,    // optional high 32-bits of distance
          FILE_BEGIN     // specifies the starting point
   );

If the offset is not a multiple of the sector size of the floppy drive, the function will return success; however, the pointer will not be exactly where requested. The pointer value is rounded down to the beginning of the sector that the pointer value is in.

CAUSE

The behavior of this application programming interface (API) is by design for the following reasons:

  • The I/O system is unaware of device particulars such as sector size; any offset is valid.
  • SetFilePointer() is very frequently used. Because speed is an important goal for Windows NT, time is not spent on querying device particulars and detecting such errors.
  • The logic to handle this situation is built into the file system, which actually performs the rounding, and therefore there was no need to put this into the code for SetFilePointer().

RESOLUTION

When using SetFilePointer() with a handle that represents a floppy drive, the offset must be a multiple of the sector size for the floppy drive in order for the function to perform as expected.

MORE INFORMATION

Think of a file pointer as merely a stored value, which is where the next read or write will take place. In fact, it is possible to override this value on either the read or write itself, using certain APIs, by supplying a different location. The new pointer location is remembered after the operation. Therefore, the operation of "setting a file pointer" merely means to go store a large integer in a cell in the system's data structures, for possible use in the next file operation. In the case of a handle to a device, the file pointer must be on a sector boundary.

In a similar way, ReadFile() only reads amounts that are multiples of the sector size if it is passed a handle that represents a floppy drive.


Additional reference words: 3.10 ntddkstorage
KBCategory: kbprg kbprb
KBSubcategory: BseFileio


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: November 2, 1995
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.