2 * Copyright 1999 Marcus Meissner
3 * Copyright 2002 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 * AVIStreamStart (AVIFILE.130)
839 * AVIStreamStart (AVIFIL32.@)
841 LONG WINAPI AVIStreamStart(PAVISTREAM pstream)
845 TRACE("(%p)\n", pstream);
850 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
856 /***********************************************************************
857 * AVIStreamLength (AVIFILE.131)
858 * AVIStreamLength (AVIFIL32.@)
860 LONG WINAPI AVIStreamLength(PAVISTREAM pstream)
864 TRACE("(%p)\n", pstream);
869 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
872 return asiw.dwLength;
875 /***********************************************************************
876 * AVIStreamSampleToTime (AVIFILE.133)
877 * AVIStreamSampleToTime (AVIFIL32.@)
879 LONG WINAPI AVIStreamSampleToTime(PAVISTREAM pstream, LONG lSample)
883 TRACE("(%p,%ld)\n", pstream, lSample);
888 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
890 if (asiw.dwRate == 0)
893 return (LONG)(((float)lSample * asiw.dwScale * 1000.0) / asiw.dwRate);
896 /***********************************************************************
897 * AVIStreamTimeToSample (AVIFILE.132)
898 * AVIStreamTimeToSample (AVIFIL32.@)
900 LONG WINAPI AVIStreamTimeToSample(PAVISTREAM pstream, LONG lTime)
904 TRACE("(%p,%ld)\n", pstream, lTime);
909 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
911 if (asiw.dwScale == 0)
914 return (LONG)(((float)lTime * asiw.dwRate) / asiw.dwScale / 1000.0);
917 /***********************************************************************
918 * AVIBuildFilterA (AVIFIL32.@)
919 * AVIBuildFilter (AVIFILE.123)
921 HRESULT WINAPI AVIBuildFilterA(LPSTR szFilter, LONG cbFilter, BOOL fSaving)
926 TRACE("(%p,%ld,%d)\n", szFilter, cbFilter, fSaving);
928 /* check parameters */
929 if (szFilter == NULL)
930 return AVIERR_BADPARAM;
932 return AVIERR_BADSIZE;
937 wszFilter = (LPWSTR)GlobalAllocPtr(GHND, cbFilter);
938 if (wszFilter == NULL)
939 return AVIERR_MEMORY;
941 hr = AVIBuildFilterW(wszFilter, cbFilter, fSaving);
943 WideCharToMultiByte(CP_ACP, 0, wszFilter, cbFilter,
944 szFilter, cbFilter, NULL, NULL);
947 GlobalFreePtr(wszFilter);
952 /***********************************************************************
953 * AVIBuildFilterW (AVIFIL32.@)
955 HRESULT WINAPI AVIBuildFilterW(LPWSTR szFilter, LONG cbFilter, BOOL fSaving)
957 static const WCHAR szClsid[] = {'C','L','S','I','D',0};
958 static const WCHAR szExtensionFmt[] = {';','*','.','%','s',0};
959 static const WCHAR szAVIFileExtensions[] =
960 {'A','V','I','F','i','l','e','\\','E','x','t','e','n','s','i','o','n','s',0};
963 WCHAR szAllFiles[40];
971 TRACE("(%p,%ld,%d)\n", szFilter, cbFilter, fSaving);
973 /* check parameters */
974 if (szFilter == NULL)
975 return AVIERR_BADPARAM;
977 return AVIERR_BADSIZE;
979 lp = (AVIFilter*)GlobalAllocPtr(GHND, MAX_FILTERS * sizeof(AVIFilter));
981 return AVIERR_MEMORY;
984 * 1. iterate over HKEY_CLASSES_ROOT\\AVIFile\\Extensions and collect
985 * extensions and CLSID's
986 * 2. iterate over collected CLSID's and copy it's description and it's
987 * extensions to szFilter if it fits
989 * First filter is named "All multimedia files" and it's filter is a
990 * collection of all possible extensions except "*.*".
992 if (RegOpenKeyW(HKEY_CLASSES_ROOT, szAVIFileExtensions, &hKey) != S_OK) {
996 for (n = 0;RegEnumKeyW(hKey, n, szFileExt, sizeof(szFileExt)) == S_OK;n++) {
997 /* get CLSID to extension */
998 size = sizeof(szValue)/sizeof(szValue[0]);
999 if (RegQueryValueW(hKey, szFileExt, szValue, &size) != S_OK)
1002 /* search if the CLSID is already known */
1003 for (i = 1; i <= count; i++) {
1004 if (lstrcmpW(lp[i].szClsid, szValue) == 0)
1005 break; /* a new one */
1008 if (count - i == -1U) {
1009 /* it's a new CLSID */
1011 /* FIXME: How do we get info's about read/write capabilities? */
1013 if (count >= MAX_FILTERS) {
1014 /* try to inform user of our full fixed size table */
1015 ERR(": More than %d filters found! Adjust MAX_FILTERS in dlls/avifil32/api.c\n", MAX_FILTERS);
1019 lstrcpyW(lp[i].szClsid, szValue);
1024 /* append extension to the filter */
1025 wsprintfW(szValue, szExtensionFmt, szFileExt);
1026 if (lp[i].szExtensions[0] == 0)
1027 lstrcatW(lp[i].szExtensions, szValue + 1);
1029 lstrcatW(lp[i].szExtensions, szValue);
1031 /* also append to the "all multimedia"-filter */
1032 if (lp[0].szExtensions[0] == 0)
1033 lstrcatW(lp[0].szExtensions, szValue + 1);
1035 lstrcatW(lp[0].szExtensions, szValue);
1039 /* 2. get descriptions for the CLSIDs and fill out szFilter */
1040 if (RegOpenKeyW(HKEY_CLASSES_ROOT, szClsid, &hKey) != S_OK) {
1042 return AVIERR_ERROR;
1044 for (n = 0; n <= count; n++) {
1045 /* first the description */
1047 size = sizeof(szValue)/sizeof(szValue[0]);
1048 if (RegQueryValueW(hKey, lp[n].szClsid, szValue, &size) == S_OK) {
1049 size = lstrlenW(szValue);
1050 lstrcpynW(szFilter, szValue, cbFilter);
1053 size = LoadStringW(AVIFILE_hModule,IDS_ALLMULTIMEDIA,szFilter,cbFilter);
1055 /* check for enough space */
1057 if (cbFilter < size + lstrlenW(lp[n].szExtensions) + 2) {
1062 return AVIERR_BUFFERTOOSMALL;
1067 /* and then the filter */
1068 lstrcpynW(szFilter, lp[n].szExtensions, cbFilter);
1069 size = lstrlenW(lp[n].szExtensions) + 1;
1077 /* add "All files" "*.*" filter if enough space left */
1078 size = LoadStringW(AVIFILE_hModule, IDS_ALLFILES,
1079 szAllFiles, sizeof(szAllFiles)) + 1;
1080 if (cbFilter > size) {
1083 /* replace '@' with \000 to separate description of filter */
1084 for (i = 0; i < size && szAllFiles[i] != 0; i++) {
1085 if (szAllFiles[i] == '@') {
1091 memcpy(szFilter, szAllFiles, size * sizeof(szAllFiles[0]));
1098 return AVIERR_BUFFERTOOSMALL;
1102 static BOOL AVISaveOptionsFmtChoose(HWND hWnd)
1104 LPAVICOMPRESSOPTIONS pOptions = SaveOpts.ppOptions[SaveOpts.nCurrent];
1105 AVISTREAMINFOW sInfo;
1107 TRACE("(%p)\n", hWnd);
1109 if (pOptions == NULL || SaveOpts.ppavis[SaveOpts.nCurrent] == NULL) {
1110 ERR(": bad state!\n");
1114 if (FAILED(AVIStreamInfoW(SaveOpts.ppavis[SaveOpts.nCurrent],
1115 &sInfo, sizeof(sInfo)))) {
1116 ERR(": AVIStreamInfoW failed!\n");
1120 if (sInfo.fccType == streamtypeVIDEO) {
1124 memset(&cv, 0, sizeof(cv));
1126 if ((pOptions->dwFlags & AVICOMPRESSF_VALID) == 0) {
1127 memset(pOptions, 0, sizeof(AVICOMPRESSOPTIONS));
1128 pOptions->fccType = streamtypeVIDEO;
1129 pOptions->fccHandler = comptypeDIB;
1130 pOptions->dwQuality = (DWORD)ICQUALITY_DEFAULT;
1133 cv.cbSize = sizeof(cv);
1134 cv.dwFlags = ICMF_COMPVARS_VALID;
1135 /*cv.fccType = pOptions->fccType; */
1136 cv.fccHandler = pOptions->fccHandler;
1137 cv.lQ = pOptions->dwQuality;
1138 cv.lpState = pOptions->lpParms;
1139 cv.cbState = pOptions->cbParms;
1140 if (pOptions->dwFlags & AVICOMPRESSF_KEYFRAMES)
1141 cv.lKey = pOptions->dwKeyFrameEvery;
1144 if (pOptions->dwFlags & AVICOMPRESSF_DATARATE)
1145 cv.lDataRate = pOptions->dwBytesPerSecond / 1024; /* need kBytes */
1149 ret = ICCompressorChoose(hWnd, SaveOpts.uFlags, NULL,
1150 SaveOpts.ppavis[SaveOpts.nCurrent], &cv, NULL);
1153 pOptions->fccHandler = cv.fccHandler;
1154 pOptions->lpParms = cv.lpState;
1155 pOptions->cbParms = cv.cbState;
1156 pOptions->dwQuality = cv.lQ;
1158 pOptions->dwKeyFrameEvery = cv.lKey;
1159 pOptions->dwFlags |= AVICOMPRESSF_KEYFRAMES;
1161 pOptions->dwFlags &= ~AVICOMPRESSF_KEYFRAMES;
1162 if (cv.lDataRate != 0) {
1163 pOptions->dwBytesPerSecond = cv.lDataRate * 1024; /* need bytes */
1164 pOptions->dwFlags |= AVICOMPRESSF_DATARATE;
1166 pOptions->dwFlags &= ~AVICOMPRESSF_DATARATE;
1167 pOptions->dwFlags |= AVICOMPRESSF_VALID;
1169 ICCompressorFree(&cv);
1172 } else if (sInfo.fccType == streamtypeAUDIO) {
1173 ACMFORMATCHOOSEW afmtc;
1177 /* FIXME: check ACM version -- Which version is needed? */
1179 memset(&afmtc, 0, sizeof(afmtc));
1180 afmtc.cbStruct = sizeof(afmtc);
1182 afmtc.hwndOwner = hWnd;
1184 acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, &size);
1185 if ((pOptions->cbFormat == 0 || pOptions->lpFormat == NULL) && size != 0) {
1186 pOptions->lpFormat = GlobalAllocPtr(GMEM_MOVEABLE, size);
1187 pOptions->cbFormat = size;
1188 } else if (pOptions->cbFormat < (DWORD)size) {
1189 pOptions->lpFormat = GlobalReAllocPtr(pOptions->lpFormat, size, GMEM_MOVEABLE);
1190 pOptions->cbFormat = size;
1192 if (pOptions->lpFormat == NULL)
1194 afmtc.pwfx = pOptions->lpFormat;
1195 afmtc.cbwfx = pOptions->cbFormat;
1198 AVIStreamFormatSize(SaveOpts.ppavis[SaveOpts.nCurrent],
1199 sInfo.dwStart, &size);
1200 if (size < (LONG)sizeof(PCMWAVEFORMAT))
1201 size = sizeof(PCMWAVEFORMAT);
1202 afmtc.pwfxEnum = GlobalAllocPtr(GHND, size);
1203 if (afmtc.pwfxEnum != NULL) {
1204 AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent],
1205 sInfo.dwStart, afmtc.pwfxEnum, &size);
1206 afmtc.fdwEnum = ACM_FORMATENUMF_CONVERT;
1209 ret = acmFormatChooseW(&afmtc);
1211 pOptions->dwFlags |= AVICOMPRESSF_VALID;
1213 if (afmtc.pwfxEnum != NULL)
1214 GlobalFreePtr(afmtc.pwfxEnum);
1216 return (ret == S_OK ? TRUE : FALSE);
1218 ERR(": unknown streamtype 0x%08lX\n", sInfo.fccType);
1223 static void AVISaveOptionsUpdate(HWND hWnd)
1225 static const WCHAR szVideoFmt[]={'%','l','d','x','%','l','d','x','%','d',0};
1226 static const WCHAR szAudioFmt[]={'%','s',' ','%','s',0};
1228 WCHAR szFormat[128];
1229 AVISTREAMINFOW sInfo;
1233 TRACE("(%p)\n", hWnd);
1235 SaveOpts.nCurrent = SendDlgItemMessageW(hWnd,IDC_STREAM,CB_GETCURSEL,0,0);
1236 if (SaveOpts.nCurrent < 0)
1239 if (FAILED(AVIStreamInfoW(SaveOpts.ppavis[SaveOpts.nCurrent], &sInfo, sizeof(sInfo))))
1242 AVIStreamFormatSize(SaveOpts.ppavis[SaveOpts.nCurrent],sInfo.dwStart,&size);
1246 /* read format to build format descriotion string */
1247 lpFormat = GlobalAllocPtr(GHND, size);
1248 if (lpFormat != NULL) {
1249 if (SUCCEEDED(AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent],sInfo.dwStart,lpFormat, &size))) {
1250 if (sInfo.fccType == streamtypeVIDEO) {
1251 LPBITMAPINFOHEADER lpbi = lpFormat;
1254 wsprintfW(szFormat, szVideoFmt, lpbi->biWidth,
1255 lpbi->biHeight, lpbi->biBitCount);
1257 if (lpbi->biCompression != BI_RGB) {
1260 hic = ICLocate(ICTYPE_VIDEO, sInfo.fccHandler, lpFormat,
1261 NULL, ICMODE_DECOMPRESS);
1263 if (ICGetInfo(hic, &icinfo, sizeof(icinfo)) == S_OK)
1264 lstrcatW(szFormat, icinfo.szDescription);
1268 LoadStringW(AVIFILE_hModule, IDS_UNCOMPRESSED,
1269 icinfo.szDescription, sizeof(icinfo.szDescription));
1270 lstrcatW(szFormat, icinfo.szDescription);
1272 } else if (sInfo.fccType == streamtypeAUDIO) {
1273 ACMFORMATTAGDETAILSW aftd;
1274 ACMFORMATDETAILSW afd;
1276 memset(&aftd, 0, sizeof(aftd));
1277 memset(&afd, 0, sizeof(afd));
1279 aftd.cbStruct = sizeof(aftd);
1280 aftd.dwFormatTag = afd.dwFormatTag =
1281 ((PWAVEFORMATEX)lpFormat)->wFormatTag;
1282 aftd.cbFormatSize = afd.cbwfx = size;
1284 afd.cbStruct = sizeof(afd);
1285 afd.pwfx = lpFormat;
1287 if (acmFormatTagDetailsW(NULL, &aftd,
1288 ACM_FORMATTAGDETAILSF_FORMATTAG) == S_OK) {
1289 if (acmFormatDetailsW(NULL,&afd,ACM_FORMATDETAILSF_FORMAT) == S_OK)
1290 wsprintfW(szFormat, szAudioFmt, afd.szFormat, aftd.szFormatTag);
1294 GlobalFreePtr(lpFormat);
1297 /* set text for format description */
1298 SetDlgItemTextW(hWnd, IDC_FORMATTEXT, szFormat);
1300 /* Disable option button for unsupported streamtypes */
1301 if (sInfo.fccType == streamtypeVIDEO ||
1302 sInfo.fccType == streamtypeAUDIO)
1303 EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), TRUE);
1305 EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), FALSE);
1310 INT_PTR CALLBACK AVISaveOptionsDlgProc(HWND hWnd, UINT uMsg,
1311 WPARAM wParam, LPARAM lParam)
1314 BOOL bIsInterleaved;
1317 /*TRACE("(%p,%u,0x%04X,0x%08lX)\n", hWnd, uMsg, wParam, lParam);*/
1321 SaveOpts.nCurrent = 0;
1322 if (SaveOpts.nStreams == 1) {
1323 EndDialog(hWnd, AVISaveOptionsFmtChoose(hWnd));
1328 for (n = 0; n < SaveOpts.nStreams; n++) {
1329 AVISTREAMINFOW sInfo;
1331 AVIStreamInfoW(SaveOpts.ppavis[n], &sInfo, sizeof(sInfo));
1332 SendDlgItemMessageW(hWnd, IDC_STREAM, CB_ADDSTRING,
1333 0L, (LPARAM)sInfo.szName);
1336 /* select first stream */
1337 SendDlgItemMessageW(hWnd, IDC_STREAM, CB_SETCURSEL, 0, 0);
1338 SendMessageW(hWnd, WM_COMMAND,
1339 GET_WM_COMMAND_MPS(IDC_STREAM, hWnd, CBN_SELCHANGE));
1341 /* initialize interleave */
1342 if (SaveOpts.ppOptions[0] != NULL &&
1343 (SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_VALID)) {
1344 bIsInterleaved = (SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_INTERLEAVE);
1345 dwInterleave = SaveOpts.ppOptions[0]->dwInterleaveEvery;
1347 bIsInterleaved = TRUE;
1350 CheckDlgButton(hWnd, IDC_INTERLEAVE, bIsInterleaved);
1351 SetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, dwInterleave, FALSE);
1352 EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY), bIsInterleaved);
1355 switch (GET_WM_COMMAND_ID(wParam, lParam)) {
1357 /* get data from controls and save them */
1358 dwInterleave = GetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, NULL, 0);
1359 bIsInterleaved = IsDlgButtonChecked(hWnd, IDC_INTERLEAVE);
1360 for (n = 0; n < SaveOpts.nStreams; n++) {
1361 if (SaveOpts.ppOptions[n] != NULL) {
1362 if (bIsInterleaved) {
1363 SaveOpts.ppOptions[n]->dwFlags |= AVICOMPRESSF_INTERLEAVE;
1364 SaveOpts.ppOptions[n]->dwInterleaveEvery = dwInterleave;
1366 SaveOpts.ppOptions[n]->dwFlags &= ~AVICOMPRESSF_INTERLEAVE;
1371 EndDialog(hWnd, GET_WM_COMMAND_CMD(wParam, lParam) == IDOK);
1373 case IDC_INTERLEAVE:
1374 EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY),
1375 IsDlgButtonChecked(hWnd, IDC_INTERLEAVE));
1378 if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE) {
1379 /* update control elements */
1380 AVISaveOptionsUpdate(hWnd);
1384 AVISaveOptionsFmtChoose(hWnd);
1393 /***********************************************************************
1394 * AVISaveOptions (AVIFIL32.@)
1396 BOOL WINAPI AVISaveOptions(HWND hWnd, UINT uFlags, INT nStreams,
1397 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *ppOptions)
1399 LPAVICOMPRESSOPTIONS pSavedOptions = NULL;
1402 TRACE("(%p,0x%X,%d,%p,%p)\n", hWnd, uFlags, nStreams,
1405 /* check parameters */
1406 if (nStreams <= 0 || ppavi == NULL || ppOptions == NULL)
1407 return AVIERR_BADPARAM;
1409 /* save options for case user press cancel */
1410 if (ppOptions != NULL && nStreams > 1) {
1411 pSavedOptions = GlobalAllocPtr(GHND,nStreams * sizeof(AVICOMPRESSOPTIONS));
1412 if (pSavedOptions == NULL)
1415 for (n = 0; n < nStreams; n++) {
1416 if (ppOptions[n] != NULL)
1417 memcpy(pSavedOptions + n, ppOptions[n], sizeof(AVICOMPRESSOPTIONS));
1421 SaveOpts.uFlags = uFlags;
1422 SaveOpts.nStreams = nStreams;
1423 SaveOpts.ppavis = ppavi;
1424 SaveOpts.ppOptions = ppOptions;
1426 ret = DialogBoxW(AVIFILE_hModule, MAKEINTRESOURCEW(IDD_SAVEOPTIONS),
1427 hWnd, AVISaveOptionsDlgProc);
1432 /* restore options when user pressed cancel */
1433 if (pSavedOptions != NULL && ret == FALSE) {
1434 for (n = 0; n < nStreams; n++) {
1435 if (ppOptions[n] != NULL)
1436 memcpy(ppOptions[n], pSavedOptions + n, sizeof(AVICOMPRESSOPTIONS));
1438 GlobalFreePtr(pSavedOptions);
1444 /***********************************************************************
1445 * AVISaveOptionsFree (AVIFIL32.@)
1446 * AVISaveOptionsFree (AVIFILE.124)
1448 HRESULT WINAPI AVISaveOptionsFree(INT nStreams,LPAVICOMPRESSOPTIONS*ppOptions)
1450 TRACE("(%d,%p)\n", nStreams, ppOptions);
1452 if (nStreams < 0 || ppOptions == NULL)
1453 return AVIERR_BADPARAM;
1455 for (; nStreams > 0; nStreams--) {
1456 if (ppOptions[nStreams] != NULL) {
1457 ppOptions[nStreams]->dwFlags &= ~AVICOMPRESSF_VALID;
1459 if (ppOptions[nStreams]->lpParms != NULL) {
1460 GlobalFreePtr(ppOptions[nStreams]->lpParms);
1461 ppOptions[nStreams]->lpParms = NULL;
1462 ppOptions[nStreams]->cbParms = 0;
1464 if (ppOptions[nStreams]->lpFormat != NULL) {
1465 GlobalFreePtr(ppOptions[nStreams]->lpFormat);
1466 ppOptions[nStreams]->lpFormat = NULL;
1467 ppOptions[nStreams]->cbFormat = 0;
1475 /***********************************************************************
1476 * AVISaveVA (AVIFIL32.@)
1478 HRESULT WINAPI AVISaveVA(LPCSTR szFile, CLSID *pclsidHandler,
1479 AVISAVECALLBACK lpfnCallback, int nStream,
1480 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions)
1482 LPWSTR wszFile = NULL;
1486 TRACE("%s,%p,%p,%d,%p,%p)\n", debugstr_a(szFile), pclsidHandler,
1487 lpfnCallback, nStream, ppavi, plpOptions);
1489 if (szFile == NULL || ppavi == NULL || plpOptions == NULL)
1490 return AVIERR_BADPARAM;
1492 /* convert ASCII string to Unicode and call Unicode function */
1493 len = lstrlenA(szFile);
1495 return AVIERR_BADPARAM;
1497 wszFile = (LPWSTR)LocalAlloc(LPTR, (len + 1) * sizeof(WCHAR));
1498 if (wszFile == NULL)
1499 return AVIERR_MEMORY;
1501 MultiByteToWideChar(CP_ACP, 0, szFile, -1, wszFile, len + 1);
1502 wszFile[len + 1] = 0;
1504 hr = AVISaveVW(wszFile, pclsidHandler, lpfnCallback,
1505 nStream, ppavi, plpOptions);
1507 LocalFree((HLOCAL)wszFile);
1512 /***********************************************************************
1513 * AVISaveVW (AVIFIL32.@)
1515 HRESULT WINAPI AVISaveVW(LPCWSTR szFile, CLSID *pclsidHandler,
1516 AVISAVECALLBACK lpfnCallback, int nStream,
1517 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions)
1519 FIXME("(%s,%p,%p,%d,%p,%p), stub!\n", debugstr_w(szFile), pclsidHandler,
1520 lpfnCallback, nStream, ppavi, plpOptions);
1522 if (szFile == NULL || ppavi == NULL || plpOptions == NULL)
1523 return AVIERR_BADPARAM;
1525 return AVIERR_UNSUPPORTED;
1528 /***********************************************************************
1529 * CreateEditableStream (AVIFIL32.@)
1531 HRESULT WINAPI CreateEditableStream(PAVISTREAM *ppEditable, PAVISTREAM pSource)
1533 FIXME("(%p,%p), stub!\n", ppEditable, pSource);
1535 if (pSource == NULL)
1536 return AVIERR_BADHANDLE;
1537 if (ppEditable == NULL)
1538 return AVIERR_BADPARAM;
1542 return AVIERR_UNSUPPORTED;
1545 /***********************************************************************
1546 * EditStreamClone (AVIFIL32.@)
1548 HRESULT WINAPI EditStreamClone(PAVISTREAM pStream, PAVISTREAM *ppResult)
1550 PAVIEDITSTREAM pEdit = NULL;
1553 TRACE("(%p,%p)\n", pStream, ppResult);
1555 if (pStream == NULL)
1556 return AVIERR_BADHANDLE;
1557 if (ppResult == NULL)
1558 return AVIERR_BADPARAM;
1562 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1563 if (SUCCEEDED(hr) && pEdit != NULL) {
1564 hr = IAVIEditStream_Clone(pEdit, ppResult);
1566 IAVIEditStream_Release(pEdit);
1568 hr = AVIERR_UNSUPPORTED;
1573 /***********************************************************************
1574 * EditStreamCopy (AVIFIL32.@)
1576 HRESULT WINAPI EditStreamCopy(PAVISTREAM pStream, LONG *plStart,
1577 LONG *plLength, PAVISTREAM *ppResult)
1579 PAVIEDITSTREAM pEdit = NULL;
1582 TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult);
1584 if (pStream == NULL)
1585 return AVIERR_BADHANDLE;
1586 if (plStart == NULL || plLength == NULL || ppResult == NULL)
1587 return AVIERR_BADPARAM;
1591 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1592 if (SUCCEEDED(hr) && pEdit != NULL) {
1593 hr = IAVIEditStream_Copy(pEdit, plStart, plLength, ppResult);
1595 IAVIEditStream_Release(pEdit);
1597 hr = AVIERR_UNSUPPORTED;
1602 /***********************************************************************
1603 * EditStreamCut (AVIFIL32.@)
1605 HRESULT WINAPI EditStreamCut(PAVISTREAM pStream, LONG *plStart,
1606 LONG *plLength, PAVISTREAM *ppResult)
1608 PAVIEDITSTREAM pEdit = NULL;
1611 TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult);
1613 if (pStream == NULL)
1614 return AVIERR_BADHANDLE;
1615 if (plStart == NULL || plLength == NULL || ppResult == NULL)
1616 return AVIERR_BADPARAM;
1620 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1621 if (SUCCEEDED(hr) && pEdit != NULL) {
1622 hr = IAVIEditStream_Cut(pEdit, plStart, plLength, ppResult);
1624 IAVIEditStream_Release(pEdit);
1626 hr = AVIERR_UNSUPPORTED;
1631 /***********************************************************************
1632 * EditStreamPaste (AVIFIL32.@)
1634 HRESULT WINAPI EditStreamPaste(PAVISTREAM pDest, LONG *plStart, LONG *plLength,
1635 PAVISTREAM pSource, LONG lStart, LONG lEnd)
1637 PAVIEDITSTREAM pEdit = NULL;
1640 TRACE("(%p,%p,%p,%p,%ld,%ld)\n", pDest, plStart, plLength,
1641 pSource, lStart, lEnd);
1643 if (pDest == NULL || pSource == NULL)
1644 return AVIERR_BADHANDLE;
1645 if (plStart == NULL || plLength == NULL || lStart < 0)
1646 return AVIERR_BADPARAM;
1648 hr = IAVIStream_QueryInterface(pDest, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1649 if (SUCCEEDED(hr) && pEdit != NULL) {
1650 hr = IAVIEditStream_Paste(pEdit, plStart, plLength, pSource, lStart, lEnd);
1652 IAVIEditStream_Release(pEdit);
1654 hr = AVIERR_UNSUPPORTED;
1659 /***********************************************************************
1660 * EditStreamSetInfoA (AVIFIL32.@)
1662 HRESULT WINAPI EditStreamSetInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi,
1665 AVISTREAMINFOW asiw;
1667 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
1669 if (pstream == NULL)
1670 return AVIERR_BADHANDLE;
1671 if ((DWORD)size < sizeof(AVISTREAMINFOA))
1672 return AVIERR_BADSIZE;
1674 memcpy(&asiw, asi, sizeof(asi) - sizeof(asi->szName));
1675 MultiByteToWideChar(CP_ACP, 0, asi->szName, -1,
1676 asiw.szName, sizeof(asiw.szName));
1678 return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw));
1681 /***********************************************************************
1682 * EditStreamSetInfoW (AVIFIL32.@)
1684 HRESULT WINAPI EditStreamSetInfoW(PAVISTREAM pstream, LPAVISTREAMINFOW asi,
1687 PAVIEDITSTREAM pEdit = NULL;
1690 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
1692 hr = IAVIStream_QueryInterface(pstream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1693 if (SUCCEEDED(hr) && pEdit != NULL) {
1694 hr = IAVIEditStream_SetInfo(pEdit, asi, size);
1696 IAVIEditStream_Release(pEdit);
1698 hr = AVIERR_UNSUPPORTED;
1703 /***********************************************************************
1704 * EditStreamSetNameA (AVIFIL32.@)
1706 HRESULT WINAPI EditStreamSetNameA(PAVISTREAM pstream, LPCSTR szName)
1708 AVISTREAMINFOA asia;
1711 TRACE("(%p,%s)\n", pstream, debugstr_a(szName));
1713 if (pstream == NULL)
1714 return AVIERR_BADHANDLE;
1716 return AVIERR_BADPARAM;
1718 hres = AVIStreamInfoA(pstream, &asia, sizeof(asia));
1722 memset(asia.szName, 0, sizeof(asia.szName));
1723 lstrcpynA(asia.szName, szName, sizeof(asia.szName)/sizeof(asia.szName[0]));
1725 return EditStreamSetInfoA(pstream, &asia, sizeof(asia));
1728 /***********************************************************************
1729 * EditStreamSetNameW (AVIFIL32.@)
1731 HRESULT WINAPI EditStreamSetNameW(PAVISTREAM pstream, LPCWSTR szName)
1733 AVISTREAMINFOW asiw;
1736 TRACE("(%p,%s)\n", pstream, debugstr_w(szName));
1738 if (pstream == NULL)
1739 return AVIERR_BADHANDLE;
1741 return AVIERR_BADPARAM;
1743 hres = IAVIStream_Info(pstream, &asiw, sizeof(asiw));
1747 memset(asiw.szName, 0, sizeof(asiw.szName));
1748 lstrcpynW(asiw.szName, szName, sizeof(asiw.szName)/sizeof(asiw.szName[0]));
1750 return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw));
1753 /***********************************************************************
1754 * AVIClearClipboard (AVIFIL32.@)
1756 HRESULT WINAPI AVIClearClipboard(void)
1760 return AVIERR_UNSUPPORTED; /* OleSetClipboard(NULL); */
1763 /***********************************************************************
1764 * AVIGetFromClipboard (AVIFIL32.@)
1766 HRESULT WINAPI AVIGetFromClipboard(PAVIFILE *ppfile)
1768 FIXME("(%p), stub!\n", ppfile);
1772 return AVIERR_UNSUPPORTED;
1775 /***********************************************************************
1776 * AVIPutFileOnClipboard (AVIFIL32.@)
1778 HRESULT WINAPI AVIPutFileOnClipboard(PAVIFILE pfile)
1780 FIXME("(%p), stub!\n", pfile);
1783 return AVIERR_BADHANDLE;
1785 return AVIERR_UNSUPPORTED;