From 92c0e065d3247f3a63bbf0f22d5621955779d60f Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 6 Jun 2015 01:21:05 +0200
Subject: ntdll: Pre-cache file descriptors after opening a file.

---
 dlls/kernel32/tests/pipe.c |  4 ++--
 dlls/ntdll/file.c          | 12 +++++++++++-
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c
index 9986337..fddb459 100644
--- a/dlls/kernel32/tests/pipe.c
+++ b/dlls/kernel32/tests/pipe.c
@@ -1944,12 +1944,12 @@ static void test_CloseHandle(void)
     SetLastError(0xdeadbeef);
     ret = ReadFile(hfile, buffer, 0, &numbytes, NULL);
     ok(!ret, "ReadFile unexpectedly succeeded\n");
-    todo_wine ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
+    ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL);
     ok(!ret, "WriteFile unexpectedly succeeded\n");
-    todo_wine ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError());
+    ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError());
 
     CloseHandle(hfile);
 
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 3bb2905..15500b9 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -209,7 +209,17 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
             *handle = wine_server_ptr_handle( reply->handle );
         }
         SERVER_END_REQ;
-        if (io->u.Status == STATUS_SUCCESS) io->Information = FILE_OPENED;
+        if (io->u.Status == STATUS_SUCCESS)
+        {
+            /* pre-cache the file descriptor. this is necessary because the fd cannot be
+             * acquired anymore after one end of the pipe has been closed - see kernel32/pipe
+             * tests. */
+            int unix_fd, needs_close;
+            int ret = server_get_unix_fd( *handle, 0, &unix_fd, &needs_close, NULL, NULL );
+            if (!ret && needs_close) close( unix_fd );
+            io->Information = FILE_OPENED;
+        }
+
         return io->u.Status;
     }
 
-- 
2.6.2

