~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/avifil32/api.c

Version: ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

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