dinput: Combine ASCII and Unicode device create callbacks. Add tests.
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 59b81e8..d3727bc 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -504,8 +504,8 @@
   for (i = 0; i < NB_DINPUT_DEVICES; i++) {
     HRESULT ret;
 
-    if (!dinput_devices[i]->create_deviceA) continue;
-    if ((ret = dinput_devices[i]->create_deviceA(This, rguid, riid, (LPDIRECTINPUTDEVICEA*) pvOut)) == DI_OK)
+    if (!dinput_devices[i]->create_device) continue;
+    if ((ret = dinput_devices[i]->create_device(This, rguid, riid, pvOut, 0)) == DI_OK)
       return DI_OK;
 
     if (ret == DIERR_NOINTERFACE)
@@ -535,8 +535,8 @@
   for (i = 0; i < NB_DINPUT_DEVICES; i++) {
     HRESULT ret;
 
-    if (!dinput_devices[i]->create_deviceW) continue;
-    if ((ret = dinput_devices[i]->create_deviceW(This, rguid, riid, (LPDIRECTINPUTDEVICEW*) pvOut)) == DI_OK)
+    if (!dinput_devices[i]->create_device) continue;
+    if ((ret = dinput_devices[i]->create_device(This, rguid, riid, pvOut, 1)) == DI_OK)
       return DI_OK;
 
     if (ret == DIERR_NOINTERFACE)
diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h
index 73f3049..d4914dc 100644
--- a/dlls/dinput/dinput_private.h
+++ b/dlls/dinput/dinput_private.h
@@ -50,8 +50,7 @@
     const char *name;
     BOOL (*enum_deviceA)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id);
     BOOL (*enum_deviceW)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id);
-    HRESULT (*create_deviceA)(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev);
-    HRESULT (*create_deviceW)(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev);
+    HRESULT (*create_device)(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPVOID *pdev, int unicode);
 };
 
 extern const struct dinput_device mouse_device;
diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c
index 8348310..5541522 100644
--- a/dlls/dinput/joystick_linux.c
+++ b/dlls/dinput/joystick_linux.c
@@ -450,76 +450,63 @@
     return MAX_JOYSTICKS;
 }
 
-static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
+static HRESULT joydev_create_device(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPVOID *pdev, int unicode)
 {
     unsigned short index;
 
-    TRACE("%p %s %p %p\n",dinput, debugstr_guid(rguid), riid, pdev);
+    TRACE("%p %s %s %p %i\n", dinput, debugstr_guid(rguid), debugstr_guid(riid), pdev, unicode);
     find_joystick_devices();
     *pdev = NULL;
 
     if ((index = get_joystick_index(rguid)) < MAX_JOYSTICKS &&
         joystick_devices_count && index < joystick_devices_count)
     {
-        if ((riid == NULL) ||
-	    IsEqualGUID(&IID_IDirectInputDeviceA,  riid) ||
-	    IsEqualGUID(&IID_IDirectInputDevice2A, riid) ||
-	    IsEqualGUID(&IID_IDirectInputDevice7A, riid) ||
-	    IsEqualGUID(&IID_IDirectInputDevice8A, riid))
-        {
-            JoystickImpl *This;
-            HRESULT hr = alloc_device(rguid, dinput, &This, index);
+        JoystickImpl *This;
+        HRESULT hr;
 
-            *pdev = (LPDIRECTINPUTDEVICEA)(This ? &This->generic.base.IDirectInputDevice8A_iface : NULL);
-            return hr;
+        if (riid == NULL)
+            ;/* nothing */
+        else if (IsEqualGUID(&IID_IDirectInputDeviceA,  riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice2A, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice7A, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice8A, riid))
+        {
+            unicode = 0;
+        }
+        else if (IsEqualGUID(&IID_IDirectInputDeviceW,  riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice2W, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice7W, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice8W, riid))
+        {
+            unicode = 1;
+        }
+        else
+        {
+            WARN("no interface\n");
+            return DIERR_NOINTERFACE;
         }
 
-        WARN("no interface\n");
-        return DIERR_NOINTERFACE;
+        hr = alloc_device(rguid, dinput, &This, index);
+        if (!This) return hr;
+
+        if (unicode)
+            *pdev = &This->generic.base.IDirectInputDevice8W_iface;
+        else
+            *pdev = &This->generic.base.IDirectInputDevice8A_iface;
+
+        return hr;
     }
 
     return DIERR_DEVICENOTREG;
 }
 
-static HRESULT joydev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
-{
-    unsigned short index;
-
-    TRACE("%p %s %p %p\n",dinput, debugstr_guid(rguid), riid, pdev);
-    find_joystick_devices();
-    *pdev = NULL;
-
-    if ((index = get_joystick_index(rguid)) < MAX_JOYSTICKS &&
-        joystick_devices_count && index < joystick_devices_count)
-    {
-        if ((riid == NULL) ||
-	    IsEqualGUID(&IID_IDirectInputDeviceW,  riid) ||
-	    IsEqualGUID(&IID_IDirectInputDevice2W, riid) ||
-	    IsEqualGUID(&IID_IDirectInputDevice7W, riid) ||
-	    IsEqualGUID(&IID_IDirectInputDevice8W, riid))
-        {
-            JoystickImpl *This;
-            HRESULT hr = alloc_device(rguid, dinput, &This, index);
-
-            *pdev = (LPDIRECTINPUTDEVICEW)(This ? &This->generic.base.IDirectInputDevice8W_iface : NULL);
-            return hr;
-        }
-        WARN("no interface\n");
-        return DIERR_NOINTERFACE;
-    }
-
-    WARN("invalid device GUID %s\n",debugstr_guid(rguid));
-    return DIERR_DEVICENOTREG;
-}
-
 #undef MAX_JOYSTICKS
 
 const struct dinput_device joystick_linux_device = {
   "Wine Linux joystick driver",
   joydev_enum_deviceA,
   joydev_enum_deviceW,
-  joydev_create_deviceA,
-  joydev_create_deviceW
+  joydev_create_device
 };
 
 /******************************************************************************
@@ -742,7 +729,6 @@
   "Wine Linux joystick driver",
   NULL,
   NULL,
-  NULL,
   NULL
 };
 
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index 088f419..7e70912 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -560,82 +560,63 @@
     return MAX_JOYDEV;
 }
 
-static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
+static HRESULT joydev_create_device(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPVOID *pdev, int unicode)
 {
     unsigned short index;
 
+    TRACE("%p %s %s %p %i\n", dinput, debugstr_guid(rguid), debugstr_guid(riid), pdev, unicode);
     find_joydevs();
+    *pdev = NULL;
 
     if ((index = get_joystick_index(rguid)) < MAX_JOYDEV &&
         have_joydevs && index < have_joydevs)
     {
-        if ((riid == NULL) ||
-            IsEqualGUID(&IID_IDirectInputDeviceA,  riid) ||
-            IsEqualGUID(&IID_IDirectInputDevice2A, riid) ||
-            IsEqualGUID(&IID_IDirectInputDevice7A, riid) ||
-            IsEqualGUID(&IID_IDirectInputDevice8A, riid))
-        {
-            JoystickImpl *This = alloc_device(rguid, dinput, index);
-            TRACE("Created a Joystick device (%p)\n", This);
+        JoystickImpl *This;
 
-            if (!This)
-            {
-                ERR("out of memory\n");
-                *pdev = NULL;
-                return DIERR_OUTOFMEMORY;
-            }
-            *pdev = (IDirectInputDeviceA*) &This->generic.base.IDirectInputDevice8A_iface;
-            return DI_OK;
+        if (riid == NULL)
+            ;/* nothing */
+        else if (IsEqualGUID(&IID_IDirectInputDeviceA,  riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice2A, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice7A, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice8A, riid))
+        {
+            unicode = 0;
+        }
+        else if (IsEqualGUID(&IID_IDirectInputDeviceW,  riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice2W, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice7W, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice8W, riid))
+        {
+            unicode = 1;
+        }
+        else
+        {
+            WARN("no interface\n");
+            return DIERR_NOINTERFACE;
         }
 
-        WARN("no interface\n");
-        return DIERR_NOINTERFACE;
+        This = alloc_device(rguid, dinput, index);
+        TRACE("Created a Joystick device (%p)\n", This);
+
+        if (!This) return DIERR_OUTOFMEMORY;
+
+        if (unicode)
+            *pdev = &This->generic.base.IDirectInputDevice8W_iface;
+        else
+            *pdev = &This->generic.base.IDirectInputDevice8A_iface;
+
+        return DI_OK;
     }
 
     return DIERR_DEVICENOTREG;
 }
 
 
-static HRESULT joydev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
-{
-    unsigned short index;
-
-    find_joydevs();
-
-    if ((index = get_joystick_index(rguid)) < MAX_JOYDEV &&
-        have_joydevs && index < have_joydevs)
-    {
-        if ((riid == NULL) ||
-            IsEqualGUID(&IID_IDirectInputDeviceW,  riid) ||
-            IsEqualGUID(&IID_IDirectInputDevice2W, riid) ||
-            IsEqualGUID(&IID_IDirectInputDevice7W, riid) ||
-            IsEqualGUID(&IID_IDirectInputDevice8W, riid))
-        {
-            JoystickImpl *This = alloc_device(rguid, dinput, index);
-            TRACE("Created a Joystick device (%p)\n", This);
-
-            if (!This)
-            {
-                ERR("out of memory\n");
-                return DIERR_OUTOFMEMORY;
-            }
-            *pdev = (IDirectInputDeviceW*) &This->generic.base.IDirectInputDevice8W_iface;
-            return DI_OK;
-        }
-        WARN("no interface\n");
-        return DIERR_NOINTERFACE;
-    }
-
-    WARN("invalid device GUID\n");
-    return DIERR_DEVICENOTREG;
-}
-
 const struct dinput_device joystick_linuxinput_device = {
   "Wine Linux-input joystick driver",
   joydev_enum_deviceA,
   joydev_enum_deviceW,
-  joydev_create_deviceA,
-  joydev_create_deviceW
+  joydev_create_device
 };
 
 /******************************************************************************
@@ -1456,7 +1437,6 @@
   "Wine Linux-input joystick driver",
   NULL,
   NULL,
-  NULL,
   NULL
 };
 
diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c
index 2fa0bb9..a36bac8 100644
--- a/dlls/dinput/joystick_osx.c
+++ b/dlls/dinput/joystick_osx.c
@@ -878,12 +878,12 @@
     return 0xffff;
 }
 
-static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
+static HRESULT joydev_create_device(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPVOID *pdev, int unicode)
 {
     unsigned short index;
     int joystick_devices_count;
 
-    TRACE("%p %s %p %p\n",dinput, debugstr_guid(rguid), riid, pdev);
+    TRACE("%p %s %s %p %i\n", dinput, debugstr_guid(rguid), debugstr_guid(riid), pdev, unicode);
     *pdev = NULL;
 
     if ((joystick_devices_count = find_joystick_devices()) == 0)
@@ -892,66 +892,49 @@
     if ((index = get_joystick_index(rguid)) < 0xffff &&
         joystick_devices_count && index < joystick_devices_count)
     {
-        if ((riid == NULL) ||
-        IsEqualGUID(&IID_IDirectInputDeviceA,  riid) ||
-        IsEqualGUID(&IID_IDirectInputDevice2A, riid) ||
-        IsEqualGUID(&IID_IDirectInputDevice7A, riid) ||
-        IsEqualGUID(&IID_IDirectInputDevice8A, riid))
-        {
-            JoystickImpl *This;
-            HRESULT hr = alloc_device(rguid, dinput, &This, index);
+        JoystickImpl *This;
+        HRESULT hr;
 
-            *pdev = (LPDIRECTINPUTDEVICEA)(This ? &This->generic.base.IDirectInputDevice8A_iface : NULL);
-            return hr;
+        if (riid == NULL)
+            ;/* nothing */
+        else if (IsEqualGUID(&IID_IDirectInputDeviceA,  riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice2A, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice7A, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice8A, riid))
+        {
+            unicode = 0;
+        }
+        else if (IsEqualGUID(&IID_IDirectInputDeviceW,  riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice2W, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice7W, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice8W, riid))
+        {
+            unicode = 1;
+        }
+        else
+        {
+            WARN("no interface\n");
+            return DIERR_NOINTERFACE;
         }
 
-        WARN("no interface\n");
-        return DIERR_NOINTERFACE;
+        hr = alloc_device(rguid, dinput, &This, index);
+        if (!This) return hr;
+
+        if (unicode)
+            *pdev = &This->generic.base.IDirectInputDevice8W_iface;
+        else
+            *pdev = &This->generic.base.IDirectInputDevice8A_iface;
+        return hr;
     }
 
     return DIERR_DEVICENOTREG;
 }
 
-static HRESULT joydev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
-{
-    unsigned short index;
-    int joystick_devices_count;
-
-    TRACE("%p %s %p %p\n",dinput, debugstr_guid(rguid), riid, pdev);
-    *pdev = NULL;
-
-    if ((joystick_devices_count = find_joystick_devices()) == 0)
-        return DIERR_DEVICENOTREG;
-
-    if ((index = get_joystick_index(rguid)) < 0xffff &&
-        joystick_devices_count && index < joystick_devices_count)
-    {
-        if ((riid == NULL) ||
-        IsEqualGUID(&IID_IDirectInputDeviceW,  riid) ||
-        IsEqualGUID(&IID_IDirectInputDevice2W, riid) ||
-        IsEqualGUID(&IID_IDirectInputDevice7W, riid) ||
-        IsEqualGUID(&IID_IDirectInputDevice8W, riid))
-        {
-            JoystickImpl *This;
-            HRESULT hr = alloc_device(rguid, dinput, &This, index);
-
-            *pdev = (LPDIRECTINPUTDEVICEW)(This ? &This->generic.base.IDirectInputDevice8W_iface : NULL);
-            return hr;
-        }
-        WARN("no interface\n");
-        return DIERR_NOINTERFACE;
-    }
-
-    WARN("invalid device GUID %s\n",debugstr_guid(rguid));
-    return DIERR_DEVICENOTREG;
-}
-
 const struct dinput_device joystick_osx_device = {
   "Wine OS X joystick driver",
   joydev_enum_deviceA,
   joydev_enum_deviceW,
-  joydev_create_deviceA,
-  joydev_create_deviceW
+  joydev_create_device
 };
 
 static const IDirectInputDevice8AVtbl JoystickAvt =
@@ -1032,7 +1015,6 @@
   "Wine OS X joystick driver",
   NULL,
   NULL,
-  NULL,
   NULL
 };
 
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index f190677..6215f62 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -270,60 +270,59 @@
 }
 
 
-static HRESULT keyboarddev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
+static HRESULT keyboarddev_create_device(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPVOID *pdev, int unicode)
 {
-  if ((IsEqualGUID(&GUID_SysKeyboard,rguid)) ||          /* Generic Keyboard */
-      (IsEqualGUID(&DInput_Wine_Keyboard_GUID,rguid))) { /* Wine Keyboard */
-    if ((riid == NULL) ||
-	IsEqualGUID(&IID_IDirectInputDeviceA,riid) ||
-	IsEqualGUID(&IID_IDirectInputDevice2A,riid) ||
-	IsEqualGUID(&IID_IDirectInputDevice7A,riid) ||
-	IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
+    TRACE("%p %s %s %p %i\n", dinput, debugstr_guid(rguid), debugstr_guid(riid), pdev, unicode);
+    *pdev = NULL;
 
-      SysKeyboardImpl *This = alloc_device(rguid, dinput);
-      if (!This) {
-        *pdev = NULL;
-        return DIERR_OUTOFMEMORY;
-      }
-      *pdev = (IDirectInputDeviceA*) &This->base.IDirectInputDevice8A_iface;
-      TRACE("Creating a Keyboard device (%p)\n", *pdev);
-      return DI_OK;
-    } else
-      return DIERR_NOINTERFACE;
-  }
-  return DIERR_DEVICENOTREG;
-}
+    if (IsEqualGUID(&GUID_SysKeyboard, rguid) ||        /* Generic Keyboard */
+        IsEqualGUID(&DInput_Wine_Keyboard_GUID, rguid)) /* Wine Keyboard */
+    {
+        SysKeyboardImpl *This;
 
-static HRESULT keyboarddev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
-{
-  if ((IsEqualGUID(&GUID_SysKeyboard,rguid)) ||          /* Generic Keyboard */
-      (IsEqualGUID(&DInput_Wine_Keyboard_GUID,rguid))) { /* Wine Keyboard */
-    if ((riid == NULL) ||
-	IsEqualGUID(&IID_IDirectInputDeviceW,riid) ||
-	IsEqualGUID(&IID_IDirectInputDevice2W,riid) ||
-	IsEqualGUID(&IID_IDirectInputDevice7W,riid) ||
-	IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
+        if (riid == NULL)
+            ;/* nothing */
+        else if (IsEqualGUID(&IID_IDirectInputDeviceA,  riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice2A, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice7A, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice8A, riid))
+        {
+            unicode = 0;
+        }
+        else if (IsEqualGUID(&IID_IDirectInputDeviceW,  riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice2W, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice7W, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice8W, riid))
+        {
+            unicode = 1;
+        }
+        else
+        {
+            WARN("no interface\n");
+            return DIERR_NOINTERFACE;
+        }
 
-      SysKeyboardImpl *This = alloc_device(rguid, dinput);
-      if (!This) {
-        *pdev = NULL;
-        return DIERR_OUTOFMEMORY;
-      }
-      *pdev = (IDirectInputDeviceW*) &This->base.IDirectInputDevice8W_iface;
-      TRACE("Creating a Keyboard device (%p)\n", *pdev);
-      return DI_OK;
-    } else
-      return DIERR_NOINTERFACE;
-  }
-  return DIERR_DEVICENOTREG;
+        This = alloc_device(rguid, dinput);
+        TRACE("Created a Keyboard device (%p)\n", This);
+
+        if (!This) return DIERR_OUTOFMEMORY;
+
+        if (unicode)
+            *pdev = &This->base.IDirectInputDevice8W_iface;
+        else
+            *pdev = &This->base.IDirectInputDevice8A_iface;
+
+        return DI_OK;
+    }
+
+    return DIERR_DEVICENOTREG;
 }
 
 const struct dinput_device keyboard_device = {
   "Wine keyboard driver",
   keyboarddev_enum_deviceA,
   keyboarddev_enum_deviceW,
-  keyboarddev_create_deviceA,
-  keyboarddev_create_deviceW
+  keyboarddev_create_device
 };
 
 static HRESULT WINAPI SysKeyboardWImpl_GetDeviceState(LPDIRECTINPUTDEVICE8W iface, DWORD len, LPVOID ptr)
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
index 2aa0574..ace9fe2 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -256,55 +256,51 @@
     return NULL;
 }
 
-static HRESULT mousedev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
+static HRESULT mousedev_create_device(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPVOID *pdev, int unicode)
 {
-    if ((IsEqualGUID(&GUID_SysMouse,rguid)) ||             /* Generic Mouse */
-	(IsEqualGUID(&DInput_Wine_Mouse_GUID,rguid))) { /* Wine Mouse */
-	if ((riid == NULL) ||
-	    IsEqualGUID(&IID_IDirectInputDeviceA,riid) ||
-	    IsEqualGUID(&IID_IDirectInputDevice2A,riid) ||
-	    IsEqualGUID(&IID_IDirectInputDevice7A,riid) ||
-	    IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
+    TRACE("%p %s %s %p %i\n", dinput, debugstr_guid(rguid), debugstr_guid(riid), pdev, unicode);
+    *pdev = NULL;
 
-            SysMouseImpl* This = alloc_device(rguid, dinput);
-            TRACE("Created a Mouse device (%p)\n", This);
+    if (IsEqualGUID(&GUID_SysMouse, rguid) ||        /* Generic Mouse */
+        IsEqualGUID(&DInput_Wine_Mouse_GUID, rguid)) /* Wine Mouse */
+    {
+        SysMouseImpl *This;
 
-            if (!This) {
-                *pdev = NULL;
-                return DIERR_OUTOFMEMORY;
-            }
-            *pdev = (IDirectInputDeviceA*) &This->base.IDirectInputDevice8A_iface;
-	    return DI_OK;
-	} else
-	    return DIERR_NOINTERFACE;
+        if (riid == NULL)
+            ;/* nothing */
+        else if (IsEqualGUID(&IID_IDirectInputDeviceA,  riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice2A, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice7A, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice8A, riid))
+        {
+            unicode = 0;
+        }
+        else if (IsEqualGUID(&IID_IDirectInputDeviceW,  riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice2W, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice7W, riid) ||
+                 IsEqualGUID(&IID_IDirectInputDevice8W, riid))
+        {
+            unicode = 1;
+        }
+        else
+        {
+            WARN("no interface\n");
+            return DIERR_NOINTERFACE;
+        }
+
+        This = alloc_device(rguid, dinput);
+        TRACE("Created a Mouse device (%p)\n", This);
+
+        if (!This) return DIERR_OUTOFMEMORY;
+
+        if (unicode)
+            *pdev = &This->base.IDirectInputDevice8W_iface;
+        else
+            *pdev = &This->base.IDirectInputDevice8A_iface;
+
+        return DI_OK;
     }
-    
-    return DIERR_DEVICENOTREG;
-}
 
-static HRESULT mousedev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
-{
-    if ((IsEqualGUID(&GUID_SysMouse,rguid)) ||             /* Generic Mouse */
-	(IsEqualGUID(&DInput_Wine_Mouse_GUID,rguid))) { /* Wine Mouse */
-	if ((riid == NULL) ||
-	    IsEqualGUID(&IID_IDirectInputDeviceW,riid) ||
-	    IsEqualGUID(&IID_IDirectInputDevice2W,riid) ||
-	    IsEqualGUID(&IID_IDirectInputDevice7W,riid) ||
-	    IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
-
-            SysMouseImpl* This = alloc_device(rguid, dinput);
-            TRACE("Created a Mouse device (%p)\n", This);
-
-            if (!This) {
-                *pdev = NULL;
-                return DIERR_OUTOFMEMORY;
-            }
-            *pdev = (IDirectInputDeviceW*) &This->base.IDirectInputDevice8W_iface;
-	    return DI_OK;
-	} else
-	    return DIERR_NOINTERFACE;
-    }
-    
     return DIERR_DEVICENOTREG;
 }
 
@@ -312,8 +308,7 @@
     "Wine mouse driver",
     mousedev_enum_deviceA,
     mousedev_enum_deviceW,
-    mousedev_create_deviceA,
-    mousedev_create_deviceW
+    mousedev_create_device
 };
 
 /******************************************************************************
diff --git a/dlls/dinput/tests/device.c b/dlls/dinput/tests/device.c
index 83c18f1..a8ff19b 100644
--- a/dlls/dinput/tests/device.c
+++ b/dlls/dinput/tests/device.c
@@ -109,6 +109,8 @@
         ok(hr == DI_OK, "Acquire() failed: %08x\n", hr);
         hr = IDirectInputDevice_SetProperty(device, DIPROP_AXISMODE, &dp.diph);
         ok(hr == DIERR_ACQUIRED, "SetProperty() returned: %08x\n", hr);
+        hr = IDirectInputDevice_Unacquire(device);
+        ok(hr == DI_OK, "Unacquire() failed: %08x\n", hr);
     }
 }
 
@@ -121,7 +123,7 @@
 static BOOL CALLBACK enum_devices(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
 {
     struct enum_data *data = pvRef;
-    LPDIRECTINPUTDEVICE device;
+    LPDIRECTINPUTDEVICE device, obj = NULL;
     HRESULT hr;
 
     hr = IDirectInput_GetDeviceStatus(data->pDI, &lpddi->guidInstance);
@@ -131,8 +133,19 @@
     {
         hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidInstance, &device, NULL);
         ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
-        trace("Testing device \"%s\"\n", lpddi->tszInstanceName);
-        test_object_info(device, data->hwnd);
+        trace("Testing device %p \"%s\"\n", device, lpddi->tszInstanceName);
+
+        hr = IUnknown_QueryInterface(device, &IID_IDirectInputDevice2A, (LPVOID*)&obj);
+        ok(SUCCEEDED(hr), "IUnknown_QueryInterface(IID_IDirectInputDevice7A) failed: %08x\n", hr);
+        test_object_info(obj, data->hwnd);
+        if (obj) IUnknown_Release(obj);
+        obj = NULL;
+
+        hr = IUnknown_QueryInterface(device, &IID_IDirectInputDevice2W, (LPVOID*)&obj);
+        ok(SUCCEEDED(hr), "IUnknown_QueryInterface(IID_IDirectInputDevice7W) failed: %08x\n", hr);
+        test_object_info(obj, data->hwnd);
+        if (obj) IUnknown_Release(obj);
+
         IUnknown_Release(device);
     }
     return DIENUM_CONTINUE;
@@ -141,13 +154,13 @@
 static void device_tests(void)
 {
     HRESULT hr;
-    LPDIRECTINPUT pDI = NULL;
+    LPDIRECTINPUT pDI = NULL, obj = NULL;
     HINSTANCE hInstance = GetModuleHandle(NULL);
     HWND hwnd;
     struct enum_data data;
 
-    hr = DirectInputCreate(hInstance, DIRECTINPUT_VERSION, &pDI, NULL);
-    if (hr == DIERR_OLDDIRECTINPUTVERSION)
+    hr = CoCreateInstance(&CLSID_DirectInput, 0, 1, &IID_IDirectInput2A, (LPVOID*)&pDI);
+    if (hr == DIERR_OLDDIRECTINPUTVERSION || hr == DIERR_DEVICENOTREG)
     {
         skip("Tests require a newer dinput version\n");
         return;
@@ -155,6 +168,13 @@
     ok(SUCCEEDED(hr), "DirectInputCreate() failed: %08x\n", hr);
     if (FAILED(hr)) return;
 
+    hr = IDirectInput_Initialize(pDI, hInstance, DIRECTINPUT_VERSION);
+    ok(SUCCEEDED(hr), "Initialize() failed: %08x\n", hr);
+    if (FAILED(hr)) return;
+
+    hr = IUnknown_QueryInterface(pDI, &IID_IDirectInput2W, (LPVOID*)&obj);
+    ok(SUCCEEDED(hr), "QueryInterface(IDirectInput7W) failed: %08x\n", hr);
+
     hwnd = CreateWindow("static", "Title", WS_OVERLAPPEDWINDOW,
                         10, 10, 200, 200, NULL, NULL, NULL, NULL);
     ok(hwnd != NULL, "err: %d\n", GetLastError());
@@ -181,6 +201,7 @@
 
         DestroyWindow(hwnd);
     }
+    if (obj) IUnknown_Release(obj);
     if (pDI) IUnknown_Release(pDI);
 }