Send a CDN_FOLDERCHANGE message when we change folders.
[wine] / dlls / dinput / device.c
1 /*              DirectInput Device
2  *
3  * Copyright 1998 Marcus Meissner
4  * Copyright 1998,1999 Lionel Ulmer
5  *
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 /* This file contains all the Device specific functions that can be used as stubs
23    by real device implementations.
24
25    It also contains all the helper functions.
26 */
27 #include "config.h"
28
29 #include <string.h>
30 #include "wine/debug.h"
31 #include "wine/unicode.h"
32 #include "winbase.h"
33 #include "winerror.h"
34 #include "windef.h"
35 #include "dinput.h"
36 #include "device_private.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(dinput);
39
40 /******************************************************************************
41  *      Various debugging tools
42  */
43 void _dump_cooperativelevel_DI(DWORD dwFlags) {
44   int   i;
45   const struct {
46     DWORD       mask;
47     char        *name;
48   } flags[] = {
49 #define FE(x) { x, #x},
50     FE(DISCL_BACKGROUND)
51     FE(DISCL_EXCLUSIVE)
52     FE(DISCL_FOREGROUND)
53     FE(DISCL_NONEXCLUSIVE)
54 #undef FE
55   };
56   for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
57     if (flags[i].mask & dwFlags)
58       DPRINTF("%s ",flags[i].name);
59   DPRINTF("\n");
60 }
61
62 void _dump_EnumObjects_flags(DWORD dwFlags) {
63   int   i;
64   const struct {
65     DWORD       mask;
66     char        *name;
67   } flags[] = {
68 #define FE(x) { x, #x},
69     FE(DIDFT_ABSAXIS)
70     FE(DIDFT_ALL)
71     FE(DIDFT_AXIS)
72     FE(DIDFT_BUTTON)
73     FE(DIDFT_COLLECTION)
74     FE(DIDFT_FFACTUATOR)
75     FE(DIDFT_FFEFFECTTRIGGER)
76     FE(DIDFT_NOCOLLECTION)
77     FE(DIDFT_NODATA)
78     FE(DIDFT_OUTPUT)
79     FE(DIDFT_POV)
80     FE(DIDFT_PSHBUTTON)
81     FE(DIDFT_RELAXIS)
82     FE(DIDFT_TGLBUTTON)
83 #undef FE
84   };
85   if (dwFlags == DIDFT_ALL) {
86     DPRINTF("DIDFT_ALL");
87     return;
88   }
89   for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
90     if (flags[i].mask & dwFlags)
91       DPRINTF("%s ",flags[i].name);
92   if (dwFlags & DIDFT_INSTANCEMASK)
93     DPRINTF("Instance(%04lx) ", dwFlags >> 8);
94 }
95
96 void _dump_DIPROPHEADER(DIPROPHEADER *diph) {
97   DPRINTF("  - dwObj = 0x%08lx\n", diph->dwObj);
98   DPRINTF("  - dwHow = %s\n",
99           ((diph->dwHow == DIPH_DEVICE) ? "DIPH_DEVICE" :
100            ((diph->dwHow == DIPH_BYOFFSET) ? "DIPH_BYOFFSET" :
101             ((diph->dwHow == DIPH_BYID)) ? "DIPH_BYID" : "unknown")));
102 }
103
104 void _dump_OBJECTINSTANCEA(DIDEVICEOBJECTINSTANCEA *ddoi) {
105   if (TRACE_ON(dinput)) {
106     DPRINTF("    - enumerating : %s - %2ld - 0x%08lx - %s\n",
107             debugstr_guid(&ddoi->guidType), ddoi->dwOfs, ddoi->dwType, ddoi->tszName);
108   }
109 }
110
111 void _dump_OBJECTINSTANCEW(DIDEVICEOBJECTINSTANCEW *ddoi) {
112   if (TRACE_ON(dinput)) {
113     DPRINTF("    - enumerating : %s - %2ld - 0x%08lx - %s\n",
114             debugstr_guid(&ddoi->guidType), ddoi->dwOfs, ddoi->dwType, debugstr_w(ddoi->tszName));
115   }
116 }
117
118 /* Conversion between internal data buffer and external data buffer */
119 void fill_DataFormat(void *out, void *in, DataFormat *df) {
120   int i;
121   char *in_c = (char *) in;
122   char *out_c = (char *) out;
123
124   if (df->dt == NULL) {
125     /* This means that the app uses Wine's internal data format */
126     memcpy(out, in, df->internal_format_size);
127   } else {
128     for (i = 0; i < df->size; i++) {
129       if (df->dt[i].offset_in >= 0) {
130         switch (df->dt[i].size) {
131         case 1:
132           TRACE("Copying (c) to %d from %d (value %d)\n",
133                 df->dt[i].offset_out, df->dt[i].offset_in, *((char *) (in_c + df->dt[i].offset_in)));
134           *((char *) (out_c + df->dt[i].offset_out)) = *((char *) (in_c + df->dt[i].offset_in));
135           break;
136
137         case 2:
138           TRACE("Copying (s) to %d from %d (value %d)\n",
139                 df->dt[i].offset_out, df->dt[i].offset_in, *((short *) (in_c + df->dt[i].offset_in)));
140           *((short *) (out_c + df->dt[i].offset_out)) = *((short *) (in_c + df->dt[i].offset_in));
141           break;
142
143         case 4:
144           TRACE("Copying (i) to %d from %d (value %d)\n",
145                 df->dt[i].offset_out, df->dt[i].offset_in, *((int *) (in_c + df->dt[i].offset_in)));
146           *((int *) (out_c + df->dt[i].offset_out)) = *((int *) (in_c + df->dt[i].offset_in));
147           break;
148
149         default:
150           memcpy((out_c + df->dt[i].offset_out), (in_c + df->dt[i].offset_in), df->dt[i].size);
151         }
152       } else {
153         switch (df->dt[i].size) {
154         case 1:
155           TRACE("Copying (c) to %d default value %d\n",
156                 df->dt[i].offset_out, df->dt[i].value);
157           *((char *) (out_c + df->dt[i].offset_out)) = (char) df->dt[i].value;
158           break;
159
160         case 2:
161           TRACE("Copying (s) to %d default value %d\n",
162                 df->dt[i].offset_out, df->dt[i].value);
163           *((short *) (out_c + df->dt[i].offset_out)) = (short) df->dt[i].value;
164           break;
165
166         case 4:
167           TRACE("Copying (i) to %d default value %d\n",
168                 df->dt[i].offset_out, df->dt[i].value);
169           *((int *) (out_c + df->dt[i].offset_out)) = (int) df->dt[i].value;
170           break;
171
172         default:
173           memset((out_c + df->dt[i].offset_out), df->dt[i].size, 0);
174         }
175       }
176     }
177   }
178 }
179
180 DataFormat *create_DataFormat(DIDATAFORMAT *wine_format, LPCDIDATAFORMAT asked_format, int *offset) {
181   DataFormat *ret;
182   DataTransform *dt;
183   int i, j;
184   int same = 1;
185   int *done;
186   int index = 0;
187
188   ret = (DataFormat *) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat));
189
190   done = (int *) HeapAlloc(GetProcessHeap(), 0, sizeof(int) * asked_format->dwNumObjs);
191   memset(done, 0, sizeof(int) * asked_format->dwNumObjs);
192
193   dt = (DataTransform *) HeapAlloc(GetProcessHeap(), 0, asked_format->dwNumObjs * sizeof(DataTransform));
194
195   TRACE("Creating DataTransform : \n");
196
197   for (i = 0; i < wine_format->dwNumObjs; i++) {
198     offset[i] = -1;
199
200     for (j = 0; j < asked_format->dwNumObjs; j++) {
201       if (done[j] == 1)
202         continue;
203
204       if (((asked_format->rgodf[j].pguid == NULL) || (IsEqualGUID(wine_format->rgodf[i].pguid, asked_format->rgodf[j].pguid)))
205           &&
206           (wine_format->rgodf[i].dwType & asked_format->rgodf[j].dwType)) {
207
208         done[j] = 1;
209
210         TRACE("Matching : \n");
211         TRACE("   - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
212               j, debugstr_guid(asked_format->rgodf[j].pguid),
213               asked_format->rgodf[j].dwOfs,
214               DIDFT_GETTYPE(asked_format->rgodf[j].dwType), DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType));
215
216         TRACE("   - Wine  (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
217               j, debugstr_guid(wine_format->rgodf[i].pguid),
218               wine_format->rgodf[i].dwOfs,
219               DIDFT_GETTYPE(wine_format->rgodf[i].dwType), DIDFT_GETINSTANCE(wine_format->rgodf[i].dwType));
220
221         if (wine_format->rgodf[i].dwType & DIDFT_BUTTON)
222           dt[index].size = sizeof(BYTE);
223         else
224           dt[index].size = sizeof(DWORD);
225         dt[index].offset_in  = wine_format ->rgodf[i].dwOfs;
226         dt[index].offset_out = asked_format->rgodf[j].dwOfs;
227         dt[index].value = 0;
228         index++;
229
230         if (wine_format->rgodf[i].dwOfs != asked_format->rgodf[j].dwOfs)
231           same = 0;
232
233         offset[i] = asked_format->rgodf[j].dwOfs;
234         break;
235       }
236     }
237
238     if (j == asked_format->dwNumObjs)
239       same = 0;
240   }
241
242   TRACE("Setting to default value :\n");
243   for (j = 0; j < asked_format->dwNumObjs; j++) {
244     if (done[j] == 0) {
245       TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
246             j, debugstr_guid(asked_format->rgodf[j].pguid),
247             asked_format->rgodf[j].dwOfs,
248             DIDFT_GETTYPE(asked_format->rgodf[j].dwType), DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType));
249
250
251       if (asked_format->rgodf[j].dwType & DIDFT_BUTTON)
252         dt[index].size = sizeof(BYTE);
253       else
254         dt[index].size = sizeof(DWORD);
255       dt[index].offset_in  = -1;
256       dt[index].offset_out = asked_format->rgodf[j].dwOfs;
257       dt[index].value = 0;
258       index++;
259
260       same = 0;
261     }
262   }
263
264   ret->internal_format_size = wine_format->dwDataSize;
265   ret->size = index;
266   if (same) {
267     ret->dt = NULL;
268     HeapFree(GetProcessHeap(), 0, dt);
269   } else {
270     ret->dt = dt;
271   }
272
273   HeapFree(GetProcessHeap(), 0, done);
274
275   return ret;
276 }
277
278 BOOL DIEnumDevicesCallbackAtoW(LPCDIDEVICEOBJECTINSTANCEA lpddi, LPVOID lpvRef) {
279   DIDEVICEOBJECTINSTANCEW ddtmp;
280   device_enumobjects_AtoWcb_data* data;
281
282   data = (device_enumobjects_AtoWcb_data*) lpvRef;
283   
284   memset(&ddtmp, 0, sizeof(DIDEVICEINSTANCEW)); 
285
286   ddtmp.dwSize = sizeof(DIDEVICEINSTANCEW);
287   ddtmp.guidType     = lpddi->guidType;
288   ddtmp.dwOfs        = lpddi->dwOfs;
289   ddtmp.dwType       = lpddi->dwType;
290   ddtmp.dwFlags      = lpddi->dwFlags;
291   MultiByteToWideChar(CP_ACP, 0, lpddi->tszName, -1, ddtmp.tszName, MAX_PATH);
292
293   if (lpddi->dwSize == sizeof(DIDEVICEINSTANCEA)) {
294     /**
295      * if dwSize < sizeof(DIDEVICEINSTANCEA of DInput version >= 5)
296      *  force feedback and other newer datas aren't available
297      */
298     ddtmp.dwFFMaxForce        = lpddi->dwFFMaxForce;
299     ddtmp.dwFFForceResolution = lpddi->dwFFForceResolution;
300     ddtmp.wCollectionNumber   = lpddi->wCollectionNumber;
301     ddtmp.wDesignatorIndex    = lpddi->wDesignatorIndex;
302     ddtmp.wUsagePage          = lpddi->wUsagePage;
303     ddtmp.wUsage              = lpddi->wUsage;
304     ddtmp.dwDimension         = lpddi->dwDimension;
305     ddtmp.wExponent           = lpddi->wExponent;
306     ddtmp.wReserved           = lpddi->wReserved;
307   }
308   return data->lpCallBack(&ddtmp, data->lpvRef);
309 }
310
311 /******************************************************************************
312  *      IDirectInputDeviceA
313  */
314
315 HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
316         LPDIRECTINPUTDEVICE8A iface,LPCDIDATAFORMAT df
317 ) {
318   int i;
319   ICOM_THIS(IDirectInputDevice2AImpl,iface);
320
321   TRACE("(this=%p,%p)\n",This,df);
322
323   TRACE("df.dwSize=%ld\n",df->dwSize);
324   TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
325   TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
326   TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
327   TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
328
329   for (i=0;i<df->dwNumObjs;i++) {
330     TRACE("df.rgodf[%d].guid %s\n",i,debugstr_guid(df->rgodf[i].pguid));
331     TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
332     TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
333     TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
334   }
335   return DI_OK;
336 }
337
338 HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
339         LPDIRECTINPUTDEVICE8A iface,HWND hwnd,DWORD dwflags
340 ) {
341         ICOM_THIS(IDirectInputDevice2AImpl,iface);
342         TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags);
343         if (TRACE_ON(dinput)) {
344             TRACE(" cooperative level : ");
345             _dump_cooperativelevel_DI(dwflags);
346         }
347         return DI_OK;
348 }
349
350 HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
351         LPDIRECTINPUTDEVICE8A iface,HANDLE hnd
352 ) {
353         ICOM_THIS(IDirectInputDevice2AImpl,iface);
354         FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
355         return DI_OK;
356 }
357
358 ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface)
359 {
360         ICOM_THIS(IDirectInputDevice2AImpl,iface);
361         This->ref--;
362         if (This->ref)
363                 return This->ref;
364         HeapFree(GetProcessHeap(),0,This);
365         return DI_OK;
366 }
367
368 HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(
369         LPDIRECTINPUTDEVICE8A iface,REFIID riid,LPVOID *ppobj
370 )
371 {
372         ICOM_THIS(IDirectInputDevice2AImpl,iface);
373
374         TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
375         if (IsEqualGUID(&IID_IUnknown,riid)) {
376                 IDirectInputDevice2_AddRef(iface);
377                 *ppobj = This;
378                 return DI_OK;
379         }
380         if (IsEqualGUID(&IID_IDirectInputDeviceA,riid)) {
381                 IDirectInputDevice2_AddRef(iface);
382                 *ppobj = This;
383                 return DI_OK;
384         }
385         if (IsEqualGUID(&IID_IDirectInputDevice2A,riid)) {
386                 IDirectInputDevice2_AddRef(iface);
387                 *ppobj = This;
388                 return DI_OK;
389         }
390         if (IsEqualGUID(&IID_IDirectInputDevice7A,riid)) {
391                 IDirectInputDevice7_AddRef(iface);
392                 *ppobj = This;
393                 return DI_OK;
394         }
395         TRACE("Unsupported interface !\n");
396         return E_FAIL;
397 }
398
399 HRESULT WINAPI IDirectInputDevice2WImpl_QueryInterface(
400         LPDIRECTINPUTDEVICE8W iface,REFIID riid,LPVOID *ppobj
401 )
402 {
403         ICOM_THIS(IDirectInputDevice2AImpl,iface);
404
405         TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
406         if (IsEqualGUID(&IID_IUnknown,riid)) {
407                 IDirectInputDevice2_AddRef(iface);
408                 *ppobj = This;
409                 return DI_OK;
410         }
411         if (IsEqualGUID(&IID_IDirectInputDeviceW,riid)) {
412                 IDirectInputDevice2_AddRef(iface);
413                 *ppobj = This;
414                 return DI_OK;
415         }
416         if (IsEqualGUID(&IID_IDirectInputDevice2W,riid)) {
417                 IDirectInputDevice2_AddRef(iface);
418                 *ppobj = This;
419                 return DI_OK;
420         }
421         if (IsEqualGUID(&IID_IDirectInputDevice7W,riid)) {
422                 IDirectInputDevice7_AddRef(iface);
423                 *ppobj = This;
424                 return DI_OK;
425         }
426         TRACE("Unsupported interface !\n");
427         return E_FAIL;
428 }
429
430 ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
431         LPDIRECTINPUTDEVICE8A iface)
432 {
433         ICOM_THIS(IDirectInputDevice2AImpl,iface);
434         return ++This->ref;
435 }
436
437 HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
438         LPDIRECTINPUTDEVICE8A iface,
439         LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
440         LPVOID lpvRef,
441         DWORD dwFlags)
442 {
443         FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface, lpCallback, lpvRef, dwFlags);
444         if (TRACE_ON(dinput)) {
445           DPRINTF("  - flags = ");
446           _dump_EnumObjects_flags(dwFlags);
447           DPRINTF("\n");
448         }
449
450         return DI_OK;
451 }
452
453 HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects(
454         LPDIRECTINPUTDEVICE8W iface,
455         LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback,
456         LPVOID lpvRef,
457         DWORD dwFlags)
458 {
459         FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface, lpCallback, lpvRef, dwFlags);
460         if (TRACE_ON(dinput)) {
461           DPRINTF("  - flags = ");
462           _dump_EnumObjects_flags(dwFlags);
463           DPRINTF("\n");
464         }
465
466         return DI_OK;
467 }
468
469 HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
470         LPDIRECTINPUTDEVICE8A iface,
471         REFGUID rguid,
472         LPDIPROPHEADER pdiph)
473 {
474         FIXME("(this=%p,%s,%p): stub!\n",
475               iface, debugstr_guid(rguid), pdiph);
476
477         if (TRACE_ON(dinput))
478           _dump_DIPROPHEADER(pdiph);
479
480         return DI_OK;
481 }
482
483 HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
484         LPDIRECTINPUTDEVICE8A iface,
485         LPDIDEVICEOBJECTINSTANCEA pdidoi,
486         DWORD dwObj,
487         DWORD dwHow)
488 {
489         FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
490               iface, pdidoi, dwObj, dwHow);
491
492         return DI_OK;
493 }
494
495 HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo(
496         LPDIRECTINPUTDEVICE8W iface,
497         LPDIDEVICEOBJECTINSTANCEW pdidoi,
498         DWORD dwObj,
499         DWORD dwHow)
500 {
501         FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
502               iface, pdidoi, dwObj, dwHow);
503
504         return DI_OK;
505 }
506
507 HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
508         LPDIRECTINPUTDEVICE8A iface,
509         LPDIDEVICEINSTANCEA pdidi)
510 {
511         FIXME("(this=%p,%p): stub!\n",
512               iface, pdidi);
513
514         return DI_OK;
515 }
516 HRESULT WINAPI IDirectInputDevice2WImpl_GetDeviceInfo(
517         LPDIRECTINPUTDEVICE8W iface,
518         LPDIDEVICEINSTANCEW pdidi)
519 {
520         FIXME("(this=%p,%p): stub!\n",
521               iface, pdidi);
522
523         return DI_OK;
524 }
525
526 HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
527         LPDIRECTINPUTDEVICE8A iface,
528         HWND hwndOwner,
529         DWORD dwFlags)
530 {
531   FIXME("(this=%p,%p,0x%08lx): stub!\n",
532         iface, hwndOwner, dwFlags);
533
534         return DI_OK;
535 }
536
537 HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
538         LPDIRECTINPUTDEVICE8A iface,
539         HINSTANCE hinst,
540         DWORD dwVersion,
541         REFGUID rguid)
542 {
543         FIXME("(this=%p,%p,%ld,%s): stub!\n",
544               iface, hinst, dwVersion, debugstr_guid(rguid));
545         return DI_OK;
546 }
547
548 /******************************************************************************
549  *      IDirectInputDevice2A
550  */
551
552 HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
553         LPDIRECTINPUTDEVICE8A iface,
554         REFGUID rguid,
555         LPCDIEFFECT lpeff,
556         LPDIRECTINPUTEFFECT *ppdef,
557         LPUNKNOWN pUnkOuter)
558 {
559         FIXME("(this=%p,%s,%p,%p,%p): stub!\n",
560               iface, debugstr_guid(rguid), lpeff, ppdef, pUnkOuter);
561         return DI_OK;
562 }
563
564 HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
565         LPDIRECTINPUTDEVICE8A iface,
566         LPDIENUMEFFECTSCALLBACKA lpCallback,
567         LPVOID lpvRef,
568         DWORD dwFlags)
569 {
570         FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
571               iface, lpCallback, lpvRef, dwFlags);
572
573         if (lpCallback)
574                 lpCallback(NULL, lpvRef);
575         return DI_OK;
576 }
577
578 HRESULT WINAPI IDirectInputDevice2WImpl_EnumEffects(
579         LPDIRECTINPUTDEVICE8W iface,
580         LPDIENUMEFFECTSCALLBACKW lpCallback,
581         LPVOID lpvRef,
582         DWORD dwFlags)
583 {
584         FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
585               iface, lpCallback, lpvRef, dwFlags);
586
587         if (lpCallback)
588                 lpCallback(NULL, lpvRef);
589         return DI_OK;
590 }
591
592 HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
593         LPDIRECTINPUTDEVICE8A iface,
594         LPDIEFFECTINFOA lpdei,
595         REFGUID rguid)
596 {
597         FIXME("(this=%p,%p,%s): stub!\n",
598               iface, lpdei, debugstr_guid(rguid));
599         return DI_OK;
600 }
601
602 HRESULT WINAPI IDirectInputDevice2WImpl_GetEffectInfo(
603         LPDIRECTINPUTDEVICE8W iface,
604         LPDIEFFECTINFOW lpdei,
605         REFGUID rguid)
606 {
607         FIXME("(this=%p,%p,%s): stub!\n",
608               iface, lpdei, debugstr_guid(rguid));
609         return DI_OK;
610 }
611
612 HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
613         LPDIRECTINPUTDEVICE8A iface,
614         LPDWORD pdwOut)
615 {
616         FIXME("(this=%p,%p): stub!\n",
617               iface, pdwOut);
618         return DI_OK;
619 }
620
621 HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
622         LPDIRECTINPUTDEVICE8A iface,
623         DWORD dwFlags)
624 {
625         FIXME("(this=%p,0x%08lx): stub!\n",
626               iface, dwFlags);
627         return DI_OK;
628 }
629
630 HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
631         LPDIRECTINPUTDEVICE8A iface,
632         LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
633         LPVOID lpvRef,
634         DWORD dwFlags)
635 {
636         FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
637               iface, lpCallback, lpvRef, dwFlags);
638         if (lpCallback)
639                 lpCallback(NULL, lpvRef);
640         return DI_OK;
641 }
642
643 HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
644         LPDIRECTINPUTDEVICE8A iface,
645         LPDIEFFESCAPE lpDIEEsc)
646 {
647         FIXME("(this=%p,%p): stub!\n",
648               iface, lpDIEEsc);
649         return DI_OK;
650 }
651
652 HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
653         LPDIRECTINPUTDEVICE8A iface)
654 {
655         /* Because wine devices do not need to be polled, just return DI_NOEFFECT */
656         return DI_NOEFFECT;
657 }
658
659 HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
660         LPDIRECTINPUTDEVICE8A iface,
661         DWORD cbObjectData,
662         LPCDIDEVICEOBJECTDATA rgdod,
663         LPDWORD pdwInOut,
664         DWORD dwFlags)
665 {
666         FIXME("(this=%p,0x%08lx,%p,%p,0x%08lx): stub!\n",
667               iface, cbObjectData, rgdod, pdwInOut, dwFlags);
668
669         return DI_OK;
670 }
671
672 HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8A iface,
673                                                           LPCSTR lpszFileName,
674                                                           LPDIENUMEFFECTSINFILECALLBACK pec,
675                                                           LPVOID pvRef,
676                                                           DWORD dwFlags)
677 {
678   FIXME("(%p)->(%s,%p,%p,%08lx): stub !\n", iface, lpszFileName, pec, pvRef, dwFlags);
679
680   return DI_OK;
681 }
682
683 HRESULT WINAPI IDirectInputDevice7WImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8W iface,
684                                                           LPCWSTR lpszFileName,
685                                                           LPDIENUMEFFECTSINFILECALLBACK pec,
686                                                           LPVOID pvRef,
687                                                           DWORD dwFlags)
688 {
689   FIXME("(%p)->(%s,%p,%p,%08lx): stub !\n", iface, debugstr_w(lpszFileName), pec, pvRef, dwFlags);
690
691   return DI_OK;
692 }
693
694 HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8A iface,
695                                                           LPCSTR lpszFileName,
696                                                           DWORD dwEntries,
697                                                           LPDIFILEEFFECT rgDiFileEft,
698                                                           DWORD dwFlags)
699 {
700   FIXME("(%p)->(%s,%08lx,%p,%08lx): stub !\n", iface, lpszFileName, dwEntries, rgDiFileEft, dwFlags);
701
702   return DI_OK;
703 }
704
705 HRESULT WINAPI IDirectInputDevice7WImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8W iface,
706                                                           LPCWSTR lpszFileName,
707                                                           DWORD dwEntries,
708                                                           LPDIFILEEFFECT rgDiFileEft,
709                                                           DWORD dwFlags)
710 {
711   FIXME("(%p)->(%s,%08lx,%p,%08lx): stub !\n", iface, debugstr_w(lpszFileName), dwEntries, rgDiFileEft, dwFlags);
712
713   return DI_OK;
714 }
715
716 HRESULT WINAPI IDirectInputDevice8AImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface,
717                                                        LPDIACTIONFORMATA lpdiaf,
718                                                        LPCSTR lpszUserName,
719                                                        DWORD dwFlags)
720 {
721   FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
722
723   return DI_OK;
724 }
725
726 HRESULT WINAPI IDirectInputDevice8WImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface,
727                                                        LPDIACTIONFORMATW lpdiaf,
728                                                        LPCWSTR lpszUserName,
729                                                        DWORD dwFlags)
730 {
731   FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags);
732
733   return DI_OK;
734 }
735
736 HRESULT WINAPI IDirectInputDevice8AImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface,
737                                                      LPDIACTIONFORMATA lpdiaf,
738                                                      LPCSTR lpszUserName,
739                                                      DWORD dwFlags)
740 {
741   FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
742
743   return DI_OK;
744 }
745
746 HRESULT WINAPI IDirectInputDevice8WImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface,
747                                                      LPDIACTIONFORMATW lpdiaf,
748                                                      LPCWSTR lpszUserName,
749                                                      DWORD dwFlags)
750 {
751   FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags);
752
753   return DI_OK;
754 }
755
756 HRESULT WINAPI IDirectInputDevice8AImpl_GetImageInfo(LPDIRECTINPUTDEVICE8A iface,
757                                                      LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader)
758 {
759   FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader);
760
761   return DI_OK;
762 }
763
764 HRESULT WINAPI IDirectInputDevice8WImpl_GetImageInfo(LPDIRECTINPUTDEVICE8W iface,
765                                                      LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader)
766 {
767   FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader);
768
769   return DI_OK;
770 }