Keep track of per-column information inside the listview.
[wine] / dlls / avifil32 / api.c
1 /*
2  * Copyright 1999 Marcus Meissner
3  * Copyright 2002 Michael Günnewig
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include <assert.h>
21
22 #include "winbase.h"
23 #include "winnls.h"
24 #include "winuser.h"
25 #include "winreg.h"
26 #include "winerror.h"
27 #include "windowsx.h"
28
29 #include "ole2.h"
30 #include "shellapi.h"
31 #include "vfw.h"
32
33 #include "avifile_private.h"
34
35 #include "wine/debug.h"
36 #include "wine/unicode.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(avifile);
39
40 /***********************************************************************
41  * copied from dlls/shell32/undocshell.h
42  */
43 HRESULT WINAPI SHCoCreateInstance(LPCSTR lpszClsid,REFCLSID rClsid,
44                                   LPUNKNOWN pUnkOuter,REFIID riid,LPVOID *ppv);
45
46 /***********************************************************************
47  * copied from dlls/ole32/compobj.c
48  */
49 static HRESULT AVIFILE_CLSIDFromString(LPCSTR idstr, LPCLSID id)
50 {
51   BYTE *s = (BYTE*)idstr;
52   BYTE *p;
53   INT   i;
54   BYTE table[256];
55
56   if (!s) {
57     memset(s, 0, sizeof(CLSID));
58     return S_OK;
59   } else {  /* validate the CLSID string */
60     if (lstrlenA(s) != 38)
61       return CO_E_CLASSSTRING;
62
63     if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') ||
64         (s[24]!='-') || (s[37]!='}'))
65       return CO_E_CLASSSTRING;
66
67     for (i = 1; i < 37; i++) {
68       if ((i == 9) || (i == 14) || (i == 19) || (i == 24))
69         continue;
70       if (!(((s[i] >= '0') && (s[i] <= '9'))  ||
71             ((s[i] >= 'a') && (s[i] <= 'f'))  ||
72             ((s[i] >= 'A') && (s[i] <= 'F')))
73           )
74         return CO_E_CLASSSTRING;
75     }
76   }
77
78   TRACE("%s -> %p\n", s, id);
79
80   /* quick lookup table */
81   memset(table, 0, 256);
82
83   for (i = 0; i < 10; i++)
84     table['0' + i] = i;
85
86   for (i = 0; i < 6; i++) {
87     table['A' + i] = i+10;
88     table['a' + i] = i+10;
89   }
90
91   /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
92   p = (BYTE *) id;
93
94   s++;  /* skip leading brace  */
95   for (i = 0; i < 4; i++) {
96     p[3 - i] = table[*s]<<4 | table[*(s+1)];
97     s += 2;
98   }
99   p += 4;
100   s++;  /* skip - */
101
102   for (i = 0; i < 2; i++) {
103     p[1-i] = table[*s]<<4 | table[*(s+1)];
104     s += 2;
105   }
106   p += 2;
107   s++;  /* skip - */
108
109   for (i = 0; i < 2; i++) {
110     p[1-i] = table[*s]<<4 | table[*(s+1)];
111     s += 2;
112   }
113   p += 2;
114   s++;  /* skip - */
115
116   /* these are just sequential bytes */
117   for (i = 0; i < 2; i++) {
118     *p++ = table[*s]<<4 | table[*(s+1)];
119     s += 2;
120   }
121   s++;  /* skip - */
122
123   for (i = 0; i < 6; i++) {
124     *p++ = table[*s]<<4 | table[*(s+1)];
125     s += 2;
126   }
127
128   return S_OK;
129 }
130
131 static BOOL AVIFILE_GetFileHandlerByExtension(LPCWSTR szFile, LPCLSID lpclsid)
132 {
133   CHAR   szRegKey[25];
134   CHAR   szValue[100];
135   LPWSTR szExt = strrchrW(szFile, '.');
136   LONG   len = sizeof(szValue) / sizeof(szValue[0]);
137
138   if (szExt == NULL)
139     return FALSE;
140
141   szExt++;
142
143   wsprintfA(szRegKey, "AVIFile\\Extensions\\%.3ls", szExt);
144   if (RegQueryValueA(HKEY_CLASSES_ROOT, szRegKey, szValue, &len) != ERROR_SUCCESS)
145     return FALSE;
146
147   return (AVIFILE_CLSIDFromString(szValue, lpclsid) == S_OK);
148 }
149
150 /***********************************************************************
151  *              AVIFileInit             (AVIFIL32.@)
152  *              AVIFileInit             (AVIFILE.100)
153  */
154 void WINAPI AVIFileInit(void) {
155   /* need to load ole32.dll if not already done and get some functions */
156   FIXME("(): stub!\n");
157 }
158
159 /***********************************************************************
160  *              AVIFileExit             (AVIFIL32.@)
161  *              AVIFileExit             (AVIFILE.101)
162  */
163 void WINAPI AVIFileExit(void) {
164   /* need to free ole32.dll if we are the last exit call */
165   FIXME("(): stub!\n");
166 }
167
168 /***********************************************************************
169  *              AVIFileOpenA            (AVIFIL32.@)
170  *              AVIFileOpenA            (AVIFILE.102)
171  */
172 HRESULT WINAPI AVIFileOpenA(PAVIFILE *ppfile, LPCSTR szFile, UINT uMode,
173                             LPCLSID lpHandler)
174 {
175   LPWSTR  wszFile = NULL;
176   HRESULT hr;
177   int     len;
178
179   TRACE("(%p,%s,0x%08X,%s)\n", ppfile, debugstr_a(szFile), uMode,
180         debugstr_guid(lpHandler));
181
182   /* check parameters */
183   if (ppfile == NULL || szFile == NULL)
184     return AVIERR_BADPARAM;
185
186   /* convert ASCII string to Unicode and call unicode function */
187   len = lstrlenA(szFile);
188   if (len <= 0)
189     return AVIERR_BADPARAM;
190
191   wszFile = (LPWSTR)LocalAlloc(LPTR, (len + 1) * sizeof(WCHAR));
192   if (wszFile == NULL)
193     return AVIERR_MEMORY;
194
195   MultiByteToWideChar(CP_ACP, 0, szFile, -1, wszFile, len + 1);
196   wszFile[len + 1] = 0;
197
198   hr = AVIFileOpenW(ppfile, wszFile, uMode, lpHandler);
199
200   LocalFree((HLOCAL)wszFile);
201
202   return hr;
203 }
204
205 /***********************************************************************
206  *              AVIFileOpenW            (AVIFIL32.@)
207  */
208 HRESULT WINAPI AVIFileOpenW(PAVIFILE *ppfile, LPCWSTR szFile, UINT uMode,
209                             LPCLSID lpHandler)
210 {
211   IPersistFile *ppersist = NULL;
212   CLSID         clsidHandler;
213   HRESULT       hr;
214
215   TRACE("(%p,%s,0x%X,%s)\n", ppfile, debugstr_w(szFile), uMode,
216         debugstr_guid(lpHandler));
217
218   /* check parameters */
219   if (ppfile == NULL || szFile == NULL)
220     return AVIERR_BADPARAM;
221
222   *ppfile = NULL;
223
224   /* if no handler then try guessing it by extension */
225   if (lpHandler == NULL) {
226     if (! AVIFILE_GetFileHandlerByExtension(szFile, &clsidHandler))
227       return AVIERR_UNSUPPORTED;
228   } else
229     memcpy(&clsidHandler, lpHandler, sizeof(clsidHandler));
230
231   /* crete instance of handler */
232   hr = SHCoCreateInstance(NULL, &clsidHandler, NULL,
233                           &IID_IAVIFile, (LPVOID*)ppfile);
234   if (FAILED(hr) || *ppfile == NULL)
235     return hr;
236
237   /* ask for IPersistFile interface for loading/creating the file */
238   hr = IAVIFile_QueryInterface(*ppfile, &IID_IPersistFile, (LPVOID*)&ppersist);
239   if (FAILED(hr) || ppersist == NULL) {
240     IAVIFile_Release(*ppfile);
241     *ppfile = NULL;
242     return hr;
243   }
244
245   hr = IPersistFile_Load(ppersist, szFile, uMode);
246   IPersistFile_Release(ppersist);
247   if (FAILED(hr)) {
248     IAVIFile_Release(*ppfile);
249     *ppfile = NULL;
250   }
251
252   return hr;
253 }
254
255 /***********************************************************************
256  *              AVIFileAddRef           (AVIFIL32.@)
257  *              AVIFileAddRef           (AVIFILE.140)
258  */
259 ULONG WINAPI AVIFileAddRef(PAVIFILE pfile)
260 {
261   TRACE("(%p)\n", pfile);
262
263   if (pfile == NULL) {
264     ERR(": bad handle passed!\n");
265     return 0;
266   }
267
268   return IAVIFile_AddRef(pfile);
269 }
270
271 /***********************************************************************
272  *              AVIFileRelease          (AVIFIL32.@)
273  *              AVIFileRelease          (AVIFILE.141)
274  */
275 ULONG WINAPI AVIFileRelease(PAVIFILE pfile)
276 {
277   TRACE("(%p)\n", pfile);
278
279   if (pfile == NULL) {
280     ERR(": bad handle passed!\n");
281     return 0;
282   }
283
284   return IAVIFile_Release(pfile);
285 }
286
287 /***********************************************************************
288  *              AVIFileInfoA            (AVIFIL32.@)
289  */
290 HRESULT WINAPI AVIFileInfoA(PAVIFILE pfile, LPAVIFILEINFOA afi, LONG size)
291 {
292   AVIFILEINFOW afiw;
293   HRESULT      hres;
294
295   TRACE("(%p,%p,%ld)\n", pfile, afi, size);
296
297   if (pfile == NULL)
298     return AVIERR_BADHANDLE;
299   if (size < sizeof(AVIFILEINFOA))
300     return AVIERR_BADSIZE;
301
302   hres = IAVIFile_Info(pfile, &afiw, sizeof(afiw));
303
304   memcpy(afi, &afiw, sizeof(*afi) - sizeof(afi->szFileType));
305   WideCharToMultiByte(CP_ACP, 0, afiw.szFileType, -1, afi->szFileType,
306                       sizeof(afi->szFileType), NULL, NULL);
307   afi->szFileType[sizeof(afi->szFileType) - 1] = 0;
308
309   return hres;
310 }
311
312 /***********************************************************************
313  *              AVIFileInfoW            (AVIFIL32.@)
314  */
315 HRESULT WINAPI AVIFileInfoW(PAVIFILE pfile, LPAVIFILEINFOW afiw, LONG size)
316 {
317   TRACE("(%p,%p,%ld)\n", pfile, afiw, size);
318
319   if (pfile == NULL)
320     return AVIERR_BADHANDLE;
321
322   return IAVIFile_Info(pfile, afiw, size);
323 }
324
325 /***********************************************************************
326  *              AVIFileGetStream        (AVIFIL32.@)
327  *              AVIFileGetStream        (AVIFILE.143)
328  */
329 HRESULT WINAPI AVIFileGetStream(PAVIFILE pfile, PAVISTREAM *avis,
330                                 DWORD fccType, LONG lParam)
331 {
332   TRACE("(%p,%p,'%4.4s',%ld)\n", pfile, avis, (char*)&fccType, lParam);
333
334   if (pfile == NULL)
335     return AVIERR_BADHANDLE;
336
337   return IAVIFile_GetStream(pfile, avis, fccType, lParam);
338 }
339
340 /***********************************************************************
341  *              AVIFileCreateStreamA    (AVIFIL32.@)
342  */
343 HRESULT WINAPI AVIFileCreateStreamA(PAVIFILE pfile, PAVISTREAM *ppavi,
344                                     LPAVISTREAMINFOA psi)
345 {
346   AVISTREAMINFOW        psiw;
347
348   TRACE("(%p,%p,%p)\n", pfile, ppavi, psi);
349
350   if (pfile == NULL)
351     return AVIERR_BADHANDLE;
352
353   /* Only the szName at the end is different */
354   memcpy(&psiw, psi, sizeof(*psi) - sizeof(psi->szName));
355   MultiByteToWideChar(CP_ACP, 0, psi->szName, -1, psiw.szName,
356                       sizeof(psiw.szName) / sizeof(psiw.szName[0]));
357
358   return IAVIFile_CreateStream(pfile, ppavi, &psiw);
359 }
360
361 /***********************************************************************
362  *              AVIFileCreateStreamW    (AVIFIL32.@)
363  */
364 HRESULT WINAPI AVIFileCreateStreamW(PAVIFILE pfile, PAVISTREAM *avis,
365                                     LPAVISTREAMINFOW asi)
366 {
367   TRACE("(%p,%p,%p)\n", pfile, avis, asi);
368
369   return IAVIFile_CreateStream(pfile, avis, asi);
370 }
371
372 /***********************************************************************
373  *              AVIFileWriteData        (AVIFIL32.@)
374  */
375 HRESULT WINAPI AVIFileWriteData(PAVIFILE pfile,DWORD fcc,LPVOID lp,LONG size)
376 {
377   TRACE("(%p,'%4.4s',%p,%ld)\n", pfile, (char*)&fcc, lp, size);
378
379   if (pfile == NULL)
380     return AVIERR_BADHANDLE;
381
382   return IAVIFile_WriteData(pfile, fcc, lp, size);
383 }
384
385 /***********************************************************************
386  *              AVIFileReadData         (AVIFIL32.@)
387  */
388 HRESULT WINAPI AVIFileReadData(PAVIFILE pfile,DWORD fcc,LPVOID lp,LPLONG size)
389 {
390   TRACE("(%p,'%4.4s',%p,%p)\n", pfile, (char*)&fcc, lp, size);
391
392   if (pfile == NULL)
393     return AVIERR_BADHANDLE;
394
395   return IAVIFile_ReadData(pfile, fcc, lp, size);
396 }
397
398 /***********************************************************************
399  *              AVIFileEndRecord        (AVIFIL32.@)
400  */
401 HRESULT WINAPI AVIFileEndRecord(PAVIFILE pfile)
402 {
403   TRACE("(%p)\n", pfile);
404
405   if (pfile == NULL)
406     return AVIERR_BADHANDLE;
407
408   return IAVIFile_EndRecord(pfile);
409 }
410
411 /***********************************************************************
412  *              AVIStreamAddRef         (AVIFIL32.@)
413  */
414 ULONG WINAPI AVIStreamAddRef(PAVISTREAM pstream)
415 {
416   TRACE("(%p)\n", pstream);
417
418   if (pstream == NULL) {
419     ERR(": bad handle passed!\n");
420     return 0;
421   }
422
423   return IAVIStream_AddRef(pstream);
424 }
425
426 /***********************************************************************
427  *              AVIStreamRelease        (AVIFIL32.@)
428  */
429 ULONG WINAPI AVIStreamRelease(PAVISTREAM pstream)
430 {
431   TRACE("(%p)\n", pstream);
432
433   if (pstream == NULL) {
434     ERR(": bad handle passed!\n");
435     return 0;
436   }
437
438   return IAVIStream_Release(pstream);
439 }
440
441 HRESULT WINAPI AVIStreamCreate(PAVISTREAM *ppavi, LONG lParam1, LONG lParam2,
442                                LPCLSID pclsidHandler)
443 {
444   HRESULT hr;
445
446   TRACE("(%p,0x%08lX,0x%08lX,%s)\n", ppavi, lParam1, lParam2,
447         debugstr_guid(pclsidHandler));
448
449   if (ppavi == NULL)
450     return AVIERR_BADPARAM;
451
452   *ppavi = NULL;
453   if (pclsidHandler == NULL)
454     return AVIERR_UNSUPPORTED;
455
456   hr = SHCoCreateInstance(NULL, pclsidHandler, NULL,
457                           &IID_IAVIStream, (LPVOID*)ppavi);
458   if (FAILED(hr) || *ppavi == NULL)
459     return hr;
460
461   hr = IAVIStream_Create(*ppavi, lParam1, lParam2);
462   if (FAILED(hr)) {
463     IAVIStream_Release(*ppavi);
464     *ppavi = NULL;
465   }
466
467   return hr;
468 }
469
470 /***********************************************************************
471  *              AVIStreamInfoA          (AVIFIL32.@)
472  */
473 HRESULT WINAPI AVIStreamInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi,
474                               LONG size)
475 {
476   AVISTREAMINFOW asiw;
477   HRESULT        hres;
478
479   TRACE("(%p,%p,%ld)\n", pstream, asi, size);
480
481   if (pstream == NULL)
482     return AVIERR_BADHANDLE;
483   if (size < sizeof(AVISTREAMINFOA))
484     return AVIERR_BADSIZE;
485
486   hres = IAVIStream_Info(pstream, &asiw, sizeof(asiw));
487
488   memcpy(asi, &asiw, sizeof(asiw) - sizeof(asiw.szName));
489   WideCharToMultiByte(CP_ACP, 0, asiw.szName, -1, asi->szName,
490                       sizeof(asi->szName), NULL, NULL);
491   asi->szName[sizeof(asi->szName) - 1] = 0;
492
493   return hres;
494 }
495
496 /***********************************************************************
497  *              AVIStreamInfoW          (AVIFIL32.@)
498  */
499 HRESULT WINAPI AVIStreamInfoW(PAVISTREAM pstream, LPAVISTREAMINFOW asi,
500                               LONG size)
501 {
502   TRACE("(%p,%p,%ld)\n", pstream, asi, size);
503
504   if (pstream == NULL)
505     return AVIERR_BADHANDLE;
506
507   return IAVIStream_Info(pstream, asi, size);
508 }
509
510 /***********************************************************************
511  *              AVIStreamFindSample     (AVIFIL32.@)
512  */
513 HRESULT WINAPI AVIStreamFindSample(PAVISTREAM pstream, LONG pos, DWORD flags)
514 {
515   TRACE("(%p,%ld,0x%lX)\n", pstream, pos, flags);
516
517   if (pstream == NULL)
518     return -1;
519
520   return IAVIStream_FindSample(pstream, pos, flags);
521 }
522
523 /***********************************************************************
524  *              AVIStreamReadFormat     (AVIFIL32.@)
525  */
526 HRESULT WINAPI AVIStreamReadFormat(PAVISTREAM pstream, LONG pos,
527                                    LPVOID format, LPLONG formatsize)
528 {
529   TRACE("(%p,%ld,%p,%p)\n", pstream, pos, format, formatsize);
530
531   if (pstream == NULL)
532     return AVIERR_BADHANDLE;
533
534   return IAVIStream_ReadFormat(pstream, pos, format, formatsize);
535 }
536
537 /***********************************************************************
538  *              AVIStreamSetFormat      (AVIFIL32.@)
539  */
540 HRESULT WINAPI AVIStreamSetFormat(PAVISTREAM pstream, LONG pos,
541                                   LPVOID format, LONG formatsize)
542 {
543   TRACE("(%p,%ld,%p,%ld)\n", pstream, pos, format, formatsize);
544
545   if (pstream == NULL)
546     return AVIERR_BADHANDLE;
547
548   return IAVIStream_SetFormat(pstream, pos, format, formatsize);
549 }
550
551 /***********************************************************************
552  *              AVIStreamRead           (AVIFIL32.@)
553  */
554 HRESULT WINAPI AVIStreamRead(PAVISTREAM pstream, LONG start, LONG samples,
555                              LPVOID buffer, LONG buffersize,
556                              LPLONG bytesread, LPLONG samplesread)
557 {
558   TRACE("(%p,%ld,%ld,%p,%ld,%p,%p)\n", pstream, start, samples, buffer,
559         buffersize, bytesread, samplesread);
560
561   if (pstream == NULL)
562     return AVIERR_BADHANDLE;
563
564   return IAVIStream_Read(pstream, start, samples, buffer, buffersize,
565                          bytesread, samplesread);
566 }
567
568 /***********************************************************************
569  *              AVIStreamWrite          (AVIFIL32.@)
570  */
571 HRESULT WINAPI AVIStreamWrite(PAVISTREAM pstream, LONG start, LONG samples,
572                               LPVOID buffer, LONG buffersize, DWORD flags,
573                               LPLONG sampwritten, LPLONG byteswritten)
574 {
575   TRACE("(%p,%ld,%ld,%p,%ld,0x%lX,%p,%p)\n", pstream, start, samples, buffer,
576         buffersize, flags, sampwritten, byteswritten);
577
578   if (pstream == NULL)
579     return AVIERR_BADHANDLE;
580
581   return IAVIStream_Write(pstream, start, samples, buffer, buffersize,
582                           flags, sampwritten, byteswritten);
583 }
584
585 /***********************************************************************
586  *              AVIStreamReadData       (AVIFIL32.@)
587  */
588 HRESULT WINAPI AVIStreamReadData(PAVISTREAM pstream, DWORD fcc, LPVOID lp,
589                                  LPLONG lpread)
590 {
591   TRACE("(%p,'%4.4s',%p,%p)\n", pstream, (char*)&fcc, lp, lpread);
592
593   if (pstream == NULL)
594     return AVIERR_BADHANDLE;
595
596   return IAVIStream_ReadData(pstream, fcc, lp, lpread);
597 }
598
599 /***********************************************************************
600  *              AVIStreamWriteData      (AVIFIL32.@)
601  */
602 HRESULT WINAPI AVIStreamWriteData(PAVISTREAM pstream, DWORD fcc, LPVOID lp,
603                                   LONG size)
604 {
605   TRACE("(%p,'%4.4s',%p,%ld)\n", pstream, (char*)&fcc, lp, size);
606
607   if (pstream == NULL)
608     return AVIERR_BADHANDLE;
609
610   return IAVIStream_WriteData(pstream, fcc, lp, size);
611 }
612
613 /***********************************************************************
614  *              AVIStreamGetFrameOpen   (AVIFIL32.@)
615  */
616 PGETFRAME WINAPI AVIStreamGetFrameOpen(PAVISTREAM pstream,
617                                        LPBITMAPINFOHEADER lpbiWanted)
618 {
619   PGETFRAME pg = NULL;
620
621   TRACE("(%p,%p)\n", pstream, lpbiWanted);
622
623   if (FAILED(IAVIStream_QueryInterface(pstream, &IID_IGetFrame, (LPVOID*)&pg)) ||
624       pg == NULL) {
625     pg = AVIFILE_CreateGetFrame(pstream);
626     if (pg == NULL)
627       return NULL;
628   }
629
630   if (FAILED(IGetFrame_SetFormat(pg, lpbiWanted, NULL, 0, 0, -1, -1))) {
631     IGetFrame_Release(pg);
632     return NULL;
633   }
634
635   return pg;
636 }
637
638 /***********************************************************************
639  *              AVIStreamGetFrame       (AVIFIL32.@)
640  */
641 LPVOID WINAPI AVIStreamGetFrame(PGETFRAME pg, LONG pos)
642 {
643   TRACE("(%p,%ld)\n", pg, pos);
644
645   if (pg == NULL)
646     return NULL;
647
648   return IGetFrame_GetFrame(pg, pos);
649 }
650
651 /***********************************************************************
652  *              AVIStreamGetFrameClose (AVIFIL32.@)
653  */
654 HRESULT WINAPI AVIStreamGetFrameClose(PGETFRAME pg)
655 {
656   TRACE("(%p)\n", pg);
657
658   if (pg != NULL)
659     return IGetFrame_Release(pg);
660   return 0;
661 }
662
663 /***********************************************************************
664  *              AVIMakeCompressedStream (AVIFIL32.@)
665  */
666 HRESULT WINAPI AVIMakeCompressedStream(PAVISTREAM *ppsCompressed,
667                                        PAVISTREAM psSource,
668                                        LPAVICOMPRESSOPTIONS aco,
669                                        LPCLSID pclsidHandler)
670 {
671   AVISTREAMINFOW asiw;
672   CHAR           szRegKey[25];
673   CHAR           szValue[100];
674   CLSID          clsidHandler;
675   HRESULT        hr;
676   LONG           size = sizeof(szValue);
677
678   TRACE("(%p,%p,%p,%s)\n", ppsCompressed, psSource, aco,
679         debugstr_guid(pclsidHandler));
680
681   if (ppsCompressed == NULL)
682     return AVIERR_BADPARAM;
683   if (psSource == NULL)
684     return AVIERR_BADHANDLE;
685
686   *ppsCompressed = NULL;
687
688   /* if no handler given get default ones based on streamtype */
689   if (pclsidHandler == NULL) {
690     hr = IAVIStream_Info(psSource, &asiw, sizeof(asiw));
691     if (FAILED(hr))
692       return hr;
693
694     wsprintfA(szRegKey, "AVIFile\\Compressors\\%4.4s", (char*)&asiw.fccHandler);
695     if (RegQueryValueA(HKEY_CLASSES_ROOT, szRegKey, szValue, &size) != ERROR_SUCCESS)
696       return AVIERR_UNSUPPORTED;
697     if (AVIFILE_CLSIDFromString(szValue, &clsidHandler) != S_OK)
698       return AVIERR_UNSUPPORTED;
699   } else
700     memcpy(&clsidHandler, pclsidHandler, sizeof(clsidHandler));
701
702   hr = SHCoCreateInstance(NULL, &clsidHandler, NULL,
703                           &IID_IAVIStream, (LPVOID*)ppsCompressed);
704   if (FAILED(hr) || *ppsCompressed == NULL)
705     return hr;
706
707   hr = IAVIStream_Create(*ppsCompressed, (LPARAM)psSource, (LPARAM)aco);
708   if (FAILED(hr)) {
709     IAVIStream_Release(*ppsCompressed);
710     *ppsCompressed = NULL;
711   }
712
713   return hr;
714 }
715
716 /***********************************************************************
717  *              AVIStreamOpenFromFileA  (AVIFIL32.@)
718  */
719 HRESULT WINAPI AVIStreamOpenFromFileA(PAVISTREAM *ppavi, LPCSTR szFile,
720                                       DWORD fccType, LONG lParam,
721                                       UINT mode, LPCLSID pclsidHandler)
722 {
723   PAVIFILE pfile = NULL;
724   HRESULT  hr;
725
726   TRACE("(%p,%s,'%4.4s',%ld,0x%X,%s)\n", ppavi, debugstr_a(szFile),
727         (char*)&fccType, lParam, mode, debugstr_guid(pclsidHandler));
728
729   if (ppavi == NULL || szFile == NULL)
730     return AVIERR_BADPARAM;
731
732   *ppavi = NULL;
733
734   hr = AVIFileOpenA(&pfile, szFile, mode, pclsidHandler);
735   if (FAILED(hr) || pfile == NULL)
736     return hr;
737
738   hr = IAVIFile_GetStream(pfile, ppavi, fccType, lParam);
739   IAVIFile_Release(pfile);
740
741   return hr;
742 }
743
744 /***********************************************************************
745  *              AVIStreamOpenFromFileW  (AVIFIL32.@)
746  */
747 HRESULT WINAPI AVIStreamOpenFromFileW(PAVISTREAM *ppavi, LPCWSTR szFile,
748                                       DWORD fccType, LONG lParam,
749                                       UINT mode, LPCLSID pclsidHandler)
750 {
751   PAVIFILE pfile = NULL;
752   HRESULT  hr;
753
754   TRACE("(%p,%s,'%4.4s',%ld,0x%X,%s)\n", ppavi, debugstr_w(szFile),
755         (char*)&fccType, lParam, mode, debugstr_guid(pclsidHandler));
756
757   if (ppavi == NULL || szFile == NULL)
758     return AVIERR_BADPARAM;
759
760   *ppavi = NULL;
761
762   hr = AVIFileOpenW(&pfile, szFile, mode, pclsidHandler);
763   if (FAILED(hr) || pfile == NULL)
764     return hr;
765
766   hr = IAVIFile_GetStream(pfile, ppavi, fccType, lParam);
767   IAVIFile_Release(pfile);
768
769   return hr;
770 }
771
772 /***********************************************************************
773  *              AVIStreamStart          (AVIFIL32.@)
774  */
775 LONG WINAPI AVIStreamStart(PAVISTREAM pstream)
776 {
777   AVISTREAMINFOW asiw;
778
779   TRACE("(%p)\n", pstream);
780
781   if (pstream == NULL)
782     return 0;
783
784   if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
785     return 0;
786
787   return asiw.dwStart;
788 }
789
790 /***********************************************************************
791  *              AVIStreamLength         (AVIFIL32.@)
792  */
793 LONG WINAPI AVIStreamLength(PAVISTREAM pstream)
794 {
795   AVISTREAMINFOW asiw;
796
797   TRACE("(%p)\n", pstream);
798
799   if (pstream == NULL)
800     return 0;
801
802   if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
803     return 0;
804
805   return asiw.dwLength;
806 }
807
808 /***********************************************************************
809  *              AVIStreamSampleToTime   (AVIFIL32.@)
810  */
811 LONG WINAPI AVIStreamSampleToTime(PAVISTREAM pstream, LONG lSample)
812 {
813   AVISTREAMINFOW asiw;
814
815   TRACE("(%p,%ld)\n", pstream, lSample);
816
817   if (pstream == NULL)
818     return -1;
819
820   if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
821     return -1;
822   if (asiw.dwRate == 0)
823     return -1;
824
825   return (LONG)(((float)lSample * asiw.dwScale * 1000.0) / asiw.dwRate);
826 }
827
828 /***********************************************************************
829  *              AVIStreamTimeToSample   (AVIFIL32.@)
830  */
831 LONG WINAPI AVIStreamTimeToSample(PAVISTREAM pstream, LONG lTime)
832 {
833   AVISTREAMINFOW asiw;
834
835   TRACE("(%p,%ld)\n", pstream, lTime);
836
837   if (pstream == NULL)
838     return -1;
839
840   if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
841     return -1;
842   if (asiw.dwScale == 0)
843     return -1;
844
845   return (LONG)(((float)lTime * asiw.dwRate) / asiw.dwScale / 1000.0);
846 }
847
848 /***********************************************************************
849  *              AVIBuildFilterA         (AVIFIL32.@)
850  */
851 HRESULT WINAPI AVIBuildFilterA(LPSTR szFilter, LONG cbFilter, BOOL fSaving)
852 {
853   FIXME("(%p,%ld,%d): stub\n", szFilter, cbFilter, fSaving);
854
855   /* check parameters */
856   if (szFilter == NULL)
857     return AVIERR_BADPARAM;
858   if (cbFilter < 2)
859     return AVIERR_BADSIZE;
860
861   szFilter[0] = 0;
862   szFilter[1] = 0;
863
864   return AVIERR_UNSUPPORTED;
865 }
866
867 /***********************************************************************
868  *              AVIBuildFilterW         (AVIFIL32.@)
869  */
870 HRESULT WINAPI AVIBuildFilterW(LPWSTR szFilter, LONG cbFilter, BOOL fSaving)
871 {
872   FIXME("(%p,%ld,%d): stub\n", szFilter, cbFilter, fSaving);
873
874   /* check parameters */
875   if (szFilter == NULL)
876     return AVIERR_BADPARAM;
877   if (cbFilter < 2)
878     return AVIERR_BADSIZE;
879
880   szFilter[0] = 0;
881   szFilter[1] = 0;
882
883   return AVIERR_UNSUPPORTED;
884 }
885
886 /***********************************************************************
887  *              AVISaveOptions          (AVIFIL32.@)
888  */
889 BOOL WINAPI AVISaveOptions(HWND hWnd, UINT uFlags, INT nStream,
890                            PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *ppOptions)
891 {
892   FIXME("(%p,0x%X,%d,%p,%p): stub\n", hWnd, uFlags, nStream,
893         ppavi, ppOptions);
894
895   return FALSE;
896 }
897
898 /***********************************************************************
899  *              AVISaveOptionsFree      (AVIFIL32.@)
900  */
901 HRESULT WINAPI AVISaveOptionsFree(INT nStreams,LPAVICOMPRESSOPTIONS*ppOptions)
902 {
903   TRACE("(%d,%p)\n", nStreams, ppOptions);
904
905   if (nStreams < 0 || ppOptions == NULL)
906     return AVIERR_BADPARAM;
907
908   for (; nStreams > 0; nStreams--) {
909     if (ppOptions[nStreams] != NULL) {
910       ppOptions[nStreams]->dwFlags &= ~AVICOMPRESSF_VALID;
911
912       if (ppOptions[nStreams]->lpParms != NULL) {
913         GlobalFreePtr(ppOptions[nStreams]->lpParms);
914         ppOptions[nStreams]->lpParms = NULL;
915         ppOptions[nStreams]->cbParms = 0;
916       }
917       if (ppOptions[nStreams]->lpFormat != NULL) {
918         GlobalFreePtr(ppOptions[nStreams]->lpFormat);
919         ppOptions[nStreams]->lpFormat = NULL;
920         ppOptions[nStreams]->cbFormat = 0;
921       }
922     }
923   }
924
925   return AVIERR_OK;
926 }