PRB: Unexpected Result of SetFilePointer() with Devices (98892)



The information in this article applies to:

  • Microsoft Win32 Application Programming Interface (API), when used with:
    • the operating system: Microsoft Windows NT 3.1

This article was previously published under Q98892

SYMPTOMS

Open a floppy drive with the CreateFile() function:
    h = CreateFile( "\\\\.\\a:", ... );
				
Use the SetFilePointer() function to advance the file pointer that is associated with the file handle that is 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 functions, 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.

Modification Type:MajorLast Reviewed:2/24/2004
Keywords:kbAPI kbFileIO kbKernBase kbprb KB98892