diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index b612a0844a4..62659fc8cb4 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -1408,9 +1408,15 @@ static void test_symboliclink(void) pNtClose(link); RtlInitUnicodeString(&str, L"\\"); + attr.Attributes = OBJ_OPENIF; status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr, &target); - todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH, - "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status); + ok(status == STATUS_OBJECT_TYPE_MISMATCH, + "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status); + attr.Attributes = 0; + status = pNtCreateSymbolicLinkObject(&h, SYMBOLIC_LINK_QUERY, &attr, &target); + todo_wine + ok(status == STATUS_OBJECT_TYPE_MISMATCH, + "NtCreateSymbolicLinkObject should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status); RtlInitUnicodeString( &target, L"->Somewhere"); @@ -1480,6 +1486,16 @@ static void test_symboliclink(void) ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status); pNtClose(h); + attr.Attributes = OBJ_OPENIF; + status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target ); + ok(status == STATUS_SUCCESS || broken( status == STATUS_OBJECT_NAME_EXISTS ), /* <= win10 1507 */ + "Got unexpected status %#lx.\n", status); + pNtClose(h); + attr.Attributes = 0; + status = pNtCreateSymbolicLinkObject( &h, SYMBOLIC_LINK_QUERY, &attr, &target ); + ok(status == STATUS_OBJECT_NAME_COLLISION, "Got unexpected status %#lx.\n", status); + pNtClose(h); + InitializeObjectAttributes(&attr, &str, 0, 0, NULL); RtlInitUnicodeString( &str, L"\\BaseNamedObjects\\om.c-test\\" ); status = NtCreateFile(&h, GENERIC_READ | SYNCHRONIZE, &attr, &iosb, NULL, 0, diff --git a/server/symlink.c b/server/symlink.c index 27d48e2f994..dd28efd3a75 100644 --- a/server/symlink.c +++ b/server/symlink.c @@ -155,13 +155,18 @@ struct object *create_symlink( struct object *root, const struct unicode_str *na set_error( STATUS_INVALID_PARAMETER ); return NULL; } - if (!(symlink = create_named_object( root, &symlink_ops, name, attr, sd ))) return NULL; - if (get_error() != STATUS_OBJECT_NAME_EXISTS && !(symlink->target = memdup( target->str, target->len ))) + if (!(symlink = create_named_object( root, &symlink_ops, name, attr | OBJ_OPENLINK, sd ))) return NULL; + if (get_error() != STATUS_OBJECT_NAME_EXISTS) { - release_object( symlink ); - return NULL; + symlink->len = target->len; + if (!(symlink->target = memdup( target->str, target->len ))) + { + release_object( symlink ); + return NULL; + } } - symlink->len = target->len; + else clear_error(); + return &symlink->obj; }