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
*s
= (BYTE
*)idstr
;
80 memset(s
, 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 (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.@)
368 HRESULT WINAPI
AVIFileCreateStreamA(PAVIFILE pfile
, PAVISTREAM
*ppavi
,
369 LPAVISTREAMINFOA psi
)
373 TRACE("(%p,%p,%p)\n", pfile
, ppavi
, psi
);
376 return AVIERR_BADHANDLE
;
378 /* Only the szName at the end is different */
379 memcpy(&psiw
, psi
, sizeof(*psi
) - sizeof(psi
->szName
));
380 MultiByteToWideChar(CP_ACP
, 0, psi
->szName
, -1, psiw
.szName
,
381 sizeof(psiw
.szName
) / sizeof(psiw
.szName
[0]));
383 return IAVIFile_CreateStream(pfile
, ppavi
, &psiw
);
386 /***********************************************************************
387 * AVIFileCreateStreamW (AVIFIL32.@)
389 HRESULT WINAPI
AVIFileCreateStreamW(PAVIFILE pfile
, PAVISTREAM
*avis
,
390 LPAVISTREAMINFOW asi
)
392 TRACE("(%p,%p,%p)\n", pfile
, avis
, asi
);
394 return IAVIFile_CreateStream(pfile
, avis
, asi
);
397 /***********************************************************************
398 * AVIFileWriteData (AVIFIL32.@)
400 HRESULT WINAPI
AVIFileWriteData(PAVIFILE pfile
,DWORD fcc
,LPVOID lp
,LONG size
)
402 TRACE("(%p,'%4.4s',%p,%ld)\n", pfile
, (char*)&fcc
, lp
, size
);
405 return AVIERR_BADHANDLE
;
407 return IAVIFile_WriteData(pfile
, fcc
, lp
, size
);
410 /***********************************************************************
411 * AVIFileReadData (AVIFIL32.@)
413 HRESULT WINAPI
AVIFileReadData(PAVIFILE pfile
,DWORD fcc
,LPVOID lp
,LPLONG size
)
415 TRACE("(%p,'%4.4s',%p,%p)\n", pfile
, (char*)&fcc
, lp
, size
);
418 return AVIERR_BADHANDLE
;
420 return IAVIFile_ReadData(pfile
, fcc
, lp
, size
);
423 /***********************************************************************
424 * AVIFileEndRecord (AVIFIL32.@)
425 * AVIFileEndRecord (AVIFILE.148)
427 HRESULT WINAPI
AVIFileEndRecord(PAVIFILE pfile
)
429 TRACE("(%p)\n", pfile
);
432 return AVIERR_BADHANDLE
;
434 return IAVIFile_EndRecord(pfile
);
437 /***********************************************************************
438 * AVIStreamAddRef (AVIFIL32.@)
439 * AVIStreamAddRef (AVIFILE.160)
441 ULONG WINAPI
AVIStreamAddRef(PAVISTREAM pstream
)
443 TRACE("(%p)\n", pstream
);
445 if (pstream
== NULL
) {
446 ERR(": bad handle passed!\n");
450 return IAVIStream_AddRef(pstream
);
453 /***********************************************************************
454 * AVIStreamRelease (AVIFIL32.@)
455 * AVIStreamRelease (AVIFILE.161)
457 ULONG WINAPI
AVIStreamRelease(PAVISTREAM pstream
)
459 TRACE("(%p)\n", pstream
);
461 if (pstream
== NULL
) {
462 ERR(": bad handle passed!\n");
466 return IAVIStream_Release(pstream
);
469 /***********************************************************************
470 * AVIStreamCreate (AVIFIL32.@)
471 * AVIStreamCreate (AVIFILE.104)
473 HRESULT WINAPI
AVIStreamCreate(PAVISTREAM
*ppavi
, LONG lParam1
, LONG lParam2
,
474 LPCLSID pclsidHandler
)
478 TRACE("(%p,0x%08lX,0x%08lX,%s)\n", ppavi
, lParam1
, lParam2
,
479 debugstr_guid(pclsidHandler
));
482 return AVIERR_BADPARAM
;
485 if (pclsidHandler
== NULL
)
486 return AVIERR_UNSUPPORTED
;
488 hr
= SHCoCreateInstance(NULL
, pclsidHandler
, NULL
,
489 &IID_IAVIStream
, (LPVOID
*)ppavi
);
490 if (FAILED(hr
) || *ppavi
== NULL
)
493 hr
= IAVIStream_Create(*ppavi
, lParam1
, lParam2
);
495 IAVIStream_Release(*ppavi
);
502 /***********************************************************************
503 * AVIStreamInfoA (AVIFIL32.@)
505 HRESULT WINAPI
AVIStreamInfoA(PAVISTREAM pstream
, LPAVISTREAMINFOA asi
,
511 TRACE("(%p,%p,%ld)\n", pstream
, asi
, size
);
514 return AVIERR_BADHANDLE
;
515 if (size
< sizeof(AVISTREAMINFOA
))
516 return AVIERR_BADSIZE
;
518 hres
= IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
));
520 memcpy(asi
, &asiw
, sizeof(asiw
) - sizeof(asiw
.szName
));
521 WideCharToMultiByte(CP_ACP
, 0, asiw
.szName
, -1, asi
->szName
,
522 sizeof(asi
->szName
), NULL
, NULL
);
523 asi
->szName
[sizeof(asi
->szName
) - 1] = 0;
528 /***********************************************************************
529 * AVIStreamInfoW (AVIFIL32.@)
531 HRESULT WINAPI
AVIStreamInfoW(PAVISTREAM pstream
, LPAVISTREAMINFOW asi
,
534 TRACE("(%p,%p,%ld)\n", pstream
, asi
, size
);
537 return AVIERR_BADHANDLE
;
539 return IAVIStream_Info(pstream
, asi
, size
);
542 /***********************************************************************
543 * AVIStreamFindSample (AVIFIL32.@)
545 HRESULT WINAPI
AVIStreamFindSample(PAVISTREAM pstream
, LONG pos
, DWORD flags
)
547 TRACE("(%p,%ld,0x%lX)\n", pstream
, pos
, flags
);
552 return IAVIStream_FindSample(pstream
, pos
, flags
);
555 /***********************************************************************
556 * AVIStreamReadFormat (AVIFIL32.@)
558 HRESULT WINAPI
AVIStreamReadFormat(PAVISTREAM pstream
, LONG pos
,
559 LPVOID format
, LPLONG formatsize
)
561 TRACE("(%p,%ld,%p,%p)\n", pstream
, pos
, format
, formatsize
);
564 return AVIERR_BADHANDLE
;
566 return IAVIStream_ReadFormat(pstream
, pos
, format
, formatsize
);
569 /***********************************************************************
570 * AVIStreamSetFormat (AVIFIL32.@)
572 HRESULT WINAPI
AVIStreamSetFormat(PAVISTREAM pstream
, LONG pos
,
573 LPVOID format
, LONG formatsize
)
575 TRACE("(%p,%ld,%p,%ld)\n", pstream
, pos
, format
, formatsize
);
578 return AVIERR_BADHANDLE
;
580 return IAVIStream_SetFormat(pstream
, pos
, format
, formatsize
);
583 /***********************************************************************
584 * AVIStreamRead (AVIFIL32.@)
586 HRESULT WINAPI
AVIStreamRead(PAVISTREAM pstream
, LONG start
, LONG samples
,
587 LPVOID buffer
, LONG buffersize
,
588 LPLONG bytesread
, LPLONG samplesread
)
590 TRACE("(%p,%ld,%ld,%p,%ld,%p,%p)\n", pstream
, start
, samples
, buffer
,
591 buffersize
, bytesread
, samplesread
);
594 return AVIERR_BADHANDLE
;
596 return IAVIStream_Read(pstream
, start
, samples
, buffer
, buffersize
,
597 bytesread
, samplesread
);
600 /***********************************************************************
601 * AVIStreamWrite (AVIFIL32.@)
603 HRESULT WINAPI
AVIStreamWrite(PAVISTREAM pstream
, LONG start
, LONG samples
,
604 LPVOID buffer
, LONG buffersize
, DWORD flags
,
605 LPLONG sampwritten
, LPLONG byteswritten
)
607 TRACE("(%p,%ld,%ld,%p,%ld,0x%lX,%p,%p)\n", pstream
, start
, samples
, buffer
,
608 buffersize
, flags
, sampwritten
, byteswritten
);
611 return AVIERR_BADHANDLE
;
613 return IAVIStream_Write(pstream
, start
, samples
, buffer
, buffersize
,
614 flags
, sampwritten
, byteswritten
);
617 /***********************************************************************
618 * AVIStreamReadData (AVIFIL32.@)
620 HRESULT WINAPI
AVIStreamReadData(PAVISTREAM pstream
, DWORD fcc
, LPVOID lp
,
623 TRACE("(%p,'%4.4s',%p,%p)\n", pstream
, (char*)&fcc
, lp
, lpread
);
626 return AVIERR_BADHANDLE
;
628 return IAVIStream_ReadData(pstream
, fcc
, lp
, lpread
);
631 /***********************************************************************
632 * AVIStreamWriteData (AVIFIL32.@)
634 HRESULT WINAPI
AVIStreamWriteData(PAVISTREAM pstream
, DWORD fcc
, LPVOID lp
,
637 TRACE("(%p,'%4.4s',%p,%ld)\n", pstream
, (char*)&fcc
, lp
, size
);
640 return AVIERR_BADHANDLE
;
642 return IAVIStream_WriteData(pstream
, fcc
, lp
, size
);
645 /***********************************************************************
646 * AVIStreamGetFrameOpen (AVIFIL32.@)
648 PGETFRAME WINAPI
AVIStreamGetFrameOpen(PAVISTREAM pstream
,
649 LPBITMAPINFOHEADER lpbiWanted
)
653 TRACE("(%p,%p)\n", pstream
, lpbiWanted
);
655 if (FAILED(IAVIStream_QueryInterface(pstream
, &IID_IGetFrame
, (LPVOID
*)&pg
)) ||
657 pg
= AVIFILE_CreateGetFrame(pstream
);
662 if (FAILED(IGetFrame_SetFormat(pg
, lpbiWanted
, NULL
, 0, 0, -1, -1))) {
663 IGetFrame_Release(pg
);
670 /***********************************************************************
671 * AVIStreamGetFrame (AVIFIL32.@)
673 LPVOID WINAPI
AVIStreamGetFrame(PGETFRAME pg
, LONG pos
)
675 TRACE("(%p,%ld)\n", pg
, pos
);
680 return IGetFrame_GetFrame(pg
, pos
);
683 /***********************************************************************
684 * AVIStreamGetFrameClose (AVIFIL32.@)
686 HRESULT WINAPI
AVIStreamGetFrameClose(PGETFRAME pg
)
691 return IGetFrame_Release(pg
);
695 /***********************************************************************
696 * AVIMakeCompressedStream (AVIFIL32.@)
698 HRESULT WINAPI
AVIMakeCompressedStream(PAVISTREAM
*ppsCompressed
,
700 LPAVICOMPRESSOPTIONS aco
,
701 LPCLSID pclsidHandler
)
708 LONG size
= sizeof(szValue
);
710 TRACE("(%p,%p,%p,%s)\n", ppsCompressed
, psSource
, aco
,
711 debugstr_guid(pclsidHandler
));
713 if (ppsCompressed
== NULL
)
714 return AVIERR_BADPARAM
;
715 if (psSource
== NULL
)
716 return AVIERR_BADHANDLE
;
718 *ppsCompressed
= NULL
;
720 /* if no handler given get default ones based on streamtype */
721 if (pclsidHandler
== NULL
) {
722 hr
= IAVIStream_Info(psSource
, &asiw
, sizeof(asiw
));
726 wsprintfA(szRegKey
, "AVIFile\\Compressors\\%4.4s", (char*)&asiw
.fccType
);
727 if (RegQueryValueA(HKEY_CLASSES_ROOT
, szRegKey
, szValue
, &size
) != ERROR_SUCCESS
)
728 return AVIERR_UNSUPPORTED
;
729 if (AVIFILE_CLSIDFromString(szValue
, &clsidHandler
) != S_OK
)
730 return AVIERR_UNSUPPORTED
;
732 memcpy(&clsidHandler
, pclsidHandler
, sizeof(clsidHandler
));
734 hr
= SHCoCreateInstance(NULL
, &clsidHandler
, NULL
,
735 &IID_IAVIStream
, (LPVOID
*)ppsCompressed
);
736 if (FAILED(hr
) || *ppsCompressed
== NULL
)
739 hr
= IAVIStream_Create(*ppsCompressed
, (LPARAM
)psSource
, (LPARAM
)aco
);
741 IAVIStream_Release(*ppsCompressed
);
742 *ppsCompressed
= NULL
;
748 /***********************************************************************
749 * AVIStreamOpenFromFile (AVIFILE.103)
750 * AVIStreamOpenFromFileA (AVIFIL32.@)
752 HRESULT WINAPI
AVIStreamOpenFromFileA(PAVISTREAM
*ppavi
, LPCSTR szFile
,
753 DWORD fccType
, LONG lParam
,
754 UINT mode
, LPCLSID pclsidHandler
)
756 PAVIFILE pfile
= NULL
;
759 TRACE("(%p,%s,'%4.4s',%ld,0x%X,%s)\n", ppavi
, debugstr_a(szFile
),
760 (char*)&fccType
, lParam
, mode
, debugstr_guid(pclsidHandler
));
762 if (ppavi
== NULL
|| szFile
== NULL
)
763 return AVIERR_BADPARAM
;
767 hr
= AVIFileOpenA(&pfile
, szFile
, mode
, pclsidHandler
);
768 if (FAILED(hr
) || pfile
== NULL
)
771 hr
= IAVIFile_GetStream(pfile
, ppavi
, fccType
, lParam
);
772 IAVIFile_Release(pfile
);
777 /***********************************************************************
778 * AVIStreamOpenFromFileW (AVIFIL32.@)
780 HRESULT WINAPI
AVIStreamOpenFromFileW(PAVISTREAM
*ppavi
, LPCWSTR szFile
,
781 DWORD fccType
, LONG lParam
,
782 UINT mode
, LPCLSID pclsidHandler
)
784 PAVIFILE pfile
= NULL
;
787 TRACE("(%p,%s,'%4.4s',%ld,0x%X,%s)\n", ppavi
, debugstr_w(szFile
),
788 (char*)&fccType
, lParam
, mode
, debugstr_guid(pclsidHandler
));
790 if (ppavi
== NULL
|| szFile
== NULL
)
791 return AVIERR_BADPARAM
;
795 hr
= AVIFileOpenW(&pfile
, szFile
, mode
, pclsidHandler
);
796 if (FAILED(hr
) || pfile
== NULL
)
799 hr
= IAVIFile_GetStream(pfile
, ppavi
, fccType
, lParam
);
800 IAVIFile_Release(pfile
);
805 /***********************************************************************
806 * AVIStreamStart (AVIFILE.130)
807 * AVIStreamStart (AVIFIL32.@)
809 LONG WINAPI
AVIStreamStart(PAVISTREAM pstream
)
813 TRACE("(%p)\n", pstream
);
818 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
824 /***********************************************************************
825 * AVIStreamLength (AVIFILE.131)
826 * AVIStreamLength (AVIFIL32.@)
828 LONG WINAPI
AVIStreamLength(PAVISTREAM pstream
)
832 TRACE("(%p)\n", pstream
);
837 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
840 return asiw
.dwLength
;
843 /***********************************************************************
844 * AVIStreamSampleToTime (AVIFILE.133)
845 * AVIStreamSampleToTime (AVIFIL32.@)
847 LONG WINAPI
AVIStreamSampleToTime(PAVISTREAM pstream
, LONG lSample
)
851 TRACE("(%p,%ld)\n", pstream
, lSample
);
856 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
858 if (asiw
.dwRate
== 0)
861 return (LONG
)(((float)lSample
* asiw
.dwScale
* 1000.0) / asiw
.dwRate
);
864 /***********************************************************************
865 * AVIStreamTimeToSample (AVIFILE.132)
866 * AVIStreamTimeToSample (AVIFIL32.@)
868 LONG WINAPI
AVIStreamTimeToSample(PAVISTREAM pstream
, LONG lTime
)
872 TRACE("(%p,%ld)\n", pstream
, lTime
);
877 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
879 if (asiw
.dwScale
== 0)
882 return (LONG
)(((float)lTime
* asiw
.dwRate
) / asiw
.dwScale
/ 1000.0);
885 /***********************************************************************
886 * AVIBuildFilterA (AVIFIL32.@)
888 HRESULT WINAPI
AVIBuildFilterA(LPSTR szFilter
, LONG cbFilter
, BOOL fSaving
)
893 TRACE("(%p,%ld,%d)\n", szFilter
, cbFilter
, fSaving
);
895 /* check parameters */
896 if (szFilter
== NULL
)
897 return AVIERR_BADPARAM
;
899 return AVIERR_BADSIZE
;
904 wszFilter
= (LPWSTR
)GlobalAllocPtr(GHND
, cbFilter
);
905 if (wszFilter
== NULL
)
906 return AVIERR_MEMORY
;
908 hr
= AVIBuildFilterW(wszFilter
, cbFilter
, fSaving
);
910 WideCharToMultiByte(CP_ACP
, 0, wszFilter
, cbFilter
,
911 szFilter
, cbFilter
, NULL
, NULL
);
914 GlobalFreePtr(wszFilter
);
919 /***********************************************************************
920 * AVIBuildFilterW (AVIFIL32.@)
922 HRESULT WINAPI
AVIBuildFilterW(LPWSTR szFilter
, LONG cbFilter
, BOOL fSaving
)
924 static const WCHAR szClsid
[] = {'C','L','S','I','D',0};
925 static const WCHAR szExtensionFmt
[] = {';','*','.','%','s',0};
926 static const WCHAR szAVIFileExtensions
[] =
927 {'A','V','I','F','i','l','e','\\','E','x','t','e','n','s','i','o','n','s',0};
930 WCHAR szAllFiles
[40];
938 TRACE("(%p,%ld,%d)\n", szFilter
, cbFilter
, fSaving
);
940 /* check parameters */
941 if (szFilter
== NULL
)
942 return AVIERR_BADPARAM
;
944 return AVIERR_BADSIZE
;
946 lp
= (AVIFilter
*)GlobalAllocPtr(GHND
, MAX_FILTERS
* sizeof(AVIFilter
));
948 return AVIERR_MEMORY
;
951 * 1. iterate over HKEY_CLASSES_ROOT\\AVIFile\\Extensions and collect
952 * extensions and CLSID's
953 * 2. iterate over collected CLSID's and copy it's description and it's
954 * extensions to szFilter if it fits
956 * First filter is named "All multimedia files" and it's filter is a
957 * collection of all possible extensions except "*.*".
959 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, szAVIFileExtensions
, &hKey
) != S_OK
) {
963 for (n
= 0;RegEnumKeyW(hKey
, n
, szFileExt
, sizeof(szFileExt
)) == S_OK
;n
++) {
964 /* get CLSID to extension */
965 size
= sizeof(szValue
)/sizeof(szValue
[0]);
966 if (RegQueryValueW(hKey
, szFileExt
, szValue
, &size
) != S_OK
)
969 /* search if the CLSID is already known */
970 for (i
= 1; i
<= count
; i
++) {
971 if (lstrcmpW(lp
[i
].szClsid
, szValue
) == 0)
972 break; /* a new one */
975 if (count
- i
== -1) {
976 /* it's a new CLSID */
978 /* FIXME: How do we get info's about read/write capabilities? */
980 if (count
>= MAX_FILTERS
) {
981 /* try to inform user of our full fixed size table */
982 ERR(": More than %d filters found! Adjust MAX_FILTERS in dlls/avifil32/api.c\n", MAX_FILTERS
);
986 lstrcpyW(lp
[i
].szClsid
, szValue
);
991 /* append extension to the filter */
992 wsprintfW(szValue
, szExtensionFmt
, szFileExt
);
993 if (lp
[i
].szExtensions
[0] == 0)
994 lstrcatW(lp
[i
].szExtensions
, szValue
+ 1);
996 lstrcatW(lp
[i
].szExtensions
, szValue
);
998 /* also append to the "all multimedia"-filter */
999 if (lp
[0].szExtensions
[0] == 0)
1000 lstrcatW(lp
[0].szExtensions
, szValue
+ 1);
1002 lstrcatW(lp
[0].szExtensions
, szValue
);
1006 /* 2. get descriptions for the CLSIDs and fill out szFilter */
1007 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, szClsid
, &hKey
) != S_OK
) {
1009 return AVIERR_ERROR
;
1011 for (n
= 0; n
<= count
; n
++) {
1012 /* first the description */
1014 size
= sizeof(szValue
)/sizeof(szValue
[0]);
1015 if (RegQueryValueW(hKey
, lp
[n
].szClsid
, szValue
, &size
) == S_OK
) {
1016 size
= lstrlenW(szValue
);
1017 lstrcpynW(szFilter
, szValue
, cbFilter
);
1020 size
= LoadStringW(AVIFILE_hModule
,IDS_ALLMULTIMEDIA
,szFilter
,cbFilter
);
1022 /* check for enough space */
1024 if (cbFilter
< size
+ lstrlenW(lp
[n
].szExtensions
) + 2) {
1029 return AVIERR_BUFFERTOOSMALL
;
1034 /* and then the filter */
1035 lstrcpynW(szFilter
, lp
[n
].szExtensions
, cbFilter
);
1036 size
= lstrlenW(lp
[n
].szExtensions
) + 1;
1044 /* add "All files" "*.*" filter if enough space left */
1045 size
= LoadStringW(AVIFILE_hModule
, IDS_ALLFILES
,
1046 szAllFiles
, sizeof(szAllFiles
)) + 1;
1047 if (cbFilter
> size
) {
1050 /* replace '@' with \000 to seperate description of filter */
1051 for (i
= 0; i
< size
&& szAllFiles
[i
] != 0; i
++) {
1052 if (szAllFiles
[i
] == '@') {
1058 memcpy(szFilter
, szAllFiles
, size
* sizeof(szAllFiles
[0]));
1065 return AVIERR_BUFFERTOOSMALL
;
1069 static BOOL
AVISaveOptionsFmtChoose(HWND hWnd
)
1071 LPAVICOMPRESSOPTIONS pOptions
= SaveOpts
.ppOptions
[SaveOpts
.nCurrent
];
1072 AVISTREAMINFOW sInfo
;
1074 TRACE("(%p)\n", hWnd
);
1076 if (pOptions
== NULL
|| SaveOpts
.ppavis
[SaveOpts
.nCurrent
] == NULL
) {
1077 ERR(": bad state!\n");
1081 if (FAILED(AVIStreamInfoW(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1082 &sInfo
, sizeof(sInfo
)))) {
1083 ERR(": AVIStreamInfoW failed!\n");
1087 if (sInfo
.fccType
== streamtypeVIDEO
) {
1091 memset(&cv
, 0, sizeof(cv
));
1093 if ((pOptions
->dwFlags
& AVICOMPRESSF_VALID
) == 0) {
1094 memset(pOptions
, 0, sizeof(AVICOMPRESSOPTIONS
));
1095 pOptions
->fccType
= streamtypeVIDEO
;
1096 pOptions
->fccHandler
= comptypeDIB
;
1097 pOptions
->dwQuality
= ICQUALITY_DEFAULT
;
1100 cv
.cbSize
= sizeof(cv
);
1101 cv
.dwFlags
= ICMF_COMPVARS_VALID
;
1102 /*cv.fccType = pOptions->fccType; */
1103 cv
.fccHandler
= pOptions
->fccHandler
;
1104 cv
.lQ
= pOptions
->dwQuality
;
1105 cv
.lpState
= pOptions
->lpParms
;
1106 cv
.cbState
= pOptions
->cbParms
;
1107 if (pOptions
->dwFlags
& AVICOMPRESSF_KEYFRAMES
)
1108 cv
.lKey
= pOptions
->dwKeyFrameEvery
;
1111 if (pOptions
->dwFlags
& AVICOMPRESSF_DATARATE
)
1112 cv
.lDataRate
= pOptions
->dwBytesPerSecond
/ 1024; /* need kBytes */
1116 ret
= ICCompressorChoose(hWnd
, SaveOpts
.uFlags
, NULL
,
1117 SaveOpts
.ppavis
[SaveOpts
.nCurrent
], &cv
, NULL
);
1120 pOptions
->lpParms
= cv
.lpState
;
1121 pOptions
->cbParms
= cv
.cbState
;
1122 pOptions
->dwQuality
= cv
.lQ
;
1124 pOptions
->dwKeyFrameEvery
= cv
.lKey
;
1125 pOptions
->dwFlags
|= AVICOMPRESSF_KEYFRAMES
;
1127 pOptions
->dwFlags
&= ~AVICOMPRESSF_KEYFRAMES
;
1128 if (cv
.lDataRate
!= 0) {
1129 pOptions
->dwBytesPerSecond
= cv
.lDataRate
* 1024; /* need bytes */
1130 pOptions
->dwFlags
|= AVICOMPRESSF_DATARATE
;
1132 pOptions
->dwFlags
&= ~AVICOMPRESSF_DATARATE
;
1133 pOptions
->dwFlags
|= AVICOMPRESSF_VALID
;
1135 ICCompressorFree(&cv
);
1138 } else if (sInfo
.fccType
== streamtypeAUDIO
) {
1139 ACMFORMATCHOOSEW afmtc
;
1143 /* FIXME: check ACM version -- Which version is needed? */
1145 memset(&afmtc
, 0, sizeof(afmtc
));
1146 afmtc
.cbStruct
= sizeof(afmtc
);
1148 afmtc
.hwndOwner
= hWnd
;
1150 acmMetrics(NULL
, ACM_METRIC_MAX_SIZE_FORMAT
, &size
);
1151 if ((pOptions
->cbFormat
== 0 || pOptions
->lpFormat
== NULL
) && size
!= 0) {
1152 pOptions
->lpFormat
= GlobalAllocPtr(GMEM_MOVEABLE
, size
);
1153 pOptions
->cbFormat
= size
;
1154 } else if (pOptions
->cbFormat
< size
) {
1155 pOptions
->lpFormat
= GlobalReAllocPtr(pOptions
->lpFormat
, size
, GMEM_MOVEABLE
);
1156 pOptions
->cbFormat
= size
;
1158 if (pOptions
->lpFormat
== NULL
)
1160 afmtc
.pwfx
= pOptions
->lpFormat
;
1161 afmtc
.cbwfx
= pOptions
->cbFormat
;
1164 AVIStreamFormatSize(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1165 sInfo
.dwStart
, &size
);
1166 if (size
< sizeof(PCMWAVEFORMAT
))
1167 size
= sizeof(PCMWAVEFORMAT
);
1168 afmtc
.pwfxEnum
= GlobalAllocPtr(GHND
, size
);
1169 if (afmtc
.pwfxEnum
!= NULL
) {
1170 AVIStreamReadFormat(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1171 sInfo
.dwStart
, afmtc
.pwfxEnum
, &size
);
1172 afmtc
.fdwEnum
= ACM_FORMATENUMF_CONVERT
;
1175 ret
= acmFormatChooseW(&afmtc
);
1177 pOptions
->dwFlags
|= AVICOMPRESSF_VALID
;
1179 if (afmtc
.pwfxEnum
!= NULL
)
1180 GlobalFreePtr(afmtc
.pwfxEnum
);
1182 return (ret
== S_OK
? TRUE
: FALSE
);
1184 ERR(": unknown streamtype 0x%08lX\n", sInfo
.fccType
);
1189 static void AVISaveOptionsUpdate(HWND hWnd
)
1191 static const WCHAR szVideoFmt
[]={'%','l','d','x','%','l','d','x','%','d',0};
1192 static const WCHAR szAudioFmt
[]={'%','s',' ','%','s',0};
1194 WCHAR szFormat
[128];
1195 AVISTREAMINFOW sInfo
;
1199 TRACE("(%p)\n", hWnd
);
1201 SaveOpts
.nCurrent
= SendDlgItemMessageW(hWnd
,IDC_STREAM
,CB_GETCURSEL
,0,0);
1202 if (SaveOpts
.nCurrent
< 0)
1205 if (FAILED(AVIStreamInfoW(SaveOpts
.ppavis
[SaveOpts
.nCurrent
], &sInfo
, sizeof(sInfo
))))
1208 AVIStreamFormatSize(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],sInfo
.dwStart
,&size
);
1212 /* read format to build format descriotion string */
1213 lpFormat
= GlobalAllocPtr(GHND
, size
);
1214 if (lpFormat
!= NULL
) {
1215 if (SUCCEEDED(AVIStreamReadFormat(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],sInfo
.dwStart
,lpFormat
, &size
))) {
1216 if (sInfo
.fccType
== streamtypeVIDEO
) {
1217 LPBITMAPINFOHEADER lpbi
= lpFormat
;
1220 wsprintfW(szFormat
, szVideoFmt
, lpbi
->biWidth
,
1221 lpbi
->biHeight
, lpbi
->biBitCount
);
1223 if (lpbi
->biCompression
!= BI_RGB
) {
1226 hic
= ICLocate(ICTYPE_VIDEO
, sInfo
.fccHandler
, lpFormat
,
1227 NULL
, ICMODE_DECOMPRESS
);
1229 if (ICGetInfo(hic
, &icinfo
, sizeof(icinfo
)) == S_OK
)
1230 lstrcatW(szFormat
, icinfo
.szDescription
);
1234 LoadStringW(AVIFILE_hModule
, IDS_UNCOMPRESSED
,
1235 icinfo
.szDescription
, sizeof(icinfo
.szDescription
));
1236 lstrcatW(szFormat
, icinfo
.szDescription
);
1238 } else if (sInfo
.fccType
== streamtypeAUDIO
) {
1239 ACMFORMATTAGDETAILSW aftd
;
1240 ACMFORMATDETAILSW afd
;
1242 memset(&aftd
, 0, sizeof(aftd
));
1243 memset(&afd
, 0, sizeof(afd
));
1245 aftd
.cbStruct
= sizeof(aftd
);
1246 aftd
.dwFormatTag
= afd
.dwFormatTag
=
1247 ((PWAVEFORMATEX
)lpFormat
)->wFormatTag
;
1248 aftd
.cbFormatSize
= afd
.cbwfx
= size
;
1250 afd
.cbStruct
= sizeof(afd
);
1251 afd
.pwfx
= lpFormat
;
1253 if (acmFormatTagDetailsW(NULL
, &aftd
,
1254 ACM_FORMATTAGDETAILSF_FORMATTAG
) == S_OK
) {
1255 if (acmFormatDetailsW(NULL
,&afd
,ACM_FORMATDETAILSF_FORMAT
) == S_OK
)
1256 wsprintfW(szFormat
, szAudioFmt
, afd
.szFormat
, aftd
.szFormatTag
);
1260 GlobalFreePtr(lpFormat
);
1263 /* set text for format description */
1264 SetDlgItemTextW(hWnd
, IDC_FORMATTEXT
, szFormat
);
1266 /* Disable option button for unsupported streamtypes */
1267 if (sInfo
.fccType
== streamtypeVIDEO
||
1268 sInfo
.fccType
== streamtypeAUDIO
)
1269 EnableWindow(GetDlgItem(hWnd
, IDC_OPTIONS
), TRUE
);
1271 EnableWindow(GetDlgItem(hWnd
, IDC_OPTIONS
), FALSE
);
1276 INT_PTR CALLBACK
AVISaveOptionsDlgProc(HWND hWnd
, UINT uMsg
,
1277 WPARAM wParam
, LPARAM lParam
)
1280 BOOL bIsInterleaved
;
1283 /*TRACE("(%p,%u,0x%04X,0x%08lX)\n", hWnd, uMsg, wParam, lParam);*/
1287 SaveOpts
.nCurrent
= 0;
1288 if (SaveOpts
.nStreams
== 1) {
1289 EndDialog(hWnd
, AVISaveOptionsFmtChoose(hWnd
));
1294 for (n
= 0; n
< SaveOpts
.nStreams
; n
++) {
1295 AVISTREAMINFOW sInfo
;
1297 AVIStreamInfoW(SaveOpts
.ppavis
[n
], &sInfo
, sizeof(sInfo
));
1298 SendDlgItemMessageW(hWnd
, IDC_STREAM
, CB_ADDSTRING
,
1299 0L, (LPARAM
)sInfo
.szName
);
1302 /* select first stream */
1303 SendDlgItemMessageW(hWnd
, IDC_STREAM
, CB_SETCURSEL
, 0, 0);
1304 SendMessageW(hWnd
, WM_COMMAND
,
1305 GET_WM_COMMAND_MPS(IDC_STREAM
, hWnd
, CBN_SELCHANGE
));
1307 /* initialize interleave */
1308 if (SaveOpts
.ppOptions
[0] != NULL
&&
1309 (SaveOpts
.ppOptions
[0]->dwFlags
& AVICOMPRESSF_VALID
)) {
1310 bIsInterleaved
= (SaveOpts
.ppOptions
[0]->dwFlags
& AVICOMPRESSF_INTERLEAVE
);
1311 dwInterleave
= SaveOpts
.ppOptions
[0]->dwInterleaveEvery
;
1313 bIsInterleaved
= TRUE
;
1316 CheckDlgButton(hWnd
, IDC_INTERLEAVE
, bIsInterleaved
);
1317 SetDlgItemInt(hWnd
, IDC_INTERLEAVEEVERY
, dwInterleave
, FALSE
);
1318 EnableWindow(GetDlgItem(hWnd
, IDC_INTERLEAVEEVERY
), bIsInterleaved
);
1321 switch (GET_WM_COMMAND_CMD(wParam
, lParam
)) {
1323 /* get data from controls and save them */
1324 dwInterleave
= GetDlgItemInt(hWnd
, IDC_INTERLEAVEEVERY
, NULL
, 0);
1325 bIsInterleaved
= IsDlgButtonChecked(hWnd
, IDC_INTERLEAVE
);
1326 for (n
= 0; n
< SaveOpts
.nStreams
; n
++) {
1327 if (SaveOpts
.ppOptions
[n
] != NULL
) {
1328 if (bIsInterleaved
) {
1329 SaveOpts
.ppOptions
[n
]->dwFlags
|= AVICOMPRESSF_INTERLEAVE
;
1330 SaveOpts
.ppOptions
[n
]->dwInterleaveEvery
= dwInterleave
;
1332 SaveOpts
.ppOptions
[n
]->dwFlags
&= ~AVICOMPRESSF_INTERLEAVE
;
1337 EndDialog(hWnd
, GET_WM_COMMAND_CMD(wParam
, lParam
) == IDOK
);
1339 case IDC_INTERLEAVE
:
1340 EnableWindow(GetDlgItem(hWnd
, IDC_INTERLEAVEEVERY
),
1341 IsDlgButtonChecked(hWnd
, IDC_INTERLEAVE
));
1344 if (GET_WM_COMMAND_CMD(wParam
, lParam
) == CBN_SELCHANGE
) {
1345 /* update control elements */
1346 AVISaveOptionsUpdate(hWnd
);
1350 AVISaveOptionsFmtChoose(hWnd
);
1359 /***********************************************************************
1360 * AVISaveOptions (AVIFIL32.@)
1362 BOOL WINAPI
AVISaveOptions(HWND hWnd
, UINT uFlags
, INT nStreams
,
1363 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*ppOptions
)
1365 LPAVICOMPRESSOPTIONS pSavedOptions
= NULL
;
1368 TRACE("(%p,0x%X,%d,%p,%p)\n", hWnd
, uFlags
, nStreams
,
1371 /* check parameters */
1372 if (nStreams
<= 0 || ppavi
== NULL
|| ppOptions
== NULL
)
1373 return AVIERR_BADPARAM
;
1375 /* save options for case user press cancel */
1376 if (ppOptions
!= NULL
&& nStreams
> 1) {
1377 pSavedOptions
= GlobalAllocPtr(GHND
,nStreams
* sizeof(AVICOMPRESSOPTIONS
));
1378 if (pSavedOptions
== NULL
)
1381 for (n
= 0; n
< nStreams
; n
++) {
1382 if (ppOptions
[n
] != NULL
)
1383 memcpy(pSavedOptions
+ n
, ppOptions
[n
], sizeof(AVICOMPRESSOPTIONS
));
1387 SaveOpts
.uFlags
= uFlags
;
1388 SaveOpts
.nStreams
= nStreams
;
1389 SaveOpts
.ppavis
= ppavi
;
1390 SaveOpts
.ppOptions
= ppOptions
;
1392 ret
= DialogBoxW(AVIFILE_hModule
, MAKEINTRESOURCEW(IDD_SAVEOPTIONS
),
1393 hWnd
, AVISaveOptionsDlgProc
);
1398 /* restore options when user pressed cancel */
1399 if (pSavedOptions
!= NULL
&& ret
== FALSE
) {
1400 for (n
= 0; n
< nStreams
; n
++) {
1401 if (ppOptions
[n
] != NULL
)
1402 memcpy(ppOptions
[n
], pSavedOptions
+ n
, sizeof(AVICOMPRESSOPTIONS
));
1404 GlobalFreePtr(pSavedOptions
);
1410 /***********************************************************************
1411 * AVISaveOptionsFree (AVIFIL32.@)
1413 HRESULT WINAPI
AVISaveOptionsFree(INT nStreams
,LPAVICOMPRESSOPTIONS
*ppOptions
)
1415 TRACE("(%d,%p)\n", nStreams
, ppOptions
);
1417 if (nStreams
< 0 || ppOptions
== NULL
)
1418 return AVIERR_BADPARAM
;
1420 for (; nStreams
> 0; nStreams
--) {
1421 if (ppOptions
[nStreams
] != NULL
) {
1422 ppOptions
[nStreams
]->dwFlags
&= ~AVICOMPRESSF_VALID
;
1424 if (ppOptions
[nStreams
]->lpParms
!= NULL
) {
1425 GlobalFreePtr(ppOptions
[nStreams
]->lpParms
);
1426 ppOptions
[nStreams
]->lpParms
= NULL
;
1427 ppOptions
[nStreams
]->cbParms
= 0;
1429 if (ppOptions
[nStreams
]->lpFormat
!= NULL
) {
1430 GlobalFreePtr(ppOptions
[nStreams
]->lpFormat
);
1431 ppOptions
[nStreams
]->lpFormat
= NULL
;
1432 ppOptions
[nStreams
]->cbFormat
= 0;