[NTDLL_WINETEST]: Sync with Wine 1.5.19.
[reactos.git] / rostests / winetests / ntdll / om.c
index d052c35..1ff0f0c 100644 (file)
@@ -44,7 +44,9 @@ static NTSTATUS (WINAPI *pNtOpenDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_A
 static NTSTATUS (WINAPI *pNtCreateDirectoryObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
 static NTSTATUS (WINAPI *pNtOpenSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
 static NTSTATUS (WINAPI *pNtCreateSymbolicLinkObject)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PUNICODE_STRING);
+static NTSTATUS (WINAPI *pNtQuerySymbolicLinkObject)(HANDLE,PUNICODE_STRING,PULONG);
 static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG);
+static NTSTATUS (WINAPI *pNtReleaseSemaphore)(HANDLE handle, ULONG count, PULONG previous);
 
 
 static void test_case_sensitive (void)
@@ -141,7 +143,8 @@ static void test_namespace_pipe(void)
     status = pNtOpenFile(&h, GENERIC_READ, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN);
     ok(status == STATUS_OBJECT_PATH_NOT_FOUND ||
        status == STATUS_PIPE_NOT_AVAILABLE ||
-       status == STATUS_OBJECT_NAME_INVALID, /* vista */
+       status == STATUS_OBJECT_NAME_INVALID || /* vista */
+       status == STATUS_OBJECT_NAME_NOT_FOUND, /* win8 */
         "NtOpenFile should have failed with STATUS_OBJECT_PATH_NOT_FOUND got(%08x)\n", status);
 
     pRtlInitUnicodeString(&str, buffer4);
@@ -402,13 +405,48 @@ static void test_directory(void)
     is_nt4 = (status == STATUS_OBJECT_NAME_NOT_FOUND);  /* nt4 doesn't have Local\\ symlink */
     if (!is_nt4)
     {
+        WCHAR buffer[256];
+        ULONG len, full_len;
+
         ok(status == STATUS_SUCCESS, "Failed to open SymbolicLink(%08x)\n", status);
         pRtlFreeUnicodeString(&str);
         InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
         pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
         DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_TYPE_MISMATCH)
         pRtlFreeUnicodeString(&str);
-        pNtClose(h);
+
+        str.Buffer = buffer;
+        str.MaximumLength = sizeof(buffer);
+        len = 0xdeadbeef;
+        memset( buffer, 0xaa, sizeof(buffer) );
+        status = pNtQuerySymbolicLinkObject( dir, &str, &len );
+        ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08x\n", status );
+        if (status != STATUS_SUCCESS)
+            goto error;
+        full_len = str.Length + sizeof(WCHAR);
+        ok( len == full_len, "bad length %u/%u\n", len, full_len );
+        if (len == full_len)
+            ok( buffer[len / sizeof(WCHAR) - 1] == 0, "no terminating null\n" );
+
+        str.MaximumLength = str.Length;
+        len = 0xdeadbeef;
+        status = pNtQuerySymbolicLinkObject( dir, &str, &len );
+        ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08x\n", status );
+        ok( len == full_len, "bad length %u/%u\n", len, full_len );
+
+        str.MaximumLength = 0;
+        len = 0xdeadbeef;
+        status = pNtQuerySymbolicLinkObject( dir, &str, &len );
+        ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySymbolicLinkObject failed %08x\n", status );
+        ok( len == full_len, "bad length %u/%u\n", len, full_len );
+
+        str.MaximumLength = str.Length + sizeof(WCHAR);
+        len = 0xdeadbeef;
+        status = pNtQuerySymbolicLinkObject( dir, &str, &len );
+        ok( status == STATUS_SUCCESS, "NtQuerySymbolicLinkObject failed %08x\n", status );
+        ok( len == full_len, "bad length %u/%u\n", len, full_len );
+
+error:
         pNtClose(dir);
     }
 
@@ -622,10 +660,12 @@ static void test_query_object(void)
 {
     static const WCHAR name[] = {'\\','B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s',
                                  '\\','t','e','s','t','_','e','v','e','n','t'};
+    static const WCHAR type_event[] = {'E','v','e','n','t'};
+    static const WCHAR type_file[] = {'F','i','l','e'};
     HANDLE handle;
     char buffer[1024];
     NTSTATUS status;
-    ULONG len;
+    ULONG len, expected_len;
     UNICODE_STRING *str;
     char dir[MAX_PATH];
 
@@ -636,11 +676,21 @@ static void test_query_object(void)
     ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
     ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
 
+    len = 0;
+    status = pNtQueryObject( handle, ObjectTypeInformation, buffer, 0, &len );
+    todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
+    todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
+
     len = 0;
     status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
     ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
     ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
 
+    len = 0;
+    status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(OBJECT_TYPE_INFORMATION), &len );
+    todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
+    todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
+
     len = 0;
     status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(buffer), &len );
     ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
@@ -657,6 +707,21 @@ static void test_query_object(void)
     ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
     ok( len >= sizeof(UNICODE_STRING) + sizeof(name) + sizeof(WCHAR), "unexpected len %u\n", len );
 
+    len = 0;
+    memset( buffer, 0, sizeof(buffer) );
+    status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
+    todo_wine ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
+    todo_wine ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
+    str = (UNICODE_STRING *)buffer;
+    todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR), "unexpected len %u\n", len );
+    todo_wine ok( str->Buffer && !memcmp( str->Buffer, type_event, sizeof(type_file) ),
+                  "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
+
+    len -= sizeof(WCHAR);
+    status = pNtQueryObject( handle, ObjectTypeInformation, buffer, len, &len );
+    todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryObject failed %x\n", status );
+    todo_wine ok( len >= sizeof(OBJECT_TYPE_INFORMATION) + sizeof(type_event) + sizeof(WCHAR), "unexpected len %u\n", len );
+
     pNtClose( handle );
 
     handle = CreateEventA( NULL, FALSE, FALSE, NULL );
@@ -677,13 +742,62 @@ static void test_query_object(void)
     ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
     ok( len > sizeof(UNICODE_STRING), "unexpected len %u\n", len );
     str = (UNICODE_STRING *)buffer;
-    ok( sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR) == len ||
-        broken(sizeof(UNICODE_STRING) + str->Length == len), /* NT4 */
+    expected_len = sizeof(UNICODE_STRING) + str->Length + sizeof(WCHAR);
+    ok( len == expected_len || broken(len == expected_len - sizeof(WCHAR)), /* NT4 */
         "unexpected len %u\n", len );
     trace( "got %s len %u\n", wine_dbgstr_w(str->Buffer), len );
+
+    len = 0;
+    status = pNtQueryObject( handle, ObjectNameInformation, buffer, 0, &len );
+    ok( status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INSUFFICIENT_RESOURCES),
+        "NtQueryObject failed %x\n", status );
+    ok( len == expected_len || broken(!len || len == sizeof(UNICODE_STRING)),
+        "unexpected len %u\n", len );
+
+    len = 0;
+    status = pNtQueryObject( handle, ObjectNameInformation, buffer, sizeof(UNICODE_STRING), &len );
+    ok( status == STATUS_BUFFER_OVERFLOW || broken(status == STATUS_INSUFFICIENT_RESOURCES
+            || status == STATUS_INFO_LENGTH_MISMATCH),
+        "NtQueryObject failed %x\n", status );
+    ok( len == expected_len || broken(!len),
+        "unexpected len %u\n", len );
+
+    len = 0;
+    memset( buffer, 0, sizeof(buffer) );
+    status = pNtQueryObject( handle, ObjectTypeInformation, buffer, sizeof(buffer), &len );
+    todo_wine ok( status == STATUS_SUCCESS, "NtQueryObject failed %x\n", status );
+    todo_wine ok( len > sizeof(OBJECT_TYPE_INFORMATION), "unexpected len %u\n", len );
+    str = (UNICODE_STRING *)buffer;
+    expected_len = sizeof(OBJECT_TYPE_INFORMATION) + str->Length + sizeof(WCHAR);
+    todo_wine ok( len >= expected_len, "unexpected len %u\n", len );
+    todo_wine ok( str->Buffer && !memcmp( str->Buffer, type_file, sizeof(type_file) ),
+                  "wrong/bad type name %s (%p)\n", wine_dbgstr_w(str->Buffer), str->Buffer );
+
     pNtClose( handle );
 }
 
+static void test_type_mismatch(void)
+{
+    HANDLE h;
+    NTSTATUS res;
+    OBJECT_ATTRIBUTES attr;
+
+    attr.Length                   = sizeof(attr);
+    attr.RootDirectory            = 0;
+    attr.ObjectName               = NULL;
+    attr.Attributes               = 0;
+    attr.SecurityDescriptor       = NULL;
+    attr.SecurityQualityOfService = NULL;
+
+    res = pNtCreateEvent( &h, 0, &attr, 0, 0 );
+    ok(!res, "can't create event: %x\n", res);
+
+    res = pNtReleaseSemaphore( h, 30, NULL );
+    ok(res == STATUS_OBJECT_TYPE_MISMATCH, "expected 0xc0000024, got %x\n", res);
+
+    pNtClose( h );
+}
+
 START_TEST(om)
 {
     HMODULE hntdll = GetModuleHandleA("ntdll.dll");
@@ -710,10 +824,12 @@ START_TEST(om)
     pNtCreateDirectoryObject= (void *)GetProcAddress(hntdll, "NtCreateDirectoryObject");
     pNtOpenSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtOpenSymbolicLinkObject");
     pNtCreateSymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtCreateSymbolicLinkObject");
+    pNtQuerySymbolicLinkObject  = (void *)GetProcAddress(hntdll, "NtQuerySymbolicLinkObject");
     pNtCreateSemaphore      =  (void *)GetProcAddress(hntdll, "NtCreateSemaphore");
     pNtCreateTimer          =  (void *)GetProcAddress(hntdll, "NtCreateTimer");
     pNtCreateSection        =  (void *)GetProcAddress(hntdll, "NtCreateSection");
     pNtQueryObject          =  (void *)GetProcAddress(hntdll, "NtQueryObject");
+    pNtReleaseSemaphore     =  (void *)GetProcAddress(hntdll, "NtReleaseSemaphore");
 
     test_case_sensitive();
     test_namespace_pipe();
@@ -721,4 +837,5 @@ START_TEST(om)
     test_directory();
     test_symboliclink();
     test_query_object();
+    test_type_mismatch();
 }