Author: weiden
Date: Thu Jul 12 14:56:00 2007
New Revision: 27612
URL:
http://svn.reactos.org/svn/reactos?rev=27612&view=rev
Log:
Fix the semantics of SetFilePointer as described by Raymond Chen on
http://blogs.msdn.com/oldnewthing/archive/2007/07/11/3805135.aspx
Modified:
trunk/reactos/dll/win32/kernel32/file/file.c
Modified: trunk/reactos/dll/win32/kernel32/file/file.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/file/fi…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/file/file.c (original)
+++ trunk/reactos/dll/win32/kernel32/file/file.c Thu Jul 12 14:56:00 2007
@@ -394,18 +394,14 @@
return -1;
}
- Distance.u.LowPart = lDistanceToMove;
if (lpDistanceToMoveHigh)
{
Distance.u.HighPart = *lpDistanceToMoveHigh;
- }
- else if (lDistanceToMove >= 0)
- {
- Distance.u.HighPart = 0;
+ Distance.u.LowPart = lDistanceToMove;
}
else
{
- Distance.u.HighPart = -1;
+ Distance.QuadPart = lDistanceToMove;
}
switch(dwMoveMethod)
@@ -441,6 +437,14 @@
return -1;
}
+ if (lpDistanceToMoveHigh == NULL && FilePosition.CurrentByteOffset.HighPart !=
0)
+ {
+ /* If we're moving the pointer outside of the 32 bit boundaries but
+ the application only passed a 32 bit value we need to bail out! */
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return -1;
+ }
+
errCode = NtSetInformationFile(hFile,
&IoStatusBlock,
&FilePosition,
@@ -448,14 +452,28 @@
FilePositionInformation);
if (!NT_SUCCESS(errCode))
{
- SetLastErrorByStatus(errCode);
- return -1;
+ if (lpDistanceToMoveHigh != NULL)
+ *lpDistanceToMoveHigh = -1;
+
+ SetLastErrorByStatus(errCode);
+ return -1;
}
if (lpDistanceToMoveHigh != NULL)
{
*lpDistanceToMoveHigh = FilePosition.CurrentByteOffset.u.HighPart;
}
+
+ if (FilePosition.CurrentByteOffset.u.LowPart == -1)
+ {
+ /* The value of -1 is valid here, especially when the new
+ file position is greater than 4 GB. Since NtSetInformationFile
+ succeeded we never set an error code and we explicitly need
+ to clear a previously set error code in this case, which
+ an application will check if INVALID_SET_FILE_POINTER is returned! */
+ SetLastError(ERROR_SUCCESS);
+ }
+
return FilePosition.CurrentByteOffset.u.LowPart;
}