2 * Copyright 1999 Marcus Meissner
3 * Copyright 2002-2003 Michael Günnewig
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.
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.
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
20 #define COM_NO_WINDOWS_H
35 #include "avifile_private.h"
37 #include "wine/debug.h"
38 #include "wine/unicode.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(avifile);
42 /***********************************************************************
43 * copied from dlls/shell32/undocshell.h
45 HRESULT WINAPI SHCoCreateInstance(LPCSTR lpszClsid,REFCLSID rClsid,
46 LPUNKNOWN pUnkOuter,REFIID riid,LPVOID *ppv);
48 /***********************************************************************
49 * for AVIBuildFilterW -- uses fixed size table
51 #define MAX_FILTERS 30 /* 30 => 7kB */
53 typedef struct _AVIFilter {
55 WCHAR szExtensions[MAX_FILTERS * 7];
58 /***********************************************************************
65 LPAVICOMPRESSOPTIONS *ppOptions;
69 /***********************************************************************
70 * copied from dlls/ole32/compobj.c
72 static HRESULT AVIFILE_CLSIDFromString(LPCSTR idstr, LPCLSID id)
74 BYTE const *s = (BYTE const*)idstr;
80 memset(id, 0, sizeof(CLSID));
82 } else { /* validate the CLSID string */
83 if (lstrlenA(s) != 38)
84 return CO_E_CLASSSTRING;
86 if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') ||
87 (s[24]!='-') || (s[37]!='}'))
88 return CO_E_CLASSSTRING;
90 for (i = 1; i < 37; i++) {
91 if ((i == 9) || (i == 14) || (i == 19) || (i == 24))
93 if (!(((s[i] >= '0') && (s[i] <= '9')) ||
94 ((s[i] >= 'a') && (s[i] <= 'f')) ||
95 ((s[i] >= 'A') && (s[i] <= 'F')))
97 return CO_E_CLASSSTRING;
101 TRACE("%s -> %p\n", s, id);
103 /* quick lookup table */
104 memset(table, 0, 256);
106 for (i = 0; i < 10; i++)
109 for (i = 0; i < 6; i++) {
110 table['A' + i] = i+10;
111 table['a' + i] = i+10;
114 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
117 s++; /* skip leading brace */
118 for (i = 0; i < 4; i++) {
119 p[3 - i] = table[*s]<<4 | table[*(s+1)];
125 for (i = 0; i < 2; i++) {
126 p[1-i] = table[*s]<<4 | table[*(s+1)];
132 for (i = 0; i < 2; i++) {
133 p[1-i] = table[*s]<<4 | table[*(s+1)];
139 /* these are just sequential bytes */
140 for (i = 0; i < 2; i++) {
141 *p++ = table[*s]<<4 | table[*(s+1)];
146 for (i = 0; i < 6; i++) {
147 *p++ = table[*s]<<4 | table[*(s+1)];
154 static BOOL AVIFILE_GetFileHandlerByExtension(LPCWSTR szFile, LPCLSID lpclsid)
158 LPWSTR szExt = strrchrW(szFile, '.');
159 LONG len = sizeof(szValue) / sizeof(szValue[0]);
166 wsprintfA(szRegKey, "AVIFile\\Extensions\\%.3ls", szExt);
167 if (RegQueryValueA(HKEY_CLASSES_ROOT, szRegKey, szValue, &len) != ERROR_SUCCESS)
170 return (AVIFILE_CLSIDFromString(szValue, lpclsid) == S_OK);
173 /***********************************************************************
174 * AVIFileInit (AVIFIL32.@)
175 * AVIFileInit (AVIFILE.100)
177 void WINAPI AVIFileInit(void) {
178 /* need to load ole32.dll if not already done and get some functions */
179 FIXME("(): stub!\n");
182 /***********************************************************************
183 * AVIFileExit (AVIFIL32.@)
184 * AVIFileExit (AVIFILE.101)
186 void WINAPI AVIFileExit(void) {
187 /* need to free ole32.dll if we are the last exit call */
188 FIXME("(): stub!\n");
191 /***********************************************************************
192 * AVIFileOpenA (AVIFIL32.@)
193 * AVIFileOpen (AVIFILE.102)
195 HRESULT WINAPI AVIFileOpenA(PAVIFILE *ppfile, LPCSTR szFile, UINT uMode,
198 LPWSTR wszFile = NULL;
202 TRACE("(%p,%s,0x%08X,%s)\n", ppfile, debugstr_a(szFile), uMode,
203 debugstr_guid(lpHandler));
205 /* check parameters */
206 if (ppfile == NULL || szFile == NULL)
207 return AVIERR_BADPARAM;
209 /* convert ASCII string to Unicode and call unicode function */
210 len = lstrlenA(szFile);
212 return AVIERR_BADPARAM;
214 wszFile = (LPWSTR)LocalAlloc(LPTR, (len + 1) * sizeof(WCHAR));
216 return AVIERR_MEMORY;
218 MultiByteToWideChar(CP_ACP, 0, szFile, -1, wszFile, len + 1);
219 wszFile[len + 1] = 0;
221 hr = AVIFileOpenW(ppfile, wszFile, uMode, lpHandler);
223 LocalFree((HLOCAL)wszFile);
228 /***********************************************************************
229 * AVIFileOpenW (AVIFIL32.@)
231 HRESULT WINAPI AVIFileOpenW(PAVIFILE *ppfile, LPCWSTR szFile, UINT uMode,
234 IPersistFile *ppersist = NULL;
238 TRACE("(%p,%s,0x%X,%s)\n", ppfile, debugstr_w(szFile), uMode,
239 debugstr_guid(lpHandler));
241 /* check parameters */
242 if (ppfile == NULL || szFile == NULL)
243 return AVIERR_BADPARAM;
247 /* if no handler then try guessing it by extension */
248 if (lpHandler == NULL) {
249 if (! AVIFILE_GetFileHandlerByExtension(szFile, &clsidHandler))
250 return AVIERR_UNSUPPORTED;
252 memcpy(&clsidHandler, lpHandler, sizeof(clsidHandler));
254 /* crete instance of handler */
255 hr = SHCoCreateInstance(NULL, &clsidHandler, NULL,
256 &IID_IAVIFile, (LPVOID*)ppfile);
257 if (FAILED(hr) || *ppfile == NULL)
260 /* ask for IPersistFile interface for loading/creating the file */
261 hr = IAVIFile_QueryInterface(*ppfile, &IID_IPersistFile, (LPVOID*)&ppersist);
262 if (FAILED(hr) || ppersist == NULL) {
263 IAVIFile_Release(*ppfile);
268 hr = IPersistFile_Load(ppersist, szFile, uMode);
269 IPersistFile_Release(ppersist);
271 IAVIFile_Release(*ppfile);
278 /***********************************************************************
279 * AVIFileAddRef (AVIFIL32.@)
280 * AVIFileAddRef (AVIFILE.140)
282 ULONG WINAPI AVIFileAddRef(PAVIFILE pfile)
284 TRACE("(%p)\n", pfile);
287 ERR(": bad handle passed!\n");
291 return IAVIFile_AddRef(pfile);
294 /***********************************************************************
295 * AVIFileRelease (AVIFIL32.@)
296 * AVIFileRelease (AVIFILE.141)
298 ULONG WINAPI AVIFileRelease(PAVIFILE pfile)
300 TRACE("(%p)\n", pfile);
303 ERR(": bad handle passed!\n");
307 return IAVIFile_Release(pfile);
310 /***********************************************************************
311 * AVIFileInfo (AVIFIL32.@)
312 * AVIFileInfoA (AVIFIL32.@)
313 * AVIFileInfo (AVIFILE.142)
315 HRESULT WINAPI AVIFileInfoA(PAVIFILE pfile, LPAVIFILEINFOA afi, LONG size)
320 TRACE("(%p,%p,%ld)\n", pfile, afi, size);
323 return AVIERR_BADHANDLE;
324 if ((DWORD)size < sizeof(AVIFILEINFOA))
325 return AVIERR_BADSIZE;
327 hres = IAVIFile_Info(pfile, &afiw, sizeof(afiw));
329 memcpy(afi, &afiw, sizeof(*afi) - sizeof(afi->szFileType));
330 WideCharToMultiByte(CP_ACP, 0, afiw.szFileType, -1, afi->szFileType,
331 sizeof(afi->szFileType), NULL, NULL);
332 afi->szFileType[sizeof(afi->szFileType) - 1] = 0;
337 /***********************************************************************
338 * AVIFileInfoW (AVIFIL32.@)
340 HRESULT WINAPI AVIFileInfoW(PAVIFILE pfile, LPAVIFILEINFOW afiw, LONG size)
342 TRACE("(%p,%p,%ld)\n", pfile, afiw, size);
345 return AVIERR_BADHANDLE;
347 return IAVIFile_Info(pfile, afiw, size);
350 /***********************************************************************
351 * AVIFileGetStream (AVIFIL32.@)
352 * AVIFileGetStream (AVIFILE.143)
354 HRESULT WINAPI AVIFileGetStream(PAVIFILE pfile, PAVISTREAM *avis,
355 DWORD fccType, LONG lParam)
357 TRACE("(%p,%p,'%4.4s',%ld)\n", pfile, avis, (char*)&fccType, lParam);
360 return AVIERR_BADHANDLE;
362 return IAVIFile_GetStream(pfile, avis, fccType, lParam);
365 /***********************************************************************
366 * AVIFileCreateStreamA (AVIFIL32.@)
367 * AVIFileCreateStream (AVIFILE.144)
369 HRESULT WINAPI AVIFileCreateStreamA(PAVIFILE pfile, PAVISTREAM *ppavi,
370 LPAVISTREAMINFOA psi)
374 TRACE("(%p,%p,%p)\n", pfile, ppavi, psi);
377 return AVIERR_BADHANDLE;
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]));
384 return IAVIFile_CreateStream(pfile, ppavi, &psiw);
387 /***********************************************************************
388 * AVIFileCreateStreamW (AVIFIL32.@)
390 HRESULT WINAPI AVIFileCreateStreamW(PAVIFILE pfile, PAVISTREAM *avis,
391 LPAVISTREAMINFOW asi)
393 TRACE("(%p,%p,%p)\n", pfile, avis, asi);
395 return IAVIFile_CreateStream(pfile, avis, asi);
398 /***********************************************************************
399 * AVIFileWriteData (AVIFIL32.@)
400 * AVIFileWriteData (AVIFILE.146)
402 HRESULT WINAPI AVIFileWriteData(PAVIFILE pfile,DWORD fcc,LPVOID lp,LONG size)
404 TRACE("(%p,'%4.4s',%p,%ld)\n", pfile, (char*)&fcc, lp, size);
407 return AVIERR_BADHANDLE;
409 return IAVIFile_WriteData(pfile, fcc, lp, size);
412 /***********************************************************************
413 * AVIFileReadData (AVIFIL32.@)
414 * AVIFileReadData (AVIFILE.147)
416 HRESULT WINAPI AVIFileReadData(PAVIFILE pfile,DWORD fcc,LPVOID lp,LPLONG size)
418 TRACE("(%p,'%4.4s',%p,%p)\n", pfile, (char*)&fcc, lp, size);
421 return AVIERR_BADHANDLE;
423 return IAVIFile_ReadData(pfile, fcc, lp, size);
426 /***********************************************************************
427 * AVIFileEndRecord (AVIFIL32.@)
428 * AVIFileEndRecord (AVIFILE.148)
430 HRESULT WINAPI AVIFileEndRecord(PAVIFILE pfile)
432 TRACE("(%p)\n", pfile);
435 return AVIERR_BADHANDLE;
437 return IAVIFile_EndRecord(pfile);
440 /***********************************************************************
441 * AVIStreamAddRef (AVIFIL32.@)
442 * AVIStreamAddRef (AVIFILE.160)
444 ULONG WINAPI AVIStreamAddRef(PAVISTREAM pstream)
446 TRACE("(%p)\n", pstream);
448 if (pstream == NULL) {
449 ERR(": bad handle passed!\n");
453 return IAVIStream_AddRef(pstream);
456 /***********************************************************************
457 * AVIStreamRelease (AVIFIL32.@)
458 * AVIStreamRelease (AVIFILE.161)
460 ULONG WINAPI AVIStreamRelease(PAVISTREAM pstream)
462 TRACE("(%p)\n", pstream);
464 if (pstream == NULL) {
465 ERR(": bad handle passed!\n");
469 return IAVIStream_Release(pstream);
472 /***********************************************************************
473 * AVIStreamCreate (AVIFIL32.@)
474 * AVIStreamCreate (AVIFILE.104)
476 HRESULT WINAPI AVIStreamCreate(PAVISTREAM *ppavi, LONG lParam1, LONG lParam2,
477 LPCLSID pclsidHandler)
481 TRACE("(%p,0x%08lX,0x%08lX,%s)\n", ppavi, lParam1, lParam2,
482 debugstr_guid(pclsidHandler));
485 return AVIERR_BADPARAM;
488 if (pclsidHandler == NULL)
489 return AVIERR_UNSUPPORTED;
491 hr = SHCoCreateInstance(NULL, pclsidHandler, NULL,
492 &IID_IAVIStream, (LPVOID*)ppavi);
493 if (FAILED(hr) || *ppavi == NULL)
496 hr = IAVIStream_Create(*ppavi, lParam1, lParam2);
498 IAVIStream_Release(*ppavi);
505 /***********************************************************************
506 * AVIStreamInfoA (AVIFIL32.@)
507 * AVIStreamInfo (AVIFILE.162)
509 HRESULT WINAPI AVIStreamInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi,
515 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
518 return AVIERR_BADHANDLE;
519 if ((DWORD)size < sizeof(AVISTREAMINFOA))
520 return AVIERR_BADSIZE;
522 hres = IAVIStream_Info(pstream, &asiw, sizeof(asiw));
524 memcpy(asi, &asiw, sizeof(asiw) - sizeof(asiw.szName));
525 WideCharToMultiByte(CP_ACP, 0, asiw.szName, -1, asi->szName,
526 sizeof(asi->szName), NULL, NULL);
527 asi->szName[sizeof(asi->szName) - 1] = 0;
532 /***********************************************************************
533 * AVIStreamInfoW (AVIFIL32.@)
535 HRESULT WINAPI AVIStreamInfoW(PAVISTREAM pstream, LPAVISTREAMINFOW asi,
538 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
541 return AVIERR_BADHANDLE;
543 return IAVIStream_Info(pstream, asi, size);
546 /***********************************************************************
547 * AVIStreamFindSample (AVIFIL32.@)
548 * AVIStreamFindSample (AVIFILE.163)
550 HRESULT WINAPI AVIStreamFindSample(PAVISTREAM pstream, LONG pos, DWORD flags)
552 TRACE("(%p,%ld,0x%lX)\n", pstream, pos, flags);
557 return IAVIStream_FindSample(pstream, pos, flags);
560 /***********************************************************************
561 * AVIStreamReadFormat (AVIFIL32.@)
562 * AVIStreamReadFormat (AVIFILE.164)
564 HRESULT WINAPI AVIStreamReadFormat(PAVISTREAM pstream, LONG pos,
565 LPVOID format, LPLONG formatsize)
567 TRACE("(%p,%ld,%p,%p)\n", pstream, pos, format, formatsize);
570 return AVIERR_BADHANDLE;
572 return IAVIStream_ReadFormat(pstream, pos, format, formatsize);
575 /***********************************************************************
576 * AVIStreamSetFormat (AVIFIL32.@)
577 * AVIStreamSetFormat (AVIFILE.169)
579 HRESULT WINAPI AVIStreamSetFormat(PAVISTREAM pstream, LONG pos,
580 LPVOID format, LONG formatsize)
582 TRACE("(%p,%ld,%p,%ld)\n", pstream, pos, format, formatsize);
585 return AVIERR_BADHANDLE;
587 return IAVIStream_SetFormat(pstream, pos, format, formatsize);
590 /***********************************************************************
591 * AVIStreamRead (AVIFIL32.@)
592 * AVIStreamRead (AVIFILE.167)
594 HRESULT WINAPI AVIStreamRead(PAVISTREAM pstream, LONG start, LONG samples,
595 LPVOID buffer, LONG buffersize,
596 LPLONG bytesread, LPLONG samplesread)
598 TRACE("(%p,%ld,%ld,%p,%ld,%p,%p)\n", pstream, start, samples, buffer,
599 buffersize, bytesread, samplesread);
602 return AVIERR_BADHANDLE;
604 return IAVIStream_Read(pstream, start, samples, buffer, buffersize,
605 bytesread, samplesread);
608 /***********************************************************************
609 * AVIStreamWrite (AVIFIL32.@)
610 * AVIStreamWrite (AVIFILE.168)
612 HRESULT WINAPI AVIStreamWrite(PAVISTREAM pstream, LONG start, LONG samples,
613 LPVOID buffer, LONG buffersize, DWORD flags,
614 LPLONG sampwritten, LPLONG byteswritten)
616 TRACE("(%p,%ld,%ld,%p,%ld,0x%lX,%p,%p)\n", pstream, start, samples, buffer,
617 buffersize, flags, sampwritten, byteswritten);
620 return AVIERR_BADHANDLE;
622 return IAVIStream_Write(pstream, start, samples, buffer, buffersize,
623 flags, sampwritten, byteswritten);
626 /***********************************************************************
627 * AVIStreamReadData (AVIFIL32.@)
628 * AVIStreamReadData (AVIFILE.165)
630 HRESULT WINAPI AVIStreamReadData(PAVISTREAM pstream, DWORD fcc, LPVOID lp,
633 TRACE("(%p,'%4.4s',%p,%p)\n", pstream, (char*)&fcc, lp, lpread);
636 return AVIERR_BADHANDLE;
638 return IAVIStream_ReadData(pstream, fcc, lp, lpread);
641 /***********************************************************************
642 * AVIStreamWriteData (AVIFIL32.@)
643 * AVIStreamWriteData (AVIFILE.166)
645 HRESULT WINAPI AVIStreamWriteData(PAVISTREAM pstream, DWORD fcc, LPVOID lp,
648 TRACE("(%p,'%4.4s',%p,%ld)\n", pstream, (char*)&fcc, lp, size);
651 return AVIERR_BADHANDLE;
653 return IAVIStream_WriteData(pstream, fcc, lp, size);
656 /***********************************************************************
657 * AVIStreamGetFrameOpen (AVIFIL32.@)
658 * AVIStreamGetFrameOpen (AVIFILE.112)
660 PGETFRAME WINAPI AVIStreamGetFrameOpen(PAVISTREAM pstream,
661 LPBITMAPINFOHEADER lpbiWanted)
665 TRACE("(%p,%p)\n", pstream, lpbiWanted);
667 if (FAILED(IAVIStream_QueryInterface(pstream, &IID_IGetFrame, (LPVOID*)&pg)) ||
669 pg = AVIFILE_CreateGetFrame(pstream);
674 if (FAILED(IGetFrame_SetFormat(pg, lpbiWanted, NULL, 0, 0, -1, -1))) {
675 IGetFrame_Release(pg);
682 /***********************************************************************
683 * AVIStreamGetFrame (AVIFIL32.@)
684 * AVIStreamGetFrame (AVIFILE.110)
686 LPVOID WINAPI AVIStreamGetFrame(PGETFRAME pg, LONG pos)
688 TRACE("(%p,%ld)\n", pg, pos);
693 return IGetFrame_GetFrame(pg, pos);
696 /***********************************************************************
697 * AVIStreamGetFrameClose (AVIFIL32.@)
698 * AVIStreamGetFrameClose (AVIFILE.111)
700 HRESULT WINAPI AVIStreamGetFrameClose(PGETFRAME pg)
705 return IGetFrame_Release(pg);
709 /***********************************************************************
710 * AVIMakeCompressedStream (AVIFIL32.@)
712 HRESULT WINAPI AVIMakeCompressedStream(PAVISTREAM *ppsCompressed,
714 LPAVICOMPRESSOPTIONS aco,
715 LPCLSID pclsidHandler)
722 LONG size = sizeof(szValue);
724 TRACE("(%p,%p,%p,%s)\n", ppsCompressed, psSource, aco,
725 debugstr_guid(pclsidHandler));
727 if (ppsCompressed == NULL)
728 return AVIERR_BADPARAM;
729 if (psSource == NULL)
730 return AVIERR_BADHANDLE;
732 *ppsCompressed = NULL;
734 /* if no handler given get default ones based on streamtype */
735 if (pclsidHandler == NULL) {
736 hr = IAVIStream_Info(psSource, &asiw, sizeof(asiw));
740 wsprintfA(szRegKey, "AVIFile\\Compressors\\%4.4s", (char*)&asiw.fccType);
741 if (RegQueryValueA(HKEY_CLASSES_ROOT, szRegKey, szValue, &size) != ERROR_SUCCESS)
742 return AVIERR_UNSUPPORTED;
743 if (AVIFILE_CLSIDFromString(szValue, &clsidHandler) != S_OK)
744 return AVIERR_UNSUPPORTED;
746 memcpy(&clsidHandler, pclsidHandler, sizeof(clsidHandler));
748 hr = SHCoCreateInstance(NULL, &clsidHandler, NULL,
749 &IID_IAVIStream, (LPVOID*)ppsCompressed);
750 if (FAILED(hr) || *ppsCompressed == NULL)
753 hr = IAVIStream_Create(*ppsCompressed, (LPARAM)psSource, (LPARAM)aco);
755 IAVIStream_Release(*ppsCompressed);
756 *ppsCompressed = NULL;
762 /***********************************************************************
763 * AVIMakeFileFromStreams (AVIFIL32.@)
765 HRESULT WINAPI AVIMakeFileFromStreams(PAVIFILE *ppfile, int nStreams,
766 PAVISTREAM *ppStreams)
768 TRACE("(%p,%d,%p)\n", ppfile, nStreams, ppStreams);
770 if (nStreams < 0 || ppfile == NULL || ppStreams == NULL)
771 return AVIERR_BADPARAM;
773 *ppfile = AVIFILE_CreateAVITempFile(nStreams, ppStreams);
775 return AVIERR_MEMORY;
780 /***********************************************************************
781 * AVIStreamOpenFromFile (AVIFILE.103)
782 * AVIStreamOpenFromFileA (AVIFIL32.@)
784 HRESULT WINAPI AVIStreamOpenFromFileA(PAVISTREAM *ppavi, LPCSTR szFile,
785 DWORD fccType, LONG lParam,
786 UINT mode, LPCLSID pclsidHandler)
788 PAVIFILE pfile = NULL;
791 TRACE("(%p,%s,'%4.4s',%ld,0x%X,%s)\n", ppavi, debugstr_a(szFile),
792 (char*)&fccType, lParam, mode, debugstr_guid(pclsidHandler));
794 if (ppavi == NULL || szFile == NULL)
795 return AVIERR_BADPARAM;
799 hr = AVIFileOpenA(&pfile, szFile, mode, pclsidHandler);
800 if (FAILED(hr) || pfile == NULL)
803 hr = IAVIFile_GetStream(pfile, ppavi, fccType, lParam);
804 IAVIFile_Release(pfile);
809 /***********************************************************************
810 * AVIStreamOpenFromFileW (AVIFIL32.@)
812 HRESULT WINAPI AVIStreamOpenFromFileW(PAVISTREAM *ppavi, LPCWSTR szFile,
813 DWORD fccType, LONG lParam,
814 UINT mode, LPCLSID pclsidHandler)
816 PAVIFILE pfile = NULL;
819 TRACE("(%p,%s,'%4.4s',%ld,0x%X,%s)\n", ppavi, debugstr_w(szFile),
820 (char*)&fccType, lParam, mode, debugstr_guid(pclsidHandler));
822 if (ppavi == NULL || szFile == NULL)
823 return AVIERR_BADPARAM;
827 hr = AVIFileOpenW(&pfile, szFile, mode, pclsidHandler);
828 if (FAILED(hr) || pfile == NULL)
831 hr = IAVIFile_GetStream(pfile, ppavi, fccType, lParam);
832 IAVIFile_Release(pfile);
837 /***********************************************************************
838 * AVIStreamBeginStreaming (AVIFIL32.@)
840 LONG WINAPI AVIStreamBeginStreaming(PAVISTREAM pavi, LONG lStart, LONG lEnd, LONG lRate)
842 FIXME("(%p)->(%ld,%ld,%ld)\n", pavi, lStart, lEnd, lRate);
847 /***********************************************************************
848 * AVIStreamEndStreaming (AVIFIL32.@)
850 LONG WINAPI AVIStreamEndStreaming(PAVISTREAM pavi)
852 FIXME("(%p)\n", pavi);
857 /***********************************************************************
858 * AVIStreamStart (AVIFILE.130)
859 * AVIStreamStart (AVIFIL32.@)
861 LONG WINAPI AVIStreamStart(PAVISTREAM pstream)
865 TRACE("(%p)\n", pstream);
870 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
876 /***********************************************************************
877 * AVIStreamLength (AVIFILE.131)
878 * AVIStreamLength (AVIFIL32.@)
880 LONG WINAPI AVIStreamLength(PAVISTREAM pstream)
884 TRACE("(%p)\n", pstream);
889 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
892 return asiw.dwLength;
895 /***********************************************************************
896 * AVIStreamSampleToTime (AVIFILE.133)
897 * AVIStreamSampleToTime (AVIFIL32.@)
899 LONG WINAPI AVIStreamSampleToTime(PAVISTREAM pstream, LONG lSample)
903 TRACE("(%p,%ld)\n", pstream, lSample);
908 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
910 if (asiw.dwRate == 0)
913 return (LONG)(((float)lSample * asiw.dwScale * 1000.0) / asiw.dwRate);
916 /***********************************************************************
917 * AVIStreamTimeToSample (AVIFILE.132)
918 * AVIStreamTimeToSample (AVIFIL32.@)
920 LONG WINAPI AVIStreamTimeToSample(PAVISTREAM pstream, LONG lTime)
924 TRACE("(%p,%ld)\n", pstream, lTime);
929 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
931 if (asiw.dwScale == 0)
934 return (LONG)(((float)lTime * asiw.dwRate) / asiw.dwScale / 1000.0);
937 /***********************************************************************
938 * AVIBuildFilterA (AVIFIL32.@)
939 * AVIBuildFilter (AVIFILE.123)
941 HRESULT WINAPI AVIBuildFilterA(LPSTR szFilter, LONG cbFilter, BOOL fSaving)
946 TRACE("(%p,%ld,%d)\n", szFilter, cbFilter, fSaving);
948 /* check parameters */
949 if (szFilter == NULL)
950 return AVIERR_BADPARAM;
952 return AVIERR_BADSIZE;
957 wszFilter = (LPWSTR)GlobalAllocPtr(GHND, cbFilter);
958 if (wszFilter == NULL)
959 return AVIERR_MEMORY;
961 hr = AVIBuildFilterW(wszFilter, cbFilter, fSaving);
963 WideCharToMultiByte(CP_ACP, 0, wszFilter, cbFilter,
964 szFilter, cbFilter, NULL, NULL);
967 GlobalFreePtr(wszFilter);
972 /***********************************************************************
973 * AVIBuildFilterW (AVIFIL32.@)
975 HRESULT WINAPI AVIBuildFilterW(LPWSTR szFilter, LONG cbFilter, BOOL fSaving)
977 static const WCHAR szClsid[] = {'C','L','S','I','D',0};
978 static const WCHAR szExtensionFmt[] = {';','*','.','%','s',0};
979 static const WCHAR szAVIFileExtensions[] =
980 {'A','V','I','F','i','l','e','\\','E','x','t','e','n','s','i','o','n','s',0};
983 WCHAR szAllFiles[40];
991 TRACE("(%p,%ld,%d)\n", szFilter, cbFilter, fSaving);
993 /* check parameters */
994 if (szFilter == NULL)
995 return AVIERR_BADPARAM;
997 return AVIERR_BADSIZE;
999 lp = (AVIFilter*)GlobalAllocPtr(GHND, MAX_FILTERS * sizeof(AVIFilter));
1001 return AVIERR_MEMORY;
1004 * 1. iterate over HKEY_CLASSES_ROOT\\AVIFile\\Extensions and collect
1005 * extensions and CLSID's
1006 * 2. iterate over collected CLSID's and copy it's description and it's
1007 * extensions to szFilter if it fits
1009 * First filter is named "All multimedia files" and it's filter is a
1010 * collection of all possible extensions except "*.*".
1012 if (RegOpenKeyW(HKEY_CLASSES_ROOT, szAVIFileExtensions, &hKey) != S_OK) {
1014 return AVIERR_ERROR;
1016 for (n = 0;RegEnumKeyW(hKey, n, szFileExt, sizeof(szFileExt)) == S_OK;n++) {
1017 /* get CLSID to extension */
1018 size = sizeof(szValue)/sizeof(szValue[0]);
1019 if (RegQueryValueW(hKey, szFileExt, szValue, &size) != S_OK)
1022 /* search if the CLSID is already known */
1023 for (i = 1; i <= count; i++) {
1024 if (lstrcmpW(lp[i].szClsid, szValue) == 0)
1025 break; /* a new one */
1028 if (count - i == -1U) {
1029 /* it's a new CLSID */
1031 /* FIXME: How do we get info's about read/write capabilities? */
1033 if (count >= MAX_FILTERS) {
1034 /* try to inform user of our full fixed size table */
1035 ERR(": More than %d filters found! Adjust MAX_FILTERS in dlls/avifil32/api.c\n", MAX_FILTERS);
1039 lstrcpyW(lp[i].szClsid, szValue);
1044 /* append extension to the filter */
1045 wsprintfW(szValue, szExtensionFmt, szFileExt);
1046 if (lp[i].szExtensions[0] == 0)
1047 lstrcatW(lp[i].szExtensions, szValue + 1);
1049 lstrcatW(lp[i].szExtensions, szValue);
1051 /* also append to the "all multimedia"-filter */
1052 if (lp[0].szExtensions[0] == 0)
1053 lstrcatW(lp[0].szExtensions, szValue + 1);
1055 lstrcatW(lp[0].szExtensions, szValue);
1059 /* 2. get descriptions for the CLSIDs and fill out szFilter */
1060 if (RegOpenKeyW(HKEY_CLASSES_ROOT, szClsid, &hKey) != S_OK) {
1062 return AVIERR_ERROR;
1064 for (n = 0; n <= count; n++) {
1065 /* first the description */
1067 size = sizeof(szValue)/sizeof(szValue[0]);
1068 if (RegQueryValueW(hKey, lp[n].szClsid, szValue, &size) == S_OK) {
1069 size = lstrlenW(szValue);
1070 lstrcpynW(szFilter, szValue, cbFilter);
1073 size = LoadStringW(AVIFILE_hModule,IDS_ALLMULTIMEDIA,szFilter,cbFilter);
1075 /* check for enough space */
1077 if (cbFilter < size + lstrlenW(lp[n].szExtensions) + 2) {
1082 return AVIERR_BUFFERTOOSMALL;
1087 /* and then the filter */
1088 lstrcpynW(szFilter, lp[n].szExtensions, cbFilter);
1089 size = lstrlenW(lp[n].szExtensions) + 1;
1097 /* add "All files" "*.*" filter if enough space left */
1098 size = LoadStringW(AVIFILE_hModule, IDS_ALLFILES,
1099 szAllFiles, sizeof(szAllFiles)) + 1;
1100 if (cbFilter > size) {
1103 /* replace '@' with \000 to separate description of filter */
1104 for (i = 0; i < size && szAllFiles[i] != 0; i++) {
1105 if (szAllFiles[i] == '@') {
1111 memcpy(szFilter, szAllFiles, size * sizeof(szAllFiles[0]));
1118 return AVIERR_BUFFERTOOSMALL;
1122 static BOOL AVISaveOptionsFmtChoose(HWND hWnd)
1124 LPAVICOMPRESSOPTIONS pOptions = SaveOpts.ppOptions[SaveOpts.nCurrent];
1125 AVISTREAMINFOW sInfo;
1127 TRACE("(%p)\n", hWnd);
1129 if (pOptions == NULL || SaveOpts.ppavis[SaveOpts.nCurrent] == NULL) {
1130 ERR(": bad state!\n");
1134 if (FAILED(AVIStreamInfoW(SaveOpts.ppavis[SaveOpts.nCurrent],
1135 &sInfo, sizeof(sInfo)))) {
1136 ERR(": AVIStreamInfoW failed!\n");
1140 if (sInfo.fccType == streamtypeVIDEO) {
1144 memset(&cv, 0, sizeof(cv));
1146 if ((pOptions->dwFlags & AVICOMPRESSF_VALID) == 0) {
1147 memset(pOptions, 0, sizeof(AVICOMPRESSOPTIONS));
1148 pOptions->fccType = streamtypeVIDEO;
1149 pOptions->fccHandler = comptypeDIB;
1150 pOptions->dwQuality = (DWORD)ICQUALITY_DEFAULT;
1153 cv.cbSize = sizeof(cv);
1154 cv.dwFlags = ICMF_COMPVARS_VALID;
1155 /*cv.fccType = pOptions->fccType; */
1156 cv.fccHandler = pOptions->fccHandler;
1157 cv.lQ = pOptions->dwQuality;
1158 cv.lpState = pOptions->lpParms;
1159 cv.cbState = pOptions->cbParms;
1160 if (pOptions->dwFlags & AVICOMPRESSF_KEYFRAMES)
1161 cv.lKey = pOptions->dwKeyFrameEvery;
1164 if (pOptions->dwFlags & AVICOMPRESSF_DATARATE)
1165 cv.lDataRate = pOptions->dwBytesPerSecond / 1024; /* need kBytes */
1169 ret = ICCompressorChoose(hWnd, SaveOpts.uFlags, NULL,
1170 SaveOpts.ppavis[SaveOpts.nCurrent], &cv, NULL);
1173 pOptions->fccHandler = cv.fccHandler;
1174 pOptions->lpParms = cv.lpState;
1175 pOptions->cbParms = cv.cbState;
1176 pOptions->dwQuality = cv.lQ;
1178 pOptions->dwKeyFrameEvery = cv.lKey;
1179 pOptions->dwFlags |= AVICOMPRESSF_KEYFRAMES;
1181 pOptions->dwFlags &= ~AVICOMPRESSF_KEYFRAMES;
1182 if (cv.lDataRate != 0) {
1183 pOptions->dwBytesPerSecond = cv.lDataRate * 1024; /* need bytes */
1184 pOptions->dwFlags |= AVICOMPRESSF_DATARATE;
1186 pOptions->dwFlags &= ~AVICOMPRESSF_DATARATE;
1187 pOptions->dwFlags |= AVICOMPRESSF_VALID;
1189 ICCompressorFree(&cv);
1192 } else if (sInfo.fccType == streamtypeAUDIO) {
1193 ACMFORMATCHOOSEW afmtc;
1197 /* FIXME: check ACM version -- Which version is needed? */
1199 memset(&afmtc, 0, sizeof(afmtc));
1200 afmtc.cbStruct = sizeof(afmtc);
1202 afmtc.hwndOwner = hWnd;
1204 acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, &size);
1205 if ((pOptions->cbFormat == 0 || pOptions->lpFormat == NULL) && size != 0) {
1206 pOptions->lpFormat = GlobalAllocPtr(GMEM_MOVEABLE, size);
1207 pOptions->cbFormat = size;
1208 } else if (pOptions->cbFormat < (DWORD)size) {
1209 pOptions->lpFormat = GlobalReAllocPtr(pOptions->lpFormat, size, GMEM_MOVEABLE);
1210 pOptions->cbFormat = size;
1212 if (pOptions->lpFormat == NULL)
1214 afmtc.pwfx = pOptions->lpFormat;
1215 afmtc.cbwfx = pOptions->cbFormat;
1218 AVIStreamFormatSize(SaveOpts.ppavis[SaveOpts.nCurrent],
1219 sInfo.dwStart, &size);
1220 if (size < (LONG)sizeof(PCMWAVEFORMAT))
1221 size = sizeof(PCMWAVEFORMAT);
1222 afmtc.pwfxEnum = GlobalAllocPtr(GHND, size);
1223 if (afmtc.pwfxEnum != NULL) {
1224 AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent],
1225 sInfo.dwStart, afmtc.pwfxEnum, &size);
1226 afmtc.fdwEnum = ACM_FORMATENUMF_CONVERT;
1229 ret = acmFormatChooseW(&afmtc);
1231 pOptions->dwFlags |= AVICOMPRESSF_VALID;
1233 if (afmtc.pwfxEnum != NULL)
1234 GlobalFreePtr(afmtc.pwfxEnum);
1236 return (ret == S_OK ? TRUE : FALSE);
1238 ERR(": unknown streamtype 0x%08lX\n", sInfo.fccType);
1243 static void AVISaveOptionsUpdate(HWND hWnd)
1245 static const WCHAR szVideoFmt[]={'%','l','d','x','%','l','d','x','%','d',0};
1246 static const WCHAR szAudioFmt[]={'%','s',' ','%','s',0};
1248 WCHAR szFormat[128];
1249 AVISTREAMINFOW sInfo;
1253 TRACE("(%p)\n", hWnd);
1255 SaveOpts.nCurrent = SendDlgItemMessageW(hWnd,IDC_STREAM,CB_GETCURSEL,0,0);
1256 if (SaveOpts.nCurrent < 0)
1259 if (FAILED(AVIStreamInfoW(SaveOpts.ppavis[SaveOpts.nCurrent], &sInfo, sizeof(sInfo))))
1262 AVIStreamFormatSize(SaveOpts.ppavis[SaveOpts.nCurrent],sInfo.dwStart,&size);
1266 /* read format to build format descriotion string */
1267 lpFormat = GlobalAllocPtr(GHND, size);
1268 if (lpFormat != NULL) {
1269 if (SUCCEEDED(AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent],sInfo.dwStart,lpFormat, &size))) {
1270 if (sInfo.fccType == streamtypeVIDEO) {
1271 LPBITMAPINFOHEADER lpbi = lpFormat;
1274 wsprintfW(szFormat, szVideoFmt, lpbi->biWidth,
1275 lpbi->biHeight, lpbi->biBitCount);
1277 if (lpbi->biCompression != BI_RGB) {
1280 hic = ICLocate(ICTYPE_VIDEO, sInfo.fccHandler, lpFormat,
1281 NULL, ICMODE_DECOMPRESS);
1283 if (ICGetInfo(hic, &icinfo, sizeof(icinfo)) == S_OK)
1284 lstrcatW(szFormat, icinfo.szDescription);
1288 LoadStringW(AVIFILE_hModule, IDS_UNCOMPRESSED,
1289 icinfo.szDescription, sizeof(icinfo.szDescription));
1290 lstrcatW(szFormat, icinfo.szDescription);
1292 } else if (sInfo.fccType == streamtypeAUDIO) {
1293 ACMFORMATTAGDETAILSW aftd;
1294 ACMFORMATDETAILSW afd;
1296 memset(&aftd, 0, sizeof(aftd));
1297 memset(&afd, 0, sizeof(afd));
1299 aftd.cbStruct = sizeof(aftd);
1300 aftd.dwFormatTag = afd.dwFormatTag =
1301 ((PWAVEFORMATEX)lpFormat)->wFormatTag;
1302 aftd.cbFormatSize = afd.cbwfx = size;
1304 afd.cbStruct = sizeof(afd);
1305 afd.pwfx = lpFormat;
1307 if (acmFormatTagDetailsW(NULL, &aftd,
1308 ACM_FORMATTAGDETAILSF_FORMATTAG) == S_OK) {
1309 if (acmFormatDetailsW(NULL,&afd,ACM_FORMATDETAILSF_FORMAT) == S_OK)
1310 wsprintfW(szFormat, szAudioFmt, afd.szFormat, aftd.szFormatTag);
1314 GlobalFreePtr(lpFormat);
1317 /* set text for format description */
1318 SetDlgItemTextW(hWnd, IDC_FORMATTEXT, szFormat);
1320 /* Disable option button for unsupported streamtypes */
1321 if (sInfo.fccType == streamtypeVIDEO ||
1322 sInfo.fccType == streamtypeAUDIO)
1323 EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), TRUE);
1325 EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), FALSE);
1330 INT_PTR CALLBACK AVISaveOptionsDlgProc(HWND hWnd, UINT uMsg,
1331 WPARAM wParam, LPARAM lParam)
1334 BOOL bIsInterleaved;
1337 /*TRACE("(%p,%u,0x%04X,0x%08lX)\n", hWnd, uMsg, wParam, lParam);*/
1341 SaveOpts.nCurrent = 0;
1342 if (SaveOpts.nStreams == 1) {
1343 EndDialog(hWnd, AVISaveOptionsFmtChoose(hWnd));
1348 for (n = 0; n < SaveOpts.nStreams; n++) {
1349 AVISTREAMINFOW sInfo;
1351 AVIStreamInfoW(SaveOpts.ppavis[n], &sInfo, sizeof(sInfo));
1352 SendDlgItemMessageW(hWnd, IDC_STREAM, CB_ADDSTRING,
1353 0L, (LPARAM)sInfo.szName);
1356 /* select first stream */
1357 SendDlgItemMessageW(hWnd, IDC_STREAM, CB_SETCURSEL, 0, 0);
1358 SendMessageW(hWnd, WM_COMMAND,
1359 GET_WM_COMMAND_MPS(IDC_STREAM, hWnd, CBN_SELCHANGE));
1361 /* initialize interleave */
1362 if (SaveOpts.ppOptions[0] != NULL &&
1363 (SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_VALID)) {
1364 bIsInterleaved = (SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_INTERLEAVE);
1365 dwInterleave = SaveOpts.ppOptions[0]->dwInterleaveEvery;
1367 bIsInterleaved = TRUE;
1370 CheckDlgButton(hWnd, IDC_INTERLEAVE, bIsInterleaved);
1371 SetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, dwInterleave, FALSE);
1372 EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY), bIsInterleaved);
1375 switch (GET_WM_COMMAND_ID(wParam, lParam)) {
1377 /* get data from controls and save them */
1378 dwInterleave = GetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, NULL, 0);
1379 bIsInterleaved = IsDlgButtonChecked(hWnd, IDC_INTERLEAVE);
1380 for (n = 0; n < SaveOpts.nStreams; n++) {
1381 if (SaveOpts.ppOptions[n] != NULL) {
1382 if (bIsInterleaved) {
1383 SaveOpts.ppOptions[n]->dwFlags |= AVICOMPRESSF_INTERLEAVE;
1384 SaveOpts.ppOptions[n]->dwInterleaveEvery = dwInterleave;
1386 SaveOpts.ppOptions[n]->dwFlags &= ~AVICOMPRESSF_INTERLEAVE;
1391 EndDialog(hWnd, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
1393 case IDC_INTERLEAVE:
1394 EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY),
1395 IsDlgButtonChecked(hWnd, IDC_INTERLEAVE));
1398 if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE) {
1399 /* update control elements */
1400 AVISaveOptionsUpdate(hWnd);
1404 AVISaveOptionsFmtChoose(hWnd);
1413 /***********************************************************************
1414 * AVISaveOptions (AVIFIL32.@)
1416 BOOL WINAPI AVISaveOptions(HWND hWnd, UINT uFlags, INT nStreams,
1417 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *ppOptions)
1419 LPAVICOMPRESSOPTIONS pSavedOptions = NULL;
1422 TRACE("(%p,0x%X,%d,%p,%p)\n", hWnd, uFlags, nStreams,
1425 /* check parameters */
1426 if (nStreams <= 0 || ppavi == NULL || ppOptions == NULL)
1427 return AVIERR_BADPARAM;
1429 /* save options for case user press cancel */
1430 if (ppOptions != NULL && nStreams > 1) {
1431 pSavedOptions = GlobalAllocPtr(GHND,nStreams * sizeof(AVICOMPRESSOPTIONS));
1432 if (pSavedOptions == NULL)
1435 for (n = 0; n < nStreams; n++) {
1436 if (ppOptions[n] != NULL)
1437 memcpy(pSavedOptions + n, ppOptions[n], sizeof(AVICOMPRESSOPTIONS));
1441 SaveOpts.uFlags = uFlags;
1442 SaveOpts.nStreams = nStreams;
1443 SaveOpts.ppavis = ppavi;
1444 SaveOpts.ppOptions = ppOptions;
1446 ret = DialogBoxW(AVIFILE_hModule, MAKEINTRESOURCEW(IDD_SAVEOPTIONS),
1447 hWnd, AVISaveOptionsDlgProc);
1452 /* restore options when user pressed cancel */
1453 if (pSavedOptions != NULL) {
1455 for (n = 0; n < nStreams; n++) {
1456 if (ppOptions[n] != NULL)
1457 memcpy(ppOptions[n], pSavedOptions + n, sizeof(AVICOMPRESSOPTIONS));
1460 GlobalFreePtr(pSavedOptions);
1466 /***********************************************************************
1467 * AVISaveOptionsFree (AVIFIL32.@)
1468 * AVISaveOptionsFree (AVIFILE.124)
1470 HRESULT WINAPI AVISaveOptionsFree(INT nStreams,LPAVICOMPRESSOPTIONS*ppOptions)
1472 TRACE("(%d,%p)\n", nStreams, ppOptions);
1474 if (nStreams < 0 || ppOptions == NULL)
1475 return AVIERR_BADPARAM;
1477 for (; nStreams > 0; nStreams--) {
1478 if (ppOptions[nStreams] != NULL) {
1479 ppOptions[nStreams]->dwFlags &= ~AVICOMPRESSF_VALID;
1481 if (ppOptions[nStreams]->lpParms != NULL) {
1482 GlobalFreePtr(ppOptions[nStreams]->lpParms);
1483 ppOptions[nStreams]->lpParms = NULL;
1484 ppOptions[nStreams]->cbParms = 0;
1486 if (ppOptions[nStreams]->lpFormat != NULL) {
1487 GlobalFreePtr(ppOptions[nStreams]->lpFormat);
1488 ppOptions[nStreams]->lpFormat = NULL;
1489 ppOptions[nStreams]->cbFormat = 0;
1497 /***********************************************************************
1498 * AVISaveVA (AVIFIL32.@)
1500 HRESULT WINAPI AVISaveVA(LPCSTR szFile, CLSID *pclsidHandler,
1501 AVISAVECALLBACK lpfnCallback, int nStream,
1502 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions)
1504 LPWSTR wszFile = NULL;
1508 TRACE("%s,%p,%p,%d,%p,%p)\n", debugstr_a(szFile), pclsidHandler,
1509 lpfnCallback, nStream, ppavi, plpOptions);
1511 if (szFile == NULL || ppavi == NULL || plpOptions == NULL)
1512 return AVIERR_BADPARAM;
1514 /* convert ASCII string to Unicode and call Unicode function */
1515 len = lstrlenA(szFile);
1517 return AVIERR_BADPARAM;
1519 wszFile = (LPWSTR)LocalAlloc(LPTR, (len + 1) * sizeof(WCHAR));
1520 if (wszFile == NULL)
1521 return AVIERR_MEMORY;
1523 MultiByteToWideChar(CP_ACP, 0, szFile, -1, wszFile, len + 1);
1524 wszFile[len + 1] = 0;
1526 hr = AVISaveVW(wszFile, pclsidHandler, lpfnCallback,
1527 nStream, ppavi, plpOptions);
1529 LocalFree((HLOCAL)wszFile);
1534 /***********************************************************************
1535 * AVIFILE_AVISaveDefaultCallback (internal)
1537 static BOOL WINAPI AVIFILE_AVISaveDefaultCallback(INT progress)
1539 TRACE("(%d)\n", progress);
1544 /***********************************************************************
1545 * AVISaveVW (AVIFIL32.@)
1547 HRESULT WINAPI AVISaveVW(LPCWSTR szFile, CLSID *pclsidHandler,
1548 AVISAVECALLBACK lpfnCallback, int nStreams,
1549 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions)
1551 LONG lStart[MAX_AVISTREAMS];
1552 PAVISTREAM pOutStreams[MAX_AVISTREAMS];
1553 PAVISTREAM pInStreams[MAX_AVISTREAMS];
1555 AVISTREAMINFOW sInfo;
1557 PAVIFILE pfile = NULL; /* the output AVI file */
1558 LONG lFirstVideo = -1;
1561 /* for interleaving ... */
1562 DWORD dwInterleave = 0; /* interleave rate */
1563 DWORD dwFileInitialFrames;
1567 /* for reading/writing the data ... */
1568 LPVOID lpBuffer = NULL;
1569 LONG cbBuffer; /* real size of lpBuffer */
1570 LONG lBufferSize; /* needed bytes for format(s), etc. */
1575 TRACE("(%s,%p,%p,%d,%p,%p)\n", debugstr_w(szFile), pclsidHandler,
1576 lpfnCallback, nStreams, ppavi, plpOptions);
1578 if (szFile == NULL || ppavi == NULL || plpOptions == NULL)
1579 return AVIERR_BADPARAM;
1580 if (nStreams >= MAX_AVISTREAMS) {
1581 WARN("Can't write AVI with %d streams only supports %d -- change MAX_AVISTREAMS!\n", nStreams, MAX_AVISTREAMS);
1582 return AVIERR_INTERNAL;
1585 if (lpfnCallback == NULL)
1586 lpfnCallback = AVIFILE_AVISaveDefaultCallback;
1588 /* clear local variable(s) */
1589 for (curStream = 0; curStream < nStreams; curStream++) {
1590 pInStreams[curStream] = NULL;
1591 pOutStreams[curStream] = NULL;
1594 /* open output AVI file (create it if it doesn't exist) */
1595 hres = AVIFileOpenW(&pfile, szFile, OF_CREATE|OF_SHARE_EXCLUSIVE|OF_WRITE,
1599 AVIFileInfoW(pfile, &fInfo, sizeof(fInfo)); /* for dwCaps */
1601 /* initialize our data structures part 1 */
1602 for (curStream = 0; curStream < nStreams; curStream++) {
1603 PAVISTREAM pCurStream = ppavi[curStream];
1605 hres = AVIStreamInfoW(pCurStream, &sInfo, sizeof(sInfo));
1609 /* search first video stream and check for interleaving */
1610 if (sInfo.fccType == streamtypeVIDEO) {
1611 /* remember first video stream -- needed for interleaving */
1612 if (lFirstVideo < 0)
1613 lFirstVideo = curStream;
1614 } else if (!dwInterleave && plpOptions != NULL) {
1615 /* check if any non-video stream wants to be interleaved */
1616 WARN("options.flags=0x%lX options.dwInterleave=%lu\n",plpOptions[curStream]->dwFlags,plpOptions[curStream]->dwInterleaveEvery);
1617 if (plpOptions[curStream] != NULL &&
1618 plpOptions[curStream]->dwFlags & AVICOMPRESSF_INTERLEAVE)
1619 dwInterleave = plpOptions[curStream]->dwInterleaveEvery;
1622 /* create de-/compressed stream interface if needed */
1623 pInStreams[curStream] = NULL;
1624 if (plpOptions != NULL && plpOptions[curStream] != NULL) {
1625 if (plpOptions[curStream]->fccHandler ||
1626 plpOptions[curStream]->lpFormat != NULL) {
1627 DWORD dwKeySave = plpOptions[curStream]->dwKeyFrameEvery;
1629 if (fInfo.dwCaps & AVIFILECAPS_ALLKEYFRAMES)
1630 plpOptions[curStream]->dwKeyFrameEvery = 1;
1632 hres = AVIMakeCompressedStream(&pInStreams[curStream], pCurStream,
1633 plpOptions[curStream], NULL);
1634 plpOptions[curStream]->dwKeyFrameEvery = dwKeySave;
1635 if (FAILED(hres) || pInStreams[curStream] == NULL) {
1636 pInStreams[curStream] = NULL;
1640 /* test stream interface and update stream-info */
1641 hres = AVIStreamInfoW(pInStreams[curStream], &sInfo, sizeof(sInfo));
1647 /* now handle streams which will only be copied */
1648 if (pInStreams[curStream] == NULL) {
1649 pCurStream = pInStreams[curStream] = ppavi[curStream];
1650 AVIStreamAddRef(pCurStream);
1652 pCurStream = pInStreams[curStream];
1654 lStart[curStream] = sInfo.dwStart;
1655 } /* for all streams */
1657 /* check that first video stream is the first stream */
1658 if (lFirstVideo > 0) {
1659 PAVISTREAM pTmp = pInStreams[lFirstVideo];
1660 LONG lTmp = lStart[lFirstVideo];
1662 pInStreams[lFirstVideo] = pInStreams[0];
1663 pInStreams[0] = pTmp;
1664 lStart[lFirstVideo] = lStart[0];
1669 /* allocate buffer for formats, data, etc. of an initiale size of 64 kByte */
1670 lpBuffer = GlobalAllocPtr(GPTR, cbBuffer = 0x00010000);
1671 if (lpBuffer == NULL) {
1672 hres = AVIERR_MEMORY;
1676 AVIStreamInfoW(pInStreams[0], &sInfo, sizeof(sInfo));
1677 lFileLength = sInfo.dwLength;
1678 dwFileInitialFrames = 0;
1679 if (lFirstVideo >= 0) {
1680 /* check for correct version of the format
1681 * -- need atleast BITMAPINFOHEADER or newer
1684 lBufferSize = cbBuffer;
1685 hres = AVIStreamReadFormat(pInStreams[lFirstVideo], AVIStreamStart(pInStreams[lFirstVideo]), lpBuffer, &lBufferSize);
1686 if (lBufferSize < (LONG)sizeof(BITMAPINFOHEADER))
1687 hres = AVIERR_INTERNAL;
1690 } else /* use one second blocks for interleaving if no video present */
1691 lSampleInc = AVIStreamTimeToSample(pInStreams[0], 1000000);
1693 /* create output streams */
1694 for (curStream = 0; curStream < nStreams; curStream++) {
1695 AVIStreamInfoW(pInStreams[curStream], &sInfo, sizeof(sInfo));
1697 sInfo.dwInitialFrames = 0;
1698 if (dwInterleave != 0 && curStream > 0 && sInfo.fccType != streamtypeVIDEO) {
1699 /* 750 ms initial frames for non-video streams */
1700 sInfo.dwInitialFrames = AVIStreamTimeToSample(pInStreams[0], 750);
1703 hres = AVIFileCreateStreamW(pfile, &pOutStreams[curStream], &sInfo);
1704 if (pOutStreams[curStream] != NULL && SUCCEEDED(hres)) {
1705 /* copy initial format for this stream */
1706 lBufferSize = cbBuffer;
1707 hres = AVIStreamReadFormat(pInStreams[curStream], sInfo.dwStart,
1708 lpBuffer, &lBufferSize);
1711 hres = AVIStreamSetFormat(pOutStreams[curStream], 0, lpBuffer, lBufferSize);
1715 /* try to copy stream handler data */
1716 lBufferSize = cbBuffer;
1717 hres = AVIStreamReadData(pInStreams[curStream], ckidSTREAMHANDLERDATA,
1718 lpBuffer, &lBufferSize);
1719 if (SUCCEEDED(hres) && lBufferSize > 0) {
1720 hres = AVIStreamWriteData(pOutStreams[curStream],ckidSTREAMHANDLERDATA,
1721 lpBuffer, lBufferSize);
1726 if (dwFileInitialFrames < sInfo.dwInitialFrames)
1727 dwFileInitialFrames = sInfo.dwInitialFrames;
1729 AVIStreamSampleToSample(pOutStreams[0], pInStreams[curStream],
1731 if (lFileLength < lReadBytes)
1732 lFileLength = lReadBytes;
1734 /* creation of de-/compression stream interface failed */
1735 WARN("creation of (de-)compression stream failed for stream %d\n",curStream);
1736 AVIStreamRelease(pInStreams[curStream]);
1737 if (curStream + 1 >= nStreams) {
1738 /* move the others one up */
1739 PAVISTREAM *ppas = &pInStreams[curStream];
1740 int n = nStreams - (curStream + 1);
1743 *ppas = pInStreams[curStream + 1];
1749 } /* create output streams for all input streams */
1751 /* have we still something to write, or lost everything? */
1756 LONG lCurFrame = -dwFileInitialFrames;
1758 /* interleaved file */
1759 if (dwInterleave == 1)
1760 AVIFileEndRecord(pfile);
1762 for (; lCurFrame < lFileLength; lCurFrame += lSampleInc) {
1763 for (curStream = 0; curStream < nStreams; curStream++) {
1766 hres = AVIStreamInfoW(pOutStreams[curStream], &sInfo, sizeof(sInfo));
1770 /* initial frames phase at the end for this stream? */
1771 if (-(LONG)sInfo.dwInitialFrames > lCurFrame)
1774 if ((lFileLength - lSampleInc) <= lCurFrame) {
1775 lLastSample = AVIStreamLength(pInStreams[curStream]);
1776 lFirstVideo = lLastSample + AVIStreamStart(pInStreams[curStream]);
1778 if (curStream != 0) {
1780 AVIStreamSampleToSample(pInStreams[curStream], pInStreams[0],
1781 (sInfo.fccType == streamtypeVIDEO ?
1782 (LONG)dwInterleave : lSampleInc) +
1783 sInfo.dwInitialFrames + lCurFrame);
1785 lFirstVideo = lSampleInc + (sInfo.dwInitialFrames + lCurFrame);
1787 lLastSample = AVIStreamEnd(pInStreams[curStream]);
1788 if (lLastSample <= lFirstVideo)
1789 lFirstVideo = lLastSample;
1792 /* copy needed samples now */
1793 WARN("copy from stream %d samples %ld to %ld...\n",curStream,
1794 lStart[curStream],lFirstVideo);
1795 while (lFirstVideo > lStart[curStream]) {
1798 /* copy format for case it can change */
1799 lBufferSize = cbBuffer;
1800 hres = AVIStreamReadFormat(pInStreams[curStream], lStart[curStream],
1801 lpBuffer, &lBufferSize);
1804 AVIStreamSetFormat(pOutStreams[curStream], lStart[curStream],
1805 lpBuffer, lBufferSize);
1807 /* try to read data until we got it, or error */
1809 hres = AVIStreamRead(pInStreams[curStream], lStart[curStream],
1810 lFirstVideo - lStart[curStream], lpBuffer,
1811 cbBuffer, &lReadBytes, &lReadSamples);
1812 } while ((hres == AVIERR_BUFFERTOOSMALL) &&
1813 (lpBuffer = GlobalReAllocPtr(lpBuffer, cbBuffer *= 2, GPTR)) != NULL);
1814 if (lpBuffer == NULL)
1815 hres = AVIERR_MEMORY;
1819 if (AVIStreamIsKeyFrame(pInStreams[curStream], (LONG)sInfo.dwStart))
1820 flags = AVIIF_KEYFRAME;
1821 hres = AVIStreamWrite(pOutStreams[curStream], -1, lReadSamples,
1822 lpBuffer, lReadBytes, flags, NULL, NULL);
1826 lStart[curStream] += lReadSamples;
1828 lStart[curStream] = lFirstVideo;
1829 } /* stream by stream */
1831 /* need to close this block? */
1832 if (dwInterleave == 1) {
1833 hres = AVIFileEndRecord(pfile);
1839 if (lpfnCallback(MulDiv(dwFileInitialFrames + lCurFrame, 100,
1840 dwFileInitialFrames + lFileLength))) {
1841 hres = AVIERR_USERABORT;
1844 } /* copy frame by frame */
1846 /* non-interleaved file */
1848 for (curStream = 0; curStream < nStreams; curStream++) {
1850 if (lpfnCallback(MulDiv(curStream, 100, nStreams))) {
1851 hres = AVIERR_USERABORT;
1855 AVIStreamInfoW(pInStreams[curStream], &sInfo, sizeof(sInfo));
1857 if (sInfo.dwSampleSize != 0) {
1858 /* sample-based data like audio */
1859 while (sInfo.dwStart < sInfo.dwLength) {
1860 LONG lSamples = cbBuffer / sInfo.dwSampleSize;
1862 /* copy format for case it can change */
1863 lBufferSize = cbBuffer;
1864 hres = AVIStreamReadFormat(pInStreams[curStream], sInfo.dwStart,
1865 lpBuffer, &lBufferSize);
1868 AVIStreamSetFormat(pOutStreams[curStream], sInfo.dwStart,
1869 lpBuffer, lBufferSize);
1871 /* limit to stream boundaries */
1872 if (lSamples != (LONG)(sInfo.dwLength - sInfo.dwStart))
1873 lSamples = sInfo.dwLength - sInfo.dwStart;
1875 /* now try to read until we got it, or error occures */
1877 lReadBytes = cbBuffer;
1879 hres = AVIStreamRead(pInStreams[curStream],sInfo.dwStart,lSamples,
1880 lpBuffer,cbBuffer,&lReadBytes,&lReadSamples);
1881 } while ((hres == AVIERR_BUFFERTOOSMALL) &&
1882 (lpBuffer = GlobalReAllocPtr(lpBuffer, cbBuffer *= 2, GPTR)) != NULL);
1883 if (lpBuffer == NULL)
1884 hres = AVIERR_MEMORY;
1887 if (lReadSamples != 0) {
1888 sInfo.dwStart += lReadSamples;
1889 hres = AVIStreamWrite(pOutStreams[curStream], -1, lReadSamples,
1890 lpBuffer, lReadBytes, 0, NULL , NULL);
1895 if (lpfnCallback(MulDiv(sInfo.dwStart,100,nStreams*sInfo.dwLength)+
1896 MulDiv(curStream, 100, nStreams))) {
1897 hres = AVIERR_USERABORT;
1901 if ((sInfo.dwLength - sInfo.dwStart) != 1) {
1902 hres = AVIERR_FILEREAD;
1908 /* block-based data like video */
1909 for (; sInfo.dwStart < sInfo.dwLength; sInfo.dwStart++) {
1912 /* copy format for case it can change */
1913 lBufferSize = cbBuffer;
1914 hres = AVIStreamReadFormat(pInStreams[curStream], sInfo.dwStart,
1915 lpBuffer, &lBufferSize);
1918 AVIStreamSetFormat(pOutStreams[curStream], sInfo.dwStart,
1919 lpBuffer, lBufferSize);
1921 /* try to read block and resize buffer if necessary */
1924 lReadBytes = cbBuffer;
1925 hres = AVIStreamRead(pInStreams[curStream], sInfo.dwStart, 1,
1926 lpBuffer, cbBuffer,&lReadBytes,&lReadSamples);
1927 } while ((hres == AVIERR_BUFFERTOOSMALL) &&
1928 (lpBuffer = GlobalReAllocPtr(lpBuffer, cbBuffer *= 2, GPTR)) != NULL);
1929 if (lpBuffer == NULL)
1930 hres = AVIERR_MEMORY;
1933 if (lReadSamples != 1) {
1934 hres = AVIERR_FILEREAD;
1938 if (AVIStreamIsKeyFrame(pInStreams[curStream], (LONG)sInfo.dwStart))
1939 flags = AVIIF_KEYFRAME;
1940 hres = AVIStreamWrite(pOutStreams[curStream], -1, lReadSamples,
1941 lpBuffer, lReadBytes, flags, NULL, NULL);
1946 if (lpfnCallback(MulDiv(sInfo.dwStart,100,nStreams*sInfo.dwLength)+
1947 MulDiv(curStream, 100, nStreams))) {
1948 hres = AVIERR_USERABORT;
1951 } /* copy all blocks */
1953 } /* copy data stream by stream */
1957 if (lpBuffer != NULL)
1958 GlobalFreePtr(lpBuffer);
1959 if (pfile != NULL) {
1960 for (curStream = 0; curStream < nStreams; curStream++) {
1961 if (pOutStreams[curStream] != NULL)
1962 AVIStreamRelease(pOutStreams[curStream]);
1963 if (pInStreams[curStream] != NULL)
1964 AVIStreamRelease(pInStreams[curStream]);
1967 AVIFileRelease(pfile);
1973 /***********************************************************************
1974 * CreateEditableStream (AVIFIL32.@)
1976 HRESULT WINAPI CreateEditableStream(PAVISTREAM *ppEditable, PAVISTREAM pSource)
1978 IAVIEditStream *pEdit = NULL;
1981 FIXME("(%p,%p), semi stub!\n", ppEditable, pSource);
1983 if (ppEditable == NULL)
1984 return AVIERR_BADPARAM;
1988 if (pSource != NULL) {
1989 hr = IAVIStream_QueryInterface(pSource, &IID_IAVIEditStream,
1991 if (FAILED(hr) || pEdit == NULL) {
1992 /* need own implementation of IAVIEditStream */
1994 return AVIERR_UNSUPPORTED;
1998 hr = IAVIEditStream_Clone(pEdit, ppEditable);
1999 IAVIEditStream_Release(pEdit);
2004 /***********************************************************************
2005 * EditStreamClone (AVIFIL32.@)
2007 HRESULT WINAPI EditStreamClone(PAVISTREAM pStream, PAVISTREAM *ppResult)
2009 PAVIEDITSTREAM pEdit = NULL;
2012 TRACE("(%p,%p)\n", pStream, ppResult);
2014 if (pStream == NULL)
2015 return AVIERR_BADHANDLE;
2016 if (ppResult == NULL)
2017 return AVIERR_BADPARAM;
2021 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
2022 if (SUCCEEDED(hr) && pEdit != NULL) {
2023 hr = IAVIEditStream_Clone(pEdit, ppResult);
2025 IAVIEditStream_Release(pEdit);
2027 hr = AVIERR_UNSUPPORTED;
2032 /***********************************************************************
2033 * EditStreamCopy (AVIFIL32.@)
2035 HRESULT WINAPI EditStreamCopy(PAVISTREAM pStream, LONG *plStart,
2036 LONG *plLength, PAVISTREAM *ppResult)
2038 PAVIEDITSTREAM pEdit = NULL;
2041 TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult);
2043 if (pStream == NULL)
2044 return AVIERR_BADHANDLE;
2045 if (plStart == NULL || plLength == NULL || ppResult == NULL)
2046 return AVIERR_BADPARAM;
2050 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
2051 if (SUCCEEDED(hr) && pEdit != NULL) {
2052 hr = IAVIEditStream_Copy(pEdit, plStart, plLength, ppResult);
2054 IAVIEditStream_Release(pEdit);
2056 hr = AVIERR_UNSUPPORTED;
2061 /***********************************************************************
2062 * EditStreamCut (AVIFIL32.@)
2064 HRESULT WINAPI EditStreamCut(PAVISTREAM pStream, LONG *plStart,
2065 LONG *plLength, PAVISTREAM *ppResult)
2067 PAVIEDITSTREAM pEdit = NULL;
2070 TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult);
2072 if (pStream == NULL)
2073 return AVIERR_BADHANDLE;
2074 if (plStart == NULL || plLength == NULL || ppResult == NULL)
2075 return AVIERR_BADPARAM;
2079 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
2080 if (SUCCEEDED(hr) && pEdit != NULL) {
2081 hr = IAVIEditStream_Cut(pEdit, plStart, plLength, ppResult);
2083 IAVIEditStream_Release(pEdit);
2085 hr = AVIERR_UNSUPPORTED;
2090 /***********************************************************************
2091 * EditStreamPaste (AVIFIL32.@)
2093 HRESULT WINAPI EditStreamPaste(PAVISTREAM pDest, LONG *plStart, LONG *plLength,
2094 PAVISTREAM pSource, LONG lStart, LONG lEnd)
2096 PAVIEDITSTREAM pEdit = NULL;
2099 TRACE("(%p,%p,%p,%p,%ld,%ld)\n", pDest, plStart, plLength,
2100 pSource, lStart, lEnd);
2102 if (pDest == NULL || pSource == NULL)
2103 return AVIERR_BADHANDLE;
2104 if (plStart == NULL || plLength == NULL || lStart < 0)
2105 return AVIERR_BADPARAM;
2107 hr = IAVIStream_QueryInterface(pDest, &IID_IAVIEditStream,(LPVOID*)&pEdit);
2108 if (SUCCEEDED(hr) && pEdit != NULL) {
2109 hr = IAVIEditStream_Paste(pEdit, plStart, plLength, pSource, lStart, lEnd);
2111 IAVIEditStream_Release(pEdit);
2113 hr = AVIERR_UNSUPPORTED;
2118 /***********************************************************************
2119 * EditStreamSetInfoA (AVIFIL32.@)
2121 HRESULT WINAPI EditStreamSetInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi,
2124 AVISTREAMINFOW asiw;
2126 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
2128 if (pstream == NULL)
2129 return AVIERR_BADHANDLE;
2130 if ((DWORD)size < sizeof(AVISTREAMINFOA))
2131 return AVIERR_BADSIZE;
2133 memcpy(&asiw, asi, sizeof(asi) - sizeof(asi->szName));
2134 MultiByteToWideChar(CP_ACP, 0, asi->szName, -1,
2135 asiw.szName, sizeof(asiw.szName));
2137 return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw));
2140 /***********************************************************************
2141 * EditStreamSetInfoW (AVIFIL32.@)
2143 HRESULT WINAPI EditStreamSetInfoW(PAVISTREAM pstream, LPAVISTREAMINFOW asi,
2146 PAVIEDITSTREAM pEdit = NULL;
2149 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
2151 hr = IAVIStream_QueryInterface(pstream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
2152 if (SUCCEEDED(hr) && pEdit != NULL) {
2153 hr = IAVIEditStream_SetInfo(pEdit, asi, size);
2155 IAVIEditStream_Release(pEdit);
2157 hr = AVIERR_UNSUPPORTED;
2162 /***********************************************************************
2163 * EditStreamSetNameA (AVIFIL32.@)
2165 HRESULT WINAPI EditStreamSetNameA(PAVISTREAM pstream, LPCSTR szName)
2167 AVISTREAMINFOA asia;
2170 TRACE("(%p,%s)\n", pstream, debugstr_a(szName));
2172 if (pstream == NULL)
2173 return AVIERR_BADHANDLE;
2175 return AVIERR_BADPARAM;
2177 hres = AVIStreamInfoA(pstream, &asia, sizeof(asia));
2181 memset(asia.szName, 0, sizeof(asia.szName));
2182 lstrcpynA(asia.szName, szName, sizeof(asia.szName)/sizeof(asia.szName[0]));
2184 return EditStreamSetInfoA(pstream, &asia, sizeof(asia));
2187 /***********************************************************************
2188 * EditStreamSetNameW (AVIFIL32.@)
2190 HRESULT WINAPI EditStreamSetNameW(PAVISTREAM pstream, LPCWSTR szName)
2192 AVISTREAMINFOW asiw;
2195 TRACE("(%p,%s)\n", pstream, debugstr_w(szName));
2197 if (pstream == NULL)
2198 return AVIERR_BADHANDLE;
2200 return AVIERR_BADPARAM;
2202 hres = IAVIStream_Info(pstream, &asiw, sizeof(asiw));
2206 memset(asiw.szName, 0, sizeof(asiw.szName));
2207 lstrcpynW(asiw.szName, szName, sizeof(asiw.szName)/sizeof(asiw.szName[0]));
2209 return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw));
2212 /***********************************************************************
2213 * AVIClearClipboard (AVIFIL32.@)
2215 HRESULT WINAPI AVIClearClipboard(void)
2219 return AVIERR_UNSUPPORTED; /* OleSetClipboard(NULL); */
2222 /***********************************************************************
2223 * AVIGetFromClipboard (AVIFIL32.@)
2225 HRESULT WINAPI AVIGetFromClipboard(PAVIFILE *ppfile)
2227 FIXME("(%p), stub!\n", ppfile);
2231 return AVIERR_UNSUPPORTED;
2234 /***********************************************************************
2235 * AVIPutFileOnClipboard (AVIFIL32.@)
2237 HRESULT WINAPI AVIPutFileOnClipboard(PAVIFILE pfile)
2239 FIXME("(%p), stub!\n", pfile);
2242 return AVIERR_BADHANDLE;
2244 return AVIERR_UNSUPPORTED;