Author: ion
Date: Tue Feb 21 21:38:08 2012
New Revision: 55795

URL: http://svn.reactos.org/svn/reactos?rev=55795&view=rev
Log:
[KERNEL32]: Lock/UnlockFile APIs should not allow console handles. Also remove 
superflous parameter check.
[KERNEL32]: Lock/UnlockFile APIs should handle STATUS_PENDING/ERROR_IO_PENDING 
situations instead of always assuming the Nt functions return synchronously.
[KERNEL32]: Other stylying changes + commenting/annotations.

Modified:
    trunk/reactos/dll/win32/kernel32/client/file/lock.c

Modified: trunk/reactos/dll/win32/kernel32/client/file/lock.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/file/lock.c?rev=55795&r1=55794&r2=55795&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/file/lock.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/file/lock.c [iso-8859-1] Tue Feb 21 
21:38:08 2012
@@ -9,14 +9,12 @@
  *                  Created 01/11/98
  */
 
-/* FIXME: the large integer manipulations in this file dont handle overflow  */
 
 /* INCLUDES ****************************************************************/
 
 #include <k32.h>
 #define NDEBUG
 #include <debug.h>
-DEBUG_CHANNEL(kernel32file);
 
 /* FUNCTIONS ****************************************************************/
 
@@ -25,165 +23,207 @@
  */
 BOOL
 WINAPI
-LockFile(HANDLE hFile,
-         DWORD dwFileOffsetLow,
-         DWORD dwFileOffsetHigh,
-         DWORD nNumberOfBytesToLockLow,
-         DWORD nNumberOfBytesToLockHigh)
-{
-    DWORD dwReserved;
+LockFile(IN HANDLE hFile,
+         IN DWORD dwFileOffsetLow,
+         IN DWORD dwFileOffsetHigh,
+         IN DWORD nNumberOfBytesToLockLow,
+         IN DWORD nNumberOfBytesToLockHigh)
+{
+    IO_STATUS_BLOCK IoStatusBlock;
+    NTSTATUS Status;
+    LARGE_INTEGER BytesToLock, Offset;
+
+    /* Is this a console handle? */
+    if (IsConsoleHandle(hFile))
+    {
+        /* Can't "lock" a console! */
+        BaseSetLastNTError(STATUS_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    /* Setup the parameters in NT style and call the native API */
+    BytesToLock.u.LowPart = nNumberOfBytesToLockLow;
+    BytesToLock.u.HighPart = nNumberOfBytesToLockHigh;
+    Offset.u.LowPart = dwFileOffsetLow;
+    Offset.u.HighPart = dwFileOffsetHigh;
+    Status = NtLockFile(hFile,
+                        NULL,
+                        NULL,
+                        NULL,
+                        &IoStatusBlock,
+                        &Offset,
+                        &BytesToLock,
+                        0,
+                        TRUE,
+                        TRUE);
+    if (Status == STATUS_PENDING)
+    {
+        /* Wait for completion if needed */
+        Status = NtWaitForSingleObject(hFile, FALSE, NULL);
+        if (NT_SUCCESS(Status)) Status = IoStatusBlock.Status;
+    }
+
+    /* Check if we failed */
+    if (!NT_SUCCESS(Status))
+    {
+        /* Convert the error code and fail */
+        BaseSetLastNTError(Status);
+        return FALSE;
+    }
+
+    /* Success! */
+    return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+LockFileEx(IN HANDLE hFile,
+           IN DWORD dwFlags,
+           IN DWORD dwReserved,
+           IN DWORD nNumberOfBytesToLockLow,
+           IN DWORD nNumberOfBytesToLockHigh,
+           IN LPOVERLAPPED lpOverlapped)
+{
+    LARGE_INTEGER BytesToLock, Offset;
+    NTSTATUS Status;
+
+    /* Is this a console handle? */
+    if (IsConsoleHandle(hFile))
+    {
+        /* Can't "lock" a console! */
+        BaseSetLastNTError(STATUS_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    /* This parameter should be zero */
+    if (dwReserved)
+    {
+        /* Fail since it isn't */
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    /* Set the initial status in the IO_STATUS_BLOCK to pending... */
+    lpOverlapped->Internal = STATUS_PENDING;
+
+    /* Convert the parameters to NT format and call the native API */
+    Offset.u.LowPart = lpOverlapped->Offset;
+    Offset.u.HighPart = lpOverlapped->OffsetHigh;
+    BytesToLock.u.LowPart = nNumberOfBytesToLockLow;
+    BytesToLock.u.HighPart = nNumberOfBytesToLockHigh;
+    Status = NtLockFile(hFile,
+                        lpOverlapped->hEvent,
+                        NULL,
+                        NULL,
+                        (PIO_STATUS_BLOCK)lpOverlapped,
+                        &Offset,
+                        &BytesToLock,
+                        0,
+                        dwFlags & LOCKFILE_FAIL_IMMEDIATELY ? TRUE : FALSE,
+                        dwFlags & LOCKFILE_EXCLUSIVE_LOCK ? TRUE: FALSE);
+    if ((NT_SUCCESS(Status)) && (Status != STATUS_PENDING))
+    {
+        /* Pending status is *not* allowed in the Ex API */
+        return TRUE;
+    }
+
+    /* Convert the error code and fail */
+    BaseSetLastNTError(Status);
+    return FALSE;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+UnlockFile(IN HANDLE hFile,
+           IN DWORD dwFileOffsetLow,
+           IN DWORD dwFileOffsetHigh,
+           IN DWORD nNumberOfBytesToUnlockLow,
+           IN DWORD nNumberOfBytesToUnlockHigh)
+{
     OVERLAPPED Overlapped;
-
+    NTSTATUS Status;
+    BOOLEAN Result;
+
+    /* Convert parameters to Ex format and call the new API */
     Overlapped.Offset = dwFileOffsetLow;
     Overlapped.OffsetHigh = dwFileOffsetHigh;
-    Overlapped.hEvent = NULL;
-    dwReserved = 0;
-
-    return LockFileEx(hFile,
-                      LOCKFILE_FAIL_IMMEDIATELY |
-                      LOCKFILE_EXCLUSIVE_LOCK,
-                      dwReserved,
-                      nNumberOfBytesToLockLow,
-                      nNumberOfBytesToLockHigh,
-                      &Overlapped ) ;
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-LockFileEx(HANDLE hFile,
-           DWORD dwFlags,
-           DWORD dwReserved,
-           DWORD nNumberOfBytesToLockLow,
-           DWORD nNumberOfBytesToLockHigh,
-           LPOVERLAPPED lpOverlapped /* required! */)
-{
-    LARGE_INTEGER BytesToLock;
-    BOOL LockImmediate;
-    BOOL LockExclusive;
-    NTSTATUS errCode;
-    LARGE_INTEGER Offset;
-
-    if(dwReserved != 0 || lpOverlapped==NULL)
-    {
+    Result = UnlockFileEx(hFile,
+                          0,
+                          nNumberOfBytesToUnlockLow,
+                          nNumberOfBytesToUnlockHigh,
+                          &Overlapped);
+    if (!(Result) && (GetLastError() == ERROR_IO_PENDING))
+    {
+        /* Ex fails during STATUS_PENDING, handle that here by waiting */
+        Status = NtWaitForSingleObject(hFile, FALSE, NULL);
+        if (NT_SUCCESS(Status)) Status = Overlapped.Internal;
+
+        /* Now if the status is successful, return */
+        if (!NT_SUCCESS(Status)) return TRUE;
+
+        /* Otherwise the asynchronous operation had a failure, so fail */
+        BaseSetLastNTError(Status);
+        return FALSE;
+    }
+
+    /* Success or error case -- Ex took care of the rest, just return */
+    return Result;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+UnlockFileEx(IN HANDLE hFile,
+             IN DWORD dwReserved,
+             IN DWORD nNumberOfBytesToUnLockLow,
+             IN DWORD nNumberOfBytesToUnLockHigh,
+             IN LPOVERLAPPED lpOverlapped)
+{
+    LARGE_INTEGER BytesToUnLock, StartAddress;
+    NTSTATUS Status;
+
+    /* Is this a console handle? */
+    if (IsConsoleHandle(hFile))
+    {
+        /* Can't "unlock" a console! */
+        BaseSetLastNTError(STATUS_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    /* This parameter should be zero */
+    if (dwReserved)
+    {
+        /* Fail since it isn't */
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
 
-    TRACE( "%p %x%08x %x%08x flags %x\n",
-        hFile, lpOverlapped->OffsetHigh, lpOverlapped->Offset, 
-        nNumberOfBytesToLockHigh, nNumberOfBytesToLockLow, dwFlags );
-
-    lpOverlapped->Internal = STATUS_PENDING;
-
-    Offset.u.LowPart = lpOverlapped->Offset;
-    Offset.u.HighPart = lpOverlapped->OffsetHigh;
-
-    if ( (dwFlags & LOCKFILE_FAIL_IMMEDIATELY) == LOCKFILE_FAIL_IMMEDIATELY )
-        LockImmediate = TRUE;
-    else
-        LockImmediate = FALSE;
-
-    if ( (dwFlags & LOCKFILE_EXCLUSIVE_LOCK) == LOCKFILE_EXCLUSIVE_LOCK )
-        LockExclusive = TRUE;
-    else
-        LockExclusive = FALSE;
-
-    BytesToLock.u.LowPart = nNumberOfBytesToLockLow;
-    BytesToLock.u.HighPart = nNumberOfBytesToLockHigh;
-
-    errCode = NtLockFile(hFile,
-                         lpOverlapped->hEvent,
-                         NULL,
-                         NULL,
-                         (PIO_STATUS_BLOCK)lpOverlapped,
-                         &Offset,
-                         &BytesToLock,
-                         0,
-                         (BOOLEAN)LockImmediate,
-                         (BOOLEAN)LockExclusive);
-
-    if ( !NT_SUCCESS(errCode) )
-    {
-        BaseSetLastNTError(errCode);
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-UnlockFile(HANDLE hFile,
-           DWORD dwFileOffsetLow,
-           DWORD dwFileOffsetHigh,
-           DWORD nNumberOfBytesToUnlockLow,
-           DWORD nNumberOfBytesToUnlockHigh)
-{
-    OVERLAPPED Overlapped;
-    DWORD dwReserved;
-    Overlapped.Offset = dwFileOffsetLow;
-    Overlapped.OffsetHigh = dwFileOffsetHigh;
-    dwReserved = 0;
-
-    return UnlockFileEx(hFile,
-                        dwReserved,
-                        nNumberOfBytesToUnlockLow,
-                        nNumberOfBytesToUnlockHigh,
-                        &Overlapped);
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-UnlockFileEx(HANDLE hFile,
-             DWORD dwReserved,
-             DWORD nNumberOfBytesToUnLockLow,
-             DWORD nNumberOfBytesToUnLockHigh,
-             LPOVERLAPPED lpOverlapped /* required! */)
-{
-    LARGE_INTEGER BytesToUnLock;
-    LARGE_INTEGER StartAddress;
-    NTSTATUS errCode;
-
-    if(dwReserved != 0 || lpOverlapped == NULL)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    TRACE( "%p %x%08x %x%08x\n",
-        hFile, lpOverlapped->OffsetHigh, lpOverlapped->Offset, 
-        nNumberOfBytesToUnLockHigh, nNumberOfBytesToUnLockLow);
-
+    /* Convert to NT format and call the native function */
     BytesToUnLock.u.LowPart = nNumberOfBytesToUnLockLow;
     BytesToUnLock.u.HighPart = nNumberOfBytesToUnLockHigh;
-
     StartAddress.u.LowPart = lpOverlapped->Offset;
     StartAddress.u.HighPart = lpOverlapped->OffsetHigh;
-
-    errCode = NtUnlockFile(hFile,
-                           (PIO_STATUS_BLOCK)lpOverlapped,
-                           &StartAddress,
-                           &BytesToUnLock,
-                           0);
-
-    if ( !NT_SUCCESS(errCode) )
-    {
-        BaseSetLastNTError(errCode);
-        return FALSE;
-    }
-
+    Status = NtUnlockFile(hFile,
+                          (PIO_STATUS_BLOCK)lpOverlapped,
+                          &StartAddress,
+                          &BytesToUnLock,
+                          0);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Convert the error and fail */
+        BaseSetLastNTError(Status);
+        return FALSE;
+    }
+
+    /* All good */
     return TRUE;
 }
 


Reply via email to