From d2ae0665b09bddf81c692d95b9ac0025f0ec1e45 Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Fri, 29 Nov 2024 19:45:58 +0100
Subject: [PATCH] server: Use the correct handle allocation pattern for all
 object types.

---
 server/completion.c |  6 +++++-
 server/directory.c  |  6 +++++-
 server/registry.c   |  6 +++++-
 server/symlink.c    | 11 ++++++++---
 server/timer.c      |  6 +++++-
 5 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/server/completion.c b/server/completion.c
index f4fad9dbeca..99680ae0680 100644
--- a/server/completion.c
+++ b/server/completion.c
@@ -323,7 +323,11 @@ DECL_HANDLER(create_completion)
 
     if ((completion = create_completion( root, &name, objattr->attributes, req->concurrent, sd )))
     {
-        reply->handle = alloc_handle( current->process, completion, req->access, objattr->attributes );
+        if (get_error() == STATUS_OBJECT_NAME_EXISTS)
+            reply->handle = alloc_handle( current->process, completion, req->access, objattr->attributes );
+        else
+            reply->handle = alloc_handle_no_access_check( current->process, completion,
+                                                          req->access, objattr->attributes );
         release_object( completion );
     }
 
diff --git a/server/directory.c b/server/directory.c
index b37ec969a9e..fd689c561bc 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -525,7 +525,11 @@ DECL_HANDLER(create_directory)
 
     if ((dir = create_directory( root, &name, objattr->attributes, HASH_SIZE, sd )))
     {
-        reply->handle = alloc_handle( current->process, dir, req->access, objattr->attributes );
+        if (get_error() == STATUS_OBJECT_NAME_EXISTS)
+            reply->handle = alloc_handle( current->process, dir, req->access, objattr->attributes );
+        else
+            reply->handle = alloc_handle_no_access_check( current->process, dir,
+                                                          req->access, objattr->attributes );
         release_object( dir );
     }
 
diff --git a/server/registry.c b/server/registry.c
index cc9a33fff1d..fefbcd6efdc 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -2178,7 +2178,11 @@ DECL_HANDLER(create_key)
             key->classlen = (key->classlen / sizeof(WCHAR)) * sizeof(WCHAR);
             if (!(key->class = memdup( class, key->classlen ))) key->classlen = 0;
         }
-        reply->hkey = alloc_handle( current->process, key, access, objattr->attributes );
+        if (get_error() == STATUS_OBJECT_NAME_EXISTS)
+            reply->hkey = alloc_handle( current->process, key, access, objattr->attributes );
+        else
+            reply->hkey = alloc_handle_no_access_check( current->process, key,
+                                                        access, objattr->attributes );
         release_object( key );
     }
     if (parent) release_object( parent );
diff --git a/server/symlink.c b/server/symlink.c
index dd28efd3a75..74b60162c01 100644
--- a/server/symlink.c
+++ b/server/symlink.c
@@ -165,8 +165,6 @@ struct object *create_symlink( struct object *root, const struct unicode_str *na
             return NULL;
         }
     }
-    else clear_error();
-
     return &symlink->obj;
 }
 
@@ -212,7 +210,14 @@ DECL_HANDLER(create_symlink)
 
     if ((symlink = create_symlink( root, &name, objattr->attributes, &target, sd )))
     {
-        reply->handle = alloc_handle( current->process, symlink, req->access, objattr->attributes );
+        if (get_error() == STATUS_OBJECT_NAME_EXISTS)
+        {
+            clear_error();
+            reply->handle = alloc_handle( current->process, symlink, req->access, objattr->attributes );
+        }
+        else
+            reply->handle = alloc_handle_no_access_check( current->process, symlink,
+                                                          req->access, objattr->attributes );
         release_object( symlink );
     }
 
diff --git a/server/timer.c b/server/timer.c
index 5dfd9c62399..b0b6ec81535 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -237,7 +237,11 @@ DECL_HANDLER(create_timer)
 
     if ((timer = create_timer( root, &name, objattr->attributes, req->manual, sd )))
     {
-        reply->handle = alloc_handle( current->process, timer, req->access, objattr->attributes );
+        if (get_error() == STATUS_OBJECT_NAME_EXISTS)
+            reply->handle = alloc_handle( current->process, timer, req->access, objattr->attributes );
+        else
+            reply->handle = alloc_handle_no_access_check( current->process, timer,
+                                                          req->access, objattr->attributes );
         release_object( timer );
     }
 
-- 
GitLab