server: Allow to specify the class name instead of the atom to create a window.
diff --git a/dlls/user32/class.c b/dlls/user32/class.c
index 9a1dd2f..2119de9 100644
--- a/dlls/user32/class.c
+++ b/dlls/user32/class.c
@@ -101,7 +101,7 @@
 /***********************************************************************
  *           get_int_atom_value
  */
-static ATOM get_int_atom_value( LPCWSTR name )
+ATOM get_int_atom_value( LPCWSTR name )
 {
     UINT ret = 0;
 
diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h
index d52c914..c5c5e35 100644
--- a/dlls/user32/controls.h
+++ b/dlls/user32/controls.h
@@ -48,6 +48,7 @@
 /* Class functions */
 struct tagCLASS;  /* opaque structure */
 struct tagWND;
+extern ATOM get_int_atom_value( LPCWSTR name );
 extern void CLASS_RegisterBuiltinClasses(void);
 extern void CLASS_AddWindow( struct tagCLASS *class, struct tagWND *win, BOOL unicode );
 extern void CLASS_FreeModuleClasses( HMODULE16 hModule );
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index f6f0512..023115e 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -95,7 +95,7 @@
  *
  * Create a window handle with the server.
  */
-static WND *create_window_handle( HWND parent, HWND owner, ATOM atom,
+static WND *create_window_handle( HWND parent, HWND owner, LPCWSTR name,
                                   HINSTANCE instance, BOOL unicode )
 {
     WORD index;
@@ -113,8 +113,9 @@
     {
         req->parent   = parent;
         req->owner    = owner;
-        req->atom     = atom;
         req->instance = instance;
+        if (!(req->atom = get_int_atom_value( name )) && name)
+            wine_server_add_data( req, name, strlenW(name)*sizeof(WCHAR) );
         if (!wine_server_call_err( req ))
         {
             handle = reply->handle;
@@ -857,7 +858,7 @@
  *
  * Implementation of CreateWindowEx().
  */
-static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, UINT flags )
+static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, LPCWSTR className, UINT flags )
 {
     INT sw = SW_SHOW;
     WND *wndPtr;
@@ -867,7 +868,7 @@
 
     TRACE("%s %s ex=%08x style=%08x %d,%d %dx%d parent=%p menu=%p inst=%p params=%p\n",
           unicode ? debugstr_w((LPCWSTR)cs->lpszName) : debugstr_a(cs->lpszName),
-          unicode ? debugstr_w((LPCWSTR)cs->lpszClass) : debugstr_a(cs->lpszClass),
+          debugstr_w(className),
           cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
           cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams );
     if(TRACE_ON(win)) dump_window_styles( cs->style, cs->dwExStyle );
@@ -968,7 +969,7 @@
             SetLastError(ERROR_TLW_WITH_WSCHILD);
             return 0;  /* WS_CHILD needs a parent, but WS_POPUP doesn't */
         }
-        if (classAtom != LOWORD(DESKTOP_CLASS_ATOM))  /* are we creating the desktop itself? */
+        if (className != (LPCWSTR)DESKTOP_CLASS_ATOM)  /* are we creating the desktop itself? */
             parent = GetDesktopWindow();
     }
 
@@ -983,7 +984,7 @@
 
     /* Create the window structure */
 
-    if (!(wndPtr = create_window_handle( parent, owner, classAtom, cs->hInstance, unicode )))
+    if (!(wndPtr = create_window_handle( parent, owner, className, cs->hInstance, unicode )))
         return 0;
     hwnd = wndPtr->hwndSelf;
 
@@ -1135,31 +1136,9 @@
                                 HWND16 parent, HMENU16 menu,
                                 HINSTANCE16 instance, LPVOID data )
 {
-    ATOM classAtom;
     CREATESTRUCTA cs;
     char buffer[256];
 
-    /* Find the class atom */
-
-    if (HIWORD(className))
-    {
-        if (!(classAtom = GlobalFindAtomA( className )))
-        {
-            ERR( "bad class name %s\n", debugstr_a(className) );
-            return 0;
-        }
-    }
-    else
-    {
-        classAtom = LOWORD(className);
-        if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
-        {
-            ERR( "bad atom %x\n", classAtom);
-            return 0;
-        }
-        className = buffer;
-    }
-
     /* Fix the coordinates */
 
     cs.x  = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)x;
@@ -1178,7 +1157,24 @@
     cs.lpszClass      = className;
     cs.dwExStyle      = exStyle;
 
-    return HWND_16( WIN_CreateWindowEx( &cs, classAtom, 0 ));
+    if (!IS_INTRESOURCE(className))
+    {
+        WCHAR bufferW[256];
+
+        if (!MultiByteToWideChar( CP_ACP, 0, className, -1, bufferW, sizeof(bufferW)/sizeof(WCHAR) ))
+            return 0;
+        return HWND_16( WIN_CreateWindowEx( &cs, bufferW, 0 ));
+    }
+    else
+    {
+        if (!GlobalGetAtomNameA( LOWORD(className), buffer, sizeof(buffer) ))
+        {
+            ERR( "bad atom %x\n", LOWORD(className));
+            return 0;
+        }
+        cs.lpszClass = buffer;
+        return HWND_16( WIN_CreateWindowEx( &cs, (LPCWSTR)className, 0 ));
+    }
 }
 
 
@@ -1191,32 +1187,7 @@
                                  HWND parent, HMENU menu,
                                  HINSTANCE instance, LPVOID data )
 {
-    ATOM classAtom;
     CREATESTRUCTA cs;
-    char buffer[256];
-
-    /* Find the class atom */
-
-    if (HIWORD(className))
-    {
-        if (!(classAtom = GlobalFindAtomA( className )))
-        {
-            ERR( "bad class name %s\n", debugstr_a(className) );
-            return 0;
-        }
-    }
-    else
-    {
-        classAtom = LOWORD(className);
-        if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
-        {
-            ERR( "bad atom %x\n", classAtom);
-            return 0;
-        }
-        className = buffer;
-    }
-
-    /* Create the window */
 
     cs.lpCreateParams = data;
     cs.hInstance      = instance;
@@ -1231,7 +1202,14 @@
     cs.lpszClass      = className;
     cs.dwExStyle      = exStyle;
 
-    return WIN_CreateWindowEx( &cs, classAtom, WIN_ISWIN32 );
+    if (!IS_INTRESOURCE(className))
+    {
+        WCHAR bufferW[256];
+        if (!MultiByteToWideChar( CP_ACP, 0, className, -1, bufferW, sizeof(bufferW)/sizeof(WCHAR) ))
+            return 0;
+        return WIN_CreateWindowEx( &cs, bufferW, WIN_ISWIN32 );
+    }
+    return WIN_CreateWindowEx( &cs, (LPCWSTR)className, WIN_ISWIN32 );
 }
 
 
@@ -1244,32 +1222,7 @@
                                  HWND parent, HMENU menu,
                                  HINSTANCE instance, LPVOID data )
 {
-    ATOM classAtom;
     CREATESTRUCTW cs;
-    WCHAR buffer[256];
-
-    /* Find the class atom */
-
-    if (HIWORD(className))
-    {
-        if (!(classAtom = GlobalFindAtomW( className )))
-        {
-            ERR( "bad class name %s\n", debugstr_w(className) );
-            return 0;
-        }
-    }
-    else
-    {
-        classAtom = LOWORD(className);
-        if (!GlobalGetAtomNameW( classAtom, buffer, sizeof(buffer)/sizeof(WCHAR) ))
-        {
-            ERR( "bad atom %x\n", classAtom);
-            return 0;
-        }
-        className = buffer;
-    }
-
-    /* Create the window */
 
     cs.lpCreateParams = data;
     cs.hInstance      = instance;
@@ -1286,7 +1239,7 @@
 
     /* Note: we rely on the fact that CREATESTRUCTA and */
     /* CREATESTRUCTW have the same layout. */
-    return WIN_CreateWindowEx( (CREATESTRUCTA *)&cs, classAtom, WIN_ISWIN32 | WIN_ISUNICODE );
+    return WIN_CreateWindowEx( (CREATESTRUCTA *)&cs, className, WIN_ISWIN32 | WIN_ISUNICODE );
 }
 
 
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 8d1485e..1643070 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -2746,6 +2746,7 @@
     user_handle_t  owner;
     atom_t         atom;
     void*          instance;
+    /* VARARG(class,unicode_str); */
 };
 struct create_window_reply
 {
@@ -4883,6 +4884,6 @@
     struct set_completion_info_reply set_completion_info_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 326
+#define SERVER_PROTOCOL_VERSION 327
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index f2e33ef..5cb951d 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2030,6 +2030,7 @@
     user_handle_t  owner;       /* owner window */
     atom_t         atom;        /* class atom */
     void*          instance;    /* module instance */
+    VARARG(class,unicode_str);  /* class name */
 @REPLY
     user_handle_t  handle;      /* created window */
     user_handle_t  parent;      /* full handle of parent */
diff --git a/server/trace.c b/server/trace.c
index a6d3ee5..2460cde 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -2526,7 +2526,9 @@
     fprintf( stderr, " parent=%p,", req->parent );
     fprintf( stderr, " owner=%p,", req->owner );
     fprintf( stderr, " atom=%04x,", req->atom );
-    fprintf( stderr, " instance=%p", req->instance );
+    fprintf( stderr, " instance=%p,", req->instance );
+    fprintf( stderr, " class=" );
+    dump_varargs_unicode_str( cur_size );
 }
 
 static void dump_create_window_reply( const struct create_window_reply *req )
diff --git a/server/window.c b/server/window.c
index ae24bd6..3e8219b 100644
--- a/server/window.c
+++ b/server/window.c
@@ -1561,6 +1561,7 @@
 DECL_HANDLER(create_window)
 {
     struct window *win, *parent, *owner = NULL;
+    atom_t atom;
 
     reply->handle = 0;
 
@@ -1580,7 +1581,13 @@
         else /* owner must be a top-level window */
             while (!is_desktop_window(owner->parent)) owner = owner->parent;
     }
-    if (!(win = create_window( parent, owner, req->atom, req->instance ))) return;
+
+    if (get_req_data_size())
+        atom = find_global_atom( NULL, get_req_data(), get_req_data_size() / sizeof(WCHAR) );
+    else
+        atom = req->atom;
+
+    if (!(win = create_window( parent, owner, atom, req->instance ))) return;
 
     reply->handle    = win->handle;
     reply->parent    = win->parent ? win->parent->handle : 0;