server: Allow to specify the class name instead of the atom to find a window.
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 023115e..72f3cfc 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -211,7 +211,7 @@
  * Build an array of the children of a given window. The array must be
  * freed with HeapFree. Returns NULL when no windows are found.
  */
-static HWND *list_window_children( HWND hwnd, ATOM atom, DWORD tid )
+static HWND *list_window_children( HWND hwnd, LPCWSTR class, DWORD tid )
 {
     HWND *list;
     int size = 32;
@@ -225,8 +225,9 @@
         SERVER_START_REQ( get_window_children )
         {
             req->parent = hwnd;
-            req->atom = atom;
             req->tid = tid;
+            if (!(req->atom = get_int_atom_value( class )) && class)
+                wine_server_add_data( req, class, strlenW(class)*sizeof(WCHAR) );
             wine_server_set_reply( req, list, (size-1) * sizeof(HWND) );
             if (!wine_server_call( req )) count = reply->count;
         }
@@ -1398,11 +1399,9 @@
 
 
 /***********************************************************************
- *           WIN_FindWindow
- *
- * Implementation of FindWindow() and FindWindowEx().
+ *		FindWindowExW (USER32.@)
  */
-static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className, LPCWSTR title )
+HWND WINAPI FindWindowExW( HWND parent, HWND child, LPCWSTR className, LPCWSTR title )
 {
     HWND *list = NULL;
     HWND retvalue = 0;
@@ -1458,58 +1457,35 @@
 /***********************************************************************
  *		FindWindowExA (USER32.@)
  */
-HWND WINAPI FindWindowExA( HWND parent, HWND child,
-                               LPCSTR className, LPCSTR title )
+HWND WINAPI FindWindowExA( HWND parent, HWND child, LPCSTR className, LPCSTR title )
 {
-    ATOM atom = 0;
-    LPWSTR buffer;
-    HWND hwnd;
-    INT len;
+    LPWSTR titleW = NULL;
+    HWND hwnd = 0;
 
-    if (className)
+    if (title)
     {
-        /* If the atom doesn't exist, then no class */
-        /* with this name exists either. */
-        if (!(atom = GlobalFindAtomA( className )))
-        {
-            SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
-            return 0;
-        }
+        DWORD len = MultiByteToWideChar( CP_ACP, 0, title, -1, NULL, 0 );
+        if (!(titleW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return 0;
+        MultiByteToWideChar( CP_ACP, 0, title, -1, titleW, len );
     }
-    if (!title) return WIN_FindWindow( parent, child, atom, NULL );
 
-    len = MultiByteToWideChar( CP_ACP, 0, title, -1, NULL, 0 );
-    if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return 0;
-    MultiByteToWideChar( CP_ACP, 0, title, -1, buffer, len );
-    hwnd = WIN_FindWindow( parent, child, atom, buffer );
-    HeapFree( GetProcessHeap(), 0, buffer );
+    if (!IS_INTRESOURCE(className))
+    {
+        WCHAR classW[256];
+        if (MultiByteToWideChar( CP_ACP, 0, className, -1, classW, sizeof(classW)/sizeof(WCHAR) ))
+            hwnd = FindWindowExW( parent, child, classW, titleW );
+    }
+    else
+    {
+        hwnd = FindWindowExW( parent, child, (LPCWSTR)className, titleW );
+    }
+
+    HeapFree( GetProcessHeap(), 0, titleW );
     return hwnd;
 }
 
 
 /***********************************************************************
- *		FindWindowExW (USER32.@)
- */
-HWND WINAPI FindWindowExW( HWND parent, HWND child,
-                               LPCWSTR className, LPCWSTR title )
-{
-    ATOM atom = 0;
-
-    if (className)
-    {
-        /* If the atom doesn't exist, then no class */
-        /* with this name exists either. */
-        if (!(atom = GlobalFindAtomW( className )))
-        {
-            SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
-            return 0;
-        }
-    }
-    return WIN_FindWindow( parent, child, atom, title );
-}
-
-
-/***********************************************************************
  *		FindWindowW (USER32.@)
  */
 HWND WINAPI FindWindowW( LPCWSTR className, LPCWSTR title )
@@ -2774,7 +2750,7 @@
  */
 HWND *WIN_ListChildren( HWND hwnd )
 {
-    return list_window_children( hwnd, 0, 0 );
+    return list_window_children( hwnd, NULL, 0 );
 }
 
 
@@ -2818,7 +2794,7 @@
 
     USER_CheckNotLock();
 
-    if (!(list = list_window_children( GetDesktopWindow(), 0, id ))) return TRUE;
+    if (!(list = list_window_children( GetDesktopWindow(), NULL, id ))) return TRUE;
 
     /* Now call the callback function for every window */
 
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 1643070..913f2a1 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -2888,6 +2888,7 @@
     user_handle_t  parent;
     atom_t         atom;
     thread_id_t    tid;
+    /* VARARG(class,unicode_str); */
 };
 struct get_window_children_reply
 {
@@ -4884,6 +4885,6 @@
     struct set_completion_info_reply set_completion_info_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 327
+#define SERVER_PROTOCOL_VERSION 328
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index 5cb951d..90e943b 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2131,6 +2131,7 @@
     user_handle_t  parent;        /* parent window */
     atom_t         atom;          /* class atom for the listed children */
     thread_id_t    tid;           /* thread owning the listed children */
+    VARARG(class,unicode_str);    /* class name */
 @REPLY
     int            count;         /* total count of children */
     VARARG(children,user_handles); /* children handles */
diff --git a/server/trace.c b/server/trace.c
index 2460cde..7275e65 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2635,7 +2635,9 @@
 {
     fprintf( stderr, " parent=%p,", req->parent );
     fprintf( stderr, " atom=%04x,", req->atom );
-    fprintf( stderr, " tid=%04x", req->tid );
+    fprintf( stderr, " tid=%04x,", req->tid );
+    fprintf( stderr, " class=" );
+    dump_varargs_unicode_str( cur_size );
 }
 
 static void dump_get_window_children_reply( const struct get_window_children_reply *req )
diff --git a/server/window.c b/server/window.c
index 3e8219b..8cf8001 100644
--- a/server/window.c
+++ b/server/window.c
@@ -1757,12 +1757,19 @@
     int total = 0;
     user_handle_t *data;
     data_size_t len;
+    atom_t atom = req->atom;
+
+    if (get_req_data_size())
+    {
+        atom = find_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
+        if (!atom) return;
+    }
 
     if (parent)
     {
         LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry )
         {
-            if (req->atom && get_class_atom(ptr->class) != req->atom) continue;
+            if (atom && get_class_atom(ptr->class) != atom) continue;
             if (req->tid && get_thread_id(ptr->thread) != req->tid) continue;
             total++;
         }
@@ -1774,7 +1781,7 @@
         LIST_FOR_EACH_ENTRY( ptr, &parent->children, struct window, entry )
         {
             if (len < sizeof(*data)) break;
-            if (req->atom && get_class_atom(ptr->class) != req->atom) continue;
+            if (atom && get_class_atom(ptr->class) != atom) continue;
             if (req->tid && get_thread_id(ptr->thread) != req->tid) continue;
             *data++ = ptr->handle;
             len -= sizeof(*data);