Merged msacm and msacm32 dlls.
[wine] / dlls / winmm / mciavi / mciavi.c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2
3 /*
4  * Digital video MCI Wine Driver
5  *
6  * Copyright 1999 Eric POUECH
7  */
8
9 #include <string.h>
10 #include "windef.h"
11 #include "wingdi.h"
12 #include "winuser.h"
13 #include "mmddk.h"
14 #include "user.h"
15 #include "driver.h"
16 #include "digitalv.h"
17 #include "debugtools.h"
18
19 DEFAULT_DEBUG_CHANNEL(mciavi)
20
21 typedef struct {
22     UINT                wDevID;
23     int                 nUseCount;              /* Incremented for each shared open          */
24     BOOL16              fShareable;             /* TRUE if first open was shareable          */
25     WORD                wNotifyDeviceID;        /* MCI device ID with a pending notification */
26     HANDLE16            hCallback;              /* Callback handle for pending notification  */
27     HMMIO               hFile;                  /* mmio file handle open as Element          */
28     WORD                wStatus;                /* One of MCI_MODE_XXX                       */
29     MCI_OPEN_PARMSA     openParms;
30     DWORD               dwTimeFormat;
31 } WINE_MCIAVI;
32
33 /*======================================================================*
34  *                          MCI AVI implemantation                      *
35  *======================================================================*/
36
37 /**************************************************************************
38  *                              AVI_drvOpen                     [internal]      
39  */
40 static  DWORD   AVI_drvOpen(LPSTR str, LPMCI_OPEN_DRIVER_PARMSA modp)
41 {
42     WINE_MCIAVI*        wma = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIAVI));
43
44     if (!wma)
45         return 0;
46
47     wma->wDevID = modp->wDeviceID;
48     mciSetDriverData(wma->wDevID, (DWORD)wma);
49     modp->wCustomCommandTable = MCI_NO_COMMAND_TABLE;
50     modp->wType = MCI_DEVTYPE_DIGITAL_VIDEO;
51     return modp->wDeviceID;
52 }
53
54 /**************************************************************************
55  *                              MCIAVI_drvClose         [internal]      
56  */
57 static  DWORD   AVI_drvClose(DWORD dwDevID)
58 {
59     WINE_MCIAVI*  wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);
60
61     if (wma) {
62         HeapFree(GetProcessHeap(), 0, wma);     
63         mciSetDriverData(dwDevID, 0);
64         return 1;
65     }
66     return 0;
67 }
68
69 /**************************************************************************
70  *                              AVI_mciGetOpenDev               [internal]      
71  */
72 static WINE_MCIAVI*  AVI_mciGetOpenDev(UINT16 wDevID)
73 {
74     WINE_MCIAVI*        wma = (WINE_MCIAVI*)mciGetDriverData(wDevID);
75     
76     if (wma == NULL || wma->nUseCount == 0) {
77         WARN("Invalid wDevID=%u\n", wDevID);
78         return 0;
79     }
80     return wma;
81 }
82
83 static  DWORD   AVI_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
84
85 /***************************************************************************
86  *                              AVI_mciOpen                     [internal]
87  */
88 static  DWORD   AVI_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSA lpParms)
89 {
90     WINE_MCIAVI*        wma = (WINE_MCIAVI*)mciGetDriverData(wDevID);
91     
92     TRACE("(%04x, %08lX, %p) : semi-stub\n", wDevID, dwFlags, lpParms);
93     
94     if (lpParms == NULL)                return MCIERR_NULL_PARAMETER_BLOCK;
95     if (wma == NULL)                    return MCIERR_INVALID_DEVICE_ID;
96     
97     if (wma->nUseCount > 0) {
98         /* The driver is already open on this channel */
99         /* If the driver was opened shareable before and this open specifies */
100         /* shareable then increment the use count */
101         if (wma->fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
102             ++wma->nUseCount;
103         else
104             return MCIERR_MUST_USE_SHAREABLE;
105     } else {
106         wma->nUseCount = 1;
107         wma->fShareable = dwFlags & MCI_OPEN_SHAREABLE;
108     }
109     if (dwFlags & MCI_OPEN_ELEMENT) {
110         TRACE("MCI_OPEN_ELEMENT !\n");
111         /*              return MCIERR_NO_ELEMENT_ALLOWED; */
112     }
113     
114     wma->openParms.dwCallback = lpParms->dwCallback;
115     wma->openParms.wDeviceID  = (WORD)lpParms->wDeviceID;
116     wma->openParms.lpstrDeviceType = lpParms->lpstrDeviceType;
117     wma->openParms.lpstrElementName = lpParms->lpstrElementName;
118     wma->openParms.lpstrAlias = lpParms->lpstrAlias;
119     
120     wma->wNotifyDeviceID = lpParms->wDeviceID;
121     /* FIXME: do real open */
122     wma->wStatus = MCI_MODE_STOP;
123     wma->dwTimeFormat = MCI_FORMAT_TMSF;
124     
125     return 0;
126     
127 }
128
129 /***************************************************************************
130  *                              AVI_mciClose                    [internal]
131  */
132 static  DWORD   AVI_mciClose(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
133 {
134     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
135     
136     TRACE("(%04x, %08lX, %p) : semi-stub\n", wDevID, dwFlags, lpParms);    
137     
138     if (wma == NULL)    return MCIERR_INVALID_DEVICE_ID;
139     
140     if (wma->nUseCount == 1) {
141         AVI_mciStop(wDevID, 0, NULL);
142         /* FIXME: do real closing */
143     }
144     wma->nUseCount--;
145     return 0;
146 }
147
148 /***************************************************************************
149  *                              AVI_mciPlay                     [internal]
150  */
151 static  DWORD   AVI_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
152 {
153     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
154     
155     TRACE("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
156     
157     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
158     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
159     
160     wma->wStatus = MCI_MODE_PLAY;
161     if (lpParms && (dwFlags & MCI_NOTIFY)) {
162         TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
163         mciDriverNotify16((HWND16)LOWORD(lpParms->dwCallback), 
164                           wma->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
165     }
166     return 0;
167 }
168
169 /***************************************************************************
170  *                              AVI_mciRecord                   [internal]
171  */
172 static  DWORD   AVI_mciRecord(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_RECORD_PARMS lpParms)
173 {
174     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
175     
176     TRACE("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
177     
178     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
179     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
180     
181     wma->wStatus = MCI_MODE_RECORD;
182     return 0;
183 }
184
185 /***************************************************************************
186  *                              AVI_mciStop                     [internal]
187  */
188 static  DWORD   AVI_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
189 {
190     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
191     
192     TRACE("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
193     
194     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
195     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
196     
197     wma->wStatus = MCI_MODE_STOP;
198     return 0;
199 }
200
201 /***************************************************************************
202  *                              AVI_mciPause                    [internal]
203  */
204 static  DWORD   AVI_mciPause(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
205 {
206     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
207     
208     TRACE("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
209     
210     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
211     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
212     
213     wma->wStatus = MCI_MODE_PAUSE;
214     return 0;
215 }
216
217 /***************************************************************************
218  *                              AVI_mciResume                   [internal]
219  */
220 static  DWORD   AVI_mciResume(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
221 {
222     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
223     
224     TRACE("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
225     
226     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
227     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
228     
229     wma->wStatus = MCI_MODE_PLAY;
230     return 0;
231 }
232
233 /***************************************************************************
234  *                              AVI_mciSeek                     [internal]
235  */
236 static  DWORD   AVI_mciSeek(UINT16 wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
237 {
238     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
239     
240     TRACE("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
241     
242     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
243     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
244     
245     return 0;
246 }
247
248 /***************************************************************************
249  *                              AVI_mciSet                      [internal]
250  */
251 static  DWORD   AVI_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_SET_PARMS lpParms)
252 {
253     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
254     
255     TRACE("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
256     
257     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
258     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
259     
260     if (dwFlags & MCI_SET_TIME_FORMAT) {
261         switch (lpParms->dwTimeFormat) {
262         case MCI_FORMAT_MILLISECONDS:
263             TRACE("MCI_FORMAT_MILLISECONDS !\n");
264             wma->dwTimeFormat = MCI_FORMAT_MILLISECONDS;
265             break;
266         case MCI_FORMAT_FRAMES:
267             TRACE("MCI_FORMAT_FRAMES !\n");
268             wma->dwTimeFormat = MCI_FORMAT_FRAMES;
269             break;
270         default:
271             WARN("Bad time format %lu!\n", lpParms->dwTimeFormat);
272             return MCIERR_BAD_TIME_FORMAT;
273         }
274     }
275     
276     if (dwFlags & MCI_SET_DOOR_OPEN) {
277         TRACE("No support for door open !\n");
278         return MCIERR_UNSUPPORTED_FUNCTION;
279     }
280     if (dwFlags & MCI_SET_DOOR_CLOSED) {
281         TRACE("No support for door close !\n");
282         return MCIERR_UNSUPPORTED_FUNCTION;
283     }
284     if (dwFlags & MCI_SET_ON) {
285         char    buffer[256];
286         
287         strcpy(buffer, "MCI_SET_ON:");
288         
289         if (dwFlags & MCI_SET_VIDEO) {
290             strncat(buffer, " video", sizeof(buffer));
291         }
292         if (dwFlags & MCI_SET_AUDIO) {
293             strncat(buffer, " audio", sizeof(buffer));
294             if (lpParms->dwAudio & MCI_SET_AUDIO_ALL)
295                 strncat(buffer, " all", sizeof(buffer));
296             if (lpParms->dwAudio & MCI_SET_AUDIO_LEFT)
297                 strncat(buffer, " left", sizeof(buffer));
298             if (lpParms->dwAudio & MCI_SET_AUDIO_RIGHT)
299                 strncat(buffer, " right", sizeof(buffer));
300         }
301         if (dwFlags & MCI_DGV_SET_SEEK_EXACTLY) {
302             strncat(buffer, " seek_exactly", sizeof(buffer));
303         }
304         TRACE("%s\n", buffer);
305     }
306     
307     if (dwFlags & MCI_SET_OFF) {
308         char    buffer[256];
309         
310         strcpy(buffer, "MCI_SET_OFF:");
311         if (dwFlags & MCI_SET_VIDEO) {
312             strncat(buffer, " video", sizeof(buffer));
313         }
314         if (dwFlags & MCI_SET_AUDIO) {
315             strncat(buffer, " audio", sizeof(buffer));
316             if (lpParms->dwAudio & MCI_SET_AUDIO_ALL)
317                 strncat(buffer, " all", sizeof(buffer));
318             if (lpParms->dwAudio & MCI_SET_AUDIO_LEFT)
319                 strncat(buffer, " left", sizeof(buffer));
320             if (lpParms->dwAudio & MCI_SET_AUDIO_RIGHT)
321                 strncat(buffer, " right", sizeof(buffer));
322         }
323         if (dwFlags & MCI_DGV_SET_SEEK_EXACTLY) {
324             strncat(buffer, " seek_exactly", sizeof(buffer));
325         }
326         TRACE("%s\n", buffer);
327     }
328     if (dwFlags & MCI_DGV_SET_FILEFORMAT) {
329         LPSTR   str = "save";
330         if (dwFlags & MCI_DGV_SET_STILL)        
331             str = "capture";
332         
333         switch (lpParms->dwFileFormat) {
334         case MCI_DGV_FF_AVI:    TRACE("Setting file format (%s) to 'AVI'\n", str);      break;
335         case MCI_DGV_FF_AVSS:   TRACE("Setting file format (%s) to 'AVSS'\n", str);     break;
336         case MCI_DGV_FF_DIB:    TRACE("Setting file format (%s) to 'DIB'\n", str);      break;
337         case MCI_DGV_FF_JFIF:   TRACE("Setting file format (%s) to 'JFIF'\n", str);     break;
338         case MCI_DGV_FF_JPEG:   TRACE("Setting file format (%s) to 'JPEG'\n", str);     break;
339         case MCI_DGV_FF_MPEG:   TRACE("Setting file format (%s) to 'MPEG'\n", str);     break;
340         case MCI_DGV_FF_RDIB:   TRACE("Setting file format (%s) to 'RLE DIB'\n", str);  break;
341         case MCI_DGV_FF_RJPEG:  TRACE("Setting file format (%s) to 'RJPEG'\n", str);    break;
342         default:                TRACE("Setting unknown file format (%s): %ld\n", str, lpParms->dwFileFormat);
343         }
344     }
345     
346     if (dwFlags & MCI_DGV_SET_SPEED) {
347         TRACE("Setting speed to %ld\n", lpParms->dwSpeed);
348     }
349     
350     return 0;
351 }
352
353 /***************************************************************************
354  *                              AVI_mciStatus                   [internal]
355  */
356 static  DWORD   AVI_mciStatus(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpParms)
357 {
358     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
359     DWORD               ret = 0;
360
361     TRACE("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
362     
363     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
364     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
365     
366     if (dwFlags & MCI_STATUS_ITEM) {
367         switch (lpParms->dwItem) {
368         case MCI_STATUS_CURRENT_TRACK:
369             lpParms->dwReturn = 1;
370             TRACE("MCI_STATUS_CURRENT_TRACK => %lu\n", lpParms->dwReturn);
371             break;
372         case MCI_STATUS_LENGTH:
373             if (dwFlags & MCI_TRACK) {
374                 /* lpParms->dwTrack contains track # */
375                 lpParms->dwReturn = 0x1234;
376             } else {
377                 lpParms->dwReturn = 0x4321;
378             }
379             TRACE("MCI_STATUS_LENGTH => %lu\n", lpParms->dwReturn);
380             break;
381         case MCI_STATUS_MODE:
382             lpParms->dwReturn = MAKEMCIRESOURCE(wma->wStatus, wma->wStatus);
383             ret = MCI_RESOURCE_RETURNED;
384             TRACE("MCI_STATUS_MODE => %u\n", LOWORD(lpParms->dwReturn));
385             break;
386         case MCI_STATUS_MEDIA_PRESENT:
387             TRACE("MCI_STATUS_MEDIA_PRESENT => TRUE\n");
388             lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
389             ret = MCI_RESOURCE_RETURNED;
390             break;
391         case MCI_STATUS_NUMBER_OF_TRACKS:
392             lpParms->dwReturn = 3;
393             TRACE("MCI_STATUS_NUMBER_OF_TRACKS => %lu\n", lpParms->dwReturn);
394             break;
395         case MCI_STATUS_POSITION:
396             /* FIXME: do I need to use MCI_TRACK ? */
397             lpParms->dwReturn = 0x0123;
398             TRACE("MCI_STATUS_POSITION %s => %lu\n", 
399                   (dwFlags & MCI_STATUS_START) ? "start" : "current", lpParms->dwReturn);
400             break;
401         case MCI_STATUS_READY:
402             lpParms->dwReturn = (wma->wStatus == MCI_MODE_NOT_READY) ?
403                 MAKEMCIRESOURCE(FALSE, MCI_FALSE) : MAKEMCIRESOURCE(TRUE, MCI_TRUE);
404             ret = MCI_RESOURCE_RETURNED;
405             TRACE("MCI_STATUS_READY = %u\n", LOWORD(lpParms->dwReturn));
406             break;
407         case MCI_STATUS_TIME_FORMAT:
408             lpParms->dwReturn = MAKEMCIRESOURCE(wma->dwTimeFormat, wma->dwTimeFormat);
409             TRACE("MCI_STATUS_TIME_FORMAT => %u\n", LOWORD(lpParms->dwReturn));
410             ret = MCI_RESOURCE_RETURNED;
411             break;
412         default:
413             FIXME("Unknowm command %08lX !\n", lpParms->dwItem);
414             return MCIERR_UNRECOGNIZED_COMMAND;
415         }
416     } else {
417         WARN("No Status-Item!\n");
418         return MCIERR_UNRECOGNIZED_COMMAND;
419     }
420     if (dwFlags & MCI_NOTIFY) {
421         TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
422         mciDriverNotify16((HWND16)LOWORD(lpParms->dwCallback), 
423                           wma->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
424     }
425     
426     return ret;
427 }
428
429 /***************************************************************************
430  *                              AVI_mciGetDevCaps                       [internal]
431  */
432 static  DWORD   AVI_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags,  LPMCI_GETDEVCAPS_PARMS lpParms)
433 {
434     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
435     DWORD               ret;
436
437     TRACE("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
438     
439     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
440     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
441     
442     if (dwFlags & MCI_GETDEVCAPS_ITEM) {
443         switch (lpParms->dwItem) {
444         case MCI_GETDEVCAPS_DEVICE_TYPE:
445             TRACE("MCI_GETDEVCAPS_DEVICE_TYPE !\n");
446             lpParms->dwReturn = MAKEMCIRESOURCE(MCI_DEVTYPE_DIGITAL_VIDEO, MCI_DEVTYPE_DIGITAL_VIDEO);
447             ret = MCI_RESOURCE_RETURNED;
448             break;
449         case MCI_GETDEVCAPS_HAS_AUDIO:
450             TRACE("MCI_GETDEVCAPS_HAS_AUDIO !\n");
451             lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
452             ret = MCI_RESOURCE_RETURNED;
453             break;
454         case MCI_GETDEVCAPS_HAS_VIDEO:
455             TRACE("MCI_GETDEVCAPS_HAS_VIDEO !\n");
456             lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
457             ret = MCI_RESOURCE_RETURNED;
458             break;
459         case MCI_GETDEVCAPS_USES_FILES:
460             TRACE("MCI_GETDEVCAPS_USES_FILES !\n");
461             lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
462             ret = MCI_RESOURCE_RETURNED;
463             break;
464         case MCI_GETDEVCAPS_COMPOUND_DEVICE:
465             TRACE("MCI_GETDEVCAPS_COMPOUND_DEVICE !\n");
466             lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
467             ret = MCI_RESOURCE_RETURNED;
468             break;
469         case MCI_GETDEVCAPS_CAN_EJECT:
470             TRACE("MCI_GETDEVCAPS_CAN_EJECT !\n");
471             lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
472             ret = MCI_RESOURCE_RETURNED;
473             break;
474         case MCI_GETDEVCAPS_CAN_PLAY:
475             TRACE("MCI_GETDEVCAPS_CAN_PLAY !\n");
476             lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
477             ret = MCI_RESOURCE_RETURNED;
478             break;
479         case MCI_GETDEVCAPS_CAN_RECORD:
480             TRACE("MCI_GETDEVCAPS_CAN_RECORD !\n");
481             lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
482             ret = MCI_RESOURCE_RETURNED;
483             break;
484         case MCI_GETDEVCAPS_CAN_SAVE:
485             TRACE("MCI_GETDEVCAPS_CAN_SAVE !\n");
486             lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
487             ret = MCI_RESOURCE_RETURNED;
488             break;
489         default:
490             FIXME("Unknown capability (%08lx) !\n", lpParms->dwItem);
491             return MCIERR_UNRECOGNIZED_COMMAND;
492         }
493     } else {
494         WARN("No GetDevCaps-Item !\n");
495         return MCIERR_UNRECOGNIZED_COMMAND;
496     }
497     return ret;
498 }
499
500 /***************************************************************************
501  *                              AVI_mciInfo                     [internal]
502  */
503 static  DWORD   AVI_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_INFO_PARMSA lpParms)
504 {
505     LPSTR               str = 0;
506     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
507     DWORD               ret = 0;
508
509     TRACE("(%04X, %08lX, %p) : stub;\n", wDevID, dwFlags, lpParms);
510     
511     if (lpParms == NULL || lpParms->lpstrReturn == NULL)
512         return MCIERR_NULL_PARAMETER_BLOCK;
513     if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
514
515     TRACE("buf=%p, len=%lu\n", lpParms->lpstrReturn, lpParms->dwRetSize);
516     
517     switch (dwFlags) {
518     case MCI_INFO_PRODUCT:
519         str = "Wine's AVI player";
520         break;
521     case MCI_INFO_FILE:
522         str = "";
523         break;
524 #if 0
525         /* FIXME: the following manifest constants are not defined in <WINE>/include/mmsystem.h */
526     case MCI_INFO_COPYRIGHT:
527         break;
528     case MCI_INFO_NAME:
529         break;
530 #endif
531     default:
532         WARN("Don't know this info command (%lu)\n", dwFlags);
533         return MCIERR_UNRECOGNIZED_COMMAND;
534     }
535     if (str) {
536         if (lpParms->dwRetSize <= strlen(str)) {
537             lstrcpynA(lpParms->lpstrReturn, str, lpParms->dwRetSize - 1);
538             ret = MCIERR_PARAM_OVERFLOW;
539         } else {
540             strcpy(lpParms->lpstrReturn, str);
541         }       
542     } else {
543         *lpParms->lpstrReturn = 0;
544     }
545     return ret;
546 }
547
548 /***************************************************************************
549  *                              AVI_mciPut                      [internal]
550  */
551 static  DWORD   AVI_mciPut(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_PUT_PARMS lpParms)
552 {
553     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
554     RECT                rc;
555     char                buffer[256];
556     
557     TRACE("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
558     
559     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
560     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
561     
562     if (dwFlags & MCI_DGV_RECT) {
563         rc = lpParms->rc;
564     } else {
565         SetRectEmpty(&rc);
566     }
567     
568     *buffer = 0;
569     if (dwFlags & MCI_DGV_PUT_CLIENT) {
570         strncat(buffer, "PUT_CLIENT", sizeof(buffer));
571     }
572     if (dwFlags & MCI_DGV_PUT_DESTINATION) {
573         strncat(buffer, "PUT_DESTINATION", sizeof(buffer));
574     }
575     if (dwFlags & MCI_DGV_PUT_FRAME) {
576         strncat(buffer, "PUT_FRAME", sizeof(buffer));
577     }
578     if (dwFlags & MCI_DGV_PUT_SOURCE) {
579         strncat(buffer, "PUT_SOURCE", sizeof(buffer));
580     }
581     if (dwFlags & MCI_DGV_PUT_VIDEO) {
582         strncat(buffer, "PUT_VIDEO", sizeof(buffer));
583     }
584     if (dwFlags & MCI_DGV_PUT_WINDOW) {
585         strncat(buffer, "PUT_WINDOW", sizeof(buffer));
586     }
587     TRACE("%s (%d,%d,%d,%d)\n", buffer, rc.left, rc.top, rc.right, rc.bottom);
588     
589     return 0;
590 }
591
592 /***************************************************************************
593  *                              AVI_mciWindow                   [internal]
594  */
595 static  DWORD   AVI_mciWindow(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMSA lpParms)
596 {
597     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
598     
599     TRACE("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
600     
601     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
602     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
603     
604     if (dwFlags & MCI_DGV_WINDOW_HWND) {
605         TRACE("Setting hWnd to %08lx\n", (DWORD)lpParms->hWnd);
606     }
607     if (dwFlags & MCI_DGV_WINDOW_STATE) {
608         TRACE("Setting nCmdShow to %d\n", lpParms->nCmdShow);
609     }
610     if (dwFlags & MCI_DGV_WINDOW_TEXT) {
611         TRACE("Setting caption to '%s'\n", lpParms->lpstrText);
612     }
613     
614     return 0;
615 }
616
617 /*****************************************************************************
618  *                              AVI_mciLoad                     [internal]
619  */
620 static DWORD    AVI_mciLoad(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_LOAD_PARMSA lpParms)
621 {
622     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
623     
624     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
625     
626     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
627     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
628     
629     return 0;
630 }
631
632 /******************************************************************************
633  *                              AVI_mciSave                     [internal]
634  */
635 static  DWORD   AVI_mciSave(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_SAVE_PARMSA lpParms)
636 {
637     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
638     
639     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
640     
641     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
642     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
643     
644     return 0;
645 }
646
647 /******************************************************************************
648  *                              AVI_mciFreeze                   [internal]
649  */
650 static  DWORD   AVI_mciFreeze(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
651 {
652     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
653     
654     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
655     
656     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
657     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
658     
659     return 0;
660 }
661
662 /******************************************************************************
663  *                              AVI_mciRealize                  [internal]
664  */
665 static  DWORD   AVI_mciRealize(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
666 {
667     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
668     
669     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
670     
671     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
672     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
673     
674     return 0;
675 }
676
677 /******************************************************************************
678  *                              AVI_mciUnFreeze                 [internal]
679  */
680 static  DWORD   AVI_mciUnFreeze(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
681 {
682     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
683     
684     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
685     
686     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
687     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
688     
689     return 0;
690 }
691
692 /******************************************************************************
693  *                              AVI_mciUpdate                   [internal]
694  */
695 static  DWORD   AVI_mciUpdate(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS lpParms)
696 {
697     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
698     
699     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
700     
701     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
702     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
703     
704     return 0;
705 }
706
707 /******************************************************************************
708  *                              AVI_mciWhere                    [internal]
709  */
710 static  DWORD   AVI_mciWhere(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
711 {
712     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
713     
714     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
715     
716     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
717     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
718     
719     return 0;
720 }
721
722 /******************************************************************************
723  *                              AVI_mciStep                     [internal]
724  */
725 static  DWORD   AVI_mciStep(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_STEP_PARMS lpParms)
726 {
727     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
728     
729     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
730     
731     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
732     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
733     
734     return 0;
735 }
736
737 /******************************************************************************
738  *                              AVI_mciCopy                     [internal]
739  */
740 static  DWORD   AVI_mciCopy(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_COPY_PARMS lpParms)
741 {
742     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
743     
744     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
745     
746     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
747     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
748     
749     return 0;
750 }
751
752 /******************************************************************************
753  *                              AVI_mciCut                      [internal]
754  */
755 static  DWORD   AVI_mciCut(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_CUT_PARMS lpParms)
756 {
757     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
758     
759     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
760     
761     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
762     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
763     
764     return 0;
765 }
766
767 /******************************************************************************
768  *                              AVI_mciDelete                   [internal]
769  */
770 static  DWORD   AVI_mciDelete(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_DELETE_PARMS lpParms)
771 {
772     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
773     
774     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
775     
776     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
777     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
778     
779     return 0;
780 }
781
782 /******************************************************************************
783  *                              AVI_mciPaste                    [internal]
784  */
785 static  DWORD   AVI_mciPaste(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_PASTE_PARMS lpParms)
786 {
787     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
788     
789     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
790     
791     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
792     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
793     
794     return 0;
795 }
796
797 /******************************************************************************
798  *                              AVI_mciCue                      [internal]
799  */
800 static  DWORD   AVI_mciCue(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_CUE_PARMS lpParms)
801 {
802     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
803     
804     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
805     
806     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
807     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
808     
809     return 0;
810 }
811
812 /******************************************************************************
813  *                              AVI_mciCapture                  [internal]
814  */
815 static  DWORD   AVI_mciCapture(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_CAPTURE_PARMSA lpParms)
816 {
817     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
818     
819     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
820     
821     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
822     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
823     
824     return 0;
825 }
826
827 /******************************************************************************
828  *                              AVI_mciMonitor                  [internal]
829  */
830 static  DWORD   AVI_mciMonitor(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_MONITOR_PARMS lpParms)
831 {
832     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
833     
834     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
835     
836     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
837     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
838     
839     return 0;
840 }
841
842 /******************************************************************************
843  *                              AVI_mciReserve                  [internal]
844  */
845 static  DWORD   AVI_mciReserve(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_RESERVE_PARMSA lpParms)
846 {
847     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
848     
849     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
850     
851     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
852     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
853     
854     return 0;
855 }
856
857 /******************************************************************************
858  *                              AVI_mciSetAudio                 [internal]
859  */
860 static  DWORD   AVI_mciSetAudio(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_PARMSA lpParms)
861 {
862     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
863     
864     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
865     
866     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
867     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
868     
869     return 0;
870 }
871
872 /******************************************************************************
873  *                              AVI_mciSignal                   [internal]
874  */
875 static  DWORD   AVI_mciSignal(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_SIGNAL_PARMS lpParms)
876 {
877     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
878     
879     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
880     
881     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
882     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
883     
884     return 0;
885 }
886
887 /******************************************************************************
888  *                              AVI_mciSetVideo                 [internal]
889  */
890 static  DWORD   AVI_mciSetVideo(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_SETVIDEO_PARMSA lpParms)
891 {
892     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
893     
894     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
895     
896     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
897     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
898     
899     return 0;
900 }
901
902 /******************************************************************************
903  *                              AVI_mciQuality                  [internal]
904  */
905 static  DWORD   AVI_mciQuality(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_QUALITY_PARMSA lpParms)
906 {
907     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
908     
909     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
910     
911     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
912     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
913     
914     return 0;
915 }
916
917 /******************************************************************************
918  *                              AVI_mciList                     [internal]
919  */
920 static  DWORD   AVI_mciList(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_LIST_PARMSA lpParms)
921 {
922     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
923     
924     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
925     
926     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
927     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
928     
929     return 0;
930 }
931
932 /******************************************************************************
933  *                              AVI_mciUndo                     [internal]
934  */
935 static  DWORD   AVI_mciUndo(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
936 {
937     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
938     
939     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
940     
941     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
942     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
943     
944     return 0;
945 }
946
947 /******************************************************************************
948  *                              AVI_mciConfigure                        [internal]
949  */
950 static  DWORD   AVI_mciConfigure(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
951 {
952     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
953     
954     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
955     
956     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
957     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
958     
959     return 0;
960 }
961
962 /******************************************************************************
963  *                              AVI_mciRestore                  [internal]
964  */
965 static  DWORD   AVI_mciRestore(UINT16 wDevID, DWORD dwFlags, LPMCI_DGV_RESTORE_PARMSA lpParms)
966 {
967     WINE_MCIAVI*        wma = AVI_mciGetOpenDev(wDevID);
968     
969     TRACE("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
970     
971     if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
972     if (wma == NULL)            return MCIERR_INVALID_DEVICE_ID;
973     
974     return 0;
975 }
976
977 /*======================================================================*
978  *                          MCI AVI entry points                        *
979  *======================================================================*/
980
981 /**************************************************************************
982  *                              MCIAVI_DriverProc       [sample driver]
983  */
984 LONG CALLBACK   MCIAVI_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg, 
985                                   DWORD dwParam1, DWORD dwParam2)
986 {
987     switch (wMsg) {
988     case DRV_LOAD:              return 1;
989     case DRV_FREE:              return 1;
990     case DRV_OPEN:              return AVI_drvOpen((LPSTR)dwParam1, (LPMCI_OPEN_DRIVER_PARMSA)dwParam2);
991     case DRV_CLOSE:             return AVI_drvClose(dwDevID);
992     case DRV_ENABLE:            return 1;
993     case DRV_DISABLE:           return 1;
994     case DRV_QUERYCONFIGURE:    return 1;
995     case DRV_CONFIGURE:         MessageBoxA(0, "Sample AVI Wine Driver !", "MM-Wine Driver", MB_OK); return 1;
996     case DRV_INSTALL:           return DRVCNF_RESTART;
997     case DRV_REMOVE:            return DRVCNF_RESTART;
998         
999     case MCI_OPEN_DRIVER:       return AVI_mciOpen      (dwDevID, dwParam1, (LPMCI_DGV_OPEN_PARMSA)     dwParam2);
1000     case MCI_CLOSE_DRIVER:      return AVI_mciClose     (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)       dwParam2);
1001     case MCI_PLAY:              return AVI_mciPlay      (dwDevID, dwParam1, (LPMCI_PLAY_PARMS)          dwParam2);
1002     case MCI_RECORD:            return AVI_mciRecord    (dwDevID, dwParam1, (LPMCI_DGV_RECORD_PARMS)    dwParam2);
1003     case MCI_STOP:              return AVI_mciStop      (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)       dwParam2);
1004     case MCI_SET:               return AVI_mciSet       (dwDevID, dwParam1, (LPMCI_DGV_SET_PARMS)       dwParam2);
1005     case MCI_PAUSE:             return AVI_mciPause     (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)       dwParam2);
1006     case MCI_RESUME:            return AVI_mciResume    (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)       dwParam2);
1007     case MCI_STATUS:            return AVI_mciStatus    (dwDevID, dwParam1, (LPMCI_DGV_STATUS_PARMSA)   dwParam2);
1008     case MCI_GETDEVCAPS:        return AVI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)    dwParam2);
1009     case MCI_INFO:              return AVI_mciInfo      (dwDevID, dwParam1, (LPMCI_DGV_INFO_PARMSA)     dwParam2);
1010     case MCI_SEEK:              return AVI_mciSeek      (dwDevID, dwParam1, (LPMCI_SEEK_PARMS)          dwParam2);
1011     case MCI_PUT:               return AVI_mciPut       (dwDevID, dwParam1, (LPMCI_DGV_PUT_PARMS)       dwParam2);              
1012     case MCI_WINDOW:            return AVI_mciWindow    (dwDevID, dwParam1, (LPMCI_DGV_WINDOW_PARMSA)   dwParam2);              
1013     case MCI_LOAD:              return AVI_mciLoad      (dwDevID, dwParam1, (LPMCI_DGV_LOAD_PARMSA)     dwParam2);              
1014     case MCI_SAVE:              return AVI_mciSave      (dwDevID, dwParam1, (LPMCI_DGV_SAVE_PARMSA)     dwParam2);              
1015     case MCI_FREEZE:            return AVI_mciFreeze    (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS)      dwParam2);
1016     case MCI_REALIZE:           return AVI_mciRealize   (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)       dwParam2);
1017     case MCI_UNFREEZE:          return AVI_mciUnFreeze  (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS)      dwParam2);
1018     case MCI_UPDATE:            return AVI_mciUpdate    (dwDevID, dwParam1, (LPMCI_DGV_UPDATE_PARMS)    dwParam2);
1019     case MCI_WHERE:             return AVI_mciWhere     (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS)      dwParam2);
1020     case MCI_STEP:              return AVI_mciStep      (dwDevID, dwParam1, (LPMCI_DGV_STEP_PARMS)      dwParam2);
1021     case MCI_COPY:              return AVI_mciCopy      (dwDevID, dwParam1, (LPMCI_DGV_COPY_PARMS)      dwParam2);              
1022     case MCI_CUT:               return AVI_mciCut       (dwDevID, dwParam1, (LPMCI_DGV_CUT_PARMS)       dwParam2);              
1023     case MCI_DELETE:            return AVI_mciDelete    (dwDevID, dwParam1, (LPMCI_DGV_DELETE_PARMS)    dwParam2);                              
1024     case MCI_PASTE:             return AVI_mciPaste     (dwDevID, dwParam1, (LPMCI_DGV_PASTE_PARMS)     dwParam2);                              
1025     case MCI_CUE:               return AVI_mciCue       (dwDevID, dwParam1, (LPMCI_DGV_CUE_PARMS)       dwParam2);
1026         /* Digital Video specific */    
1027     case MCI_CAPTURE:           return AVI_mciCapture   (dwDevID, dwParam1, (LPMCI_DGV_CAPTURE_PARMSA)  dwParam2);
1028     case MCI_MONITOR:           return AVI_mciMonitor   (dwDevID, dwParam1, (LPMCI_DGV_MONITOR_PARMS)   dwParam2);
1029     case MCI_RESERVE:           return AVI_mciReserve   (dwDevID, dwParam1, (LPMCI_DGV_RESERVE_PARMSA)  dwParam2);
1030     case MCI_SETAUDIO:          return AVI_mciSetAudio  (dwDevID, dwParam1, (LPMCI_DGV_SETAUDIO_PARMSA) dwParam2);
1031     case MCI_SIGNAL:            return AVI_mciSignal    (dwDevID, dwParam1, (LPMCI_DGV_SIGNAL_PARMS)    dwParam2);
1032     case MCI_SETVIDEO:          return AVI_mciSetVideo  (dwDevID, dwParam1, (LPMCI_DGV_SETVIDEO_PARMSA) dwParam2);
1033     case MCI_QUALITY:           return AVI_mciQuality   (dwDevID, dwParam1, (LPMCI_DGV_QUALITY_PARMSA)  dwParam2);
1034     case MCI_LIST:              return AVI_mciList      (dwDevID, dwParam1, (LPMCI_DGV_LIST_PARMSA)     dwParam2);
1035     case MCI_UNDO:              return AVI_mciUndo      (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)       dwParam2);
1036     case MCI_CONFIGURE:         return AVI_mciConfigure (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)       dwParam2);
1037     case MCI_RESTORE:           return AVI_mciRestore   (dwDevID, dwParam1, (LPMCI_DGV_RESTORE_PARMSA)  dwParam2);
1038         
1039     case MCI_SPIN:
1040     case MCI_ESCAPE:            
1041         WARN("Unsupported command [%lu]\n", wMsg);
1042         break;
1043     case MCI_OPEN:
1044     case MCI_CLOSE:
1045         FIXME("Shouldn't receive a MCI_OPEN or CLOSE message\n");
1046         break;
1047     default:                    
1048         TRACE("Sending msg [%lu] to default driver proc\n", wMsg);
1049         return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1050     }
1051     return MCIERR_UNRECOGNIZED_COMMAND;
1052 }
1053
1054