📄 api.c
字号:
/*
* Copyright 1999 Marcus Meissner
* Copyright 2002-2003 Michael G黱newig
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
#include "winerror.h"
#include "ole2.h"
#include "shellapi.h"
#include "shlobj.h"
#include "vfw.h"
#include "msacm.h"
#include "avifile_private.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(avifile);
/***********************************************************************
* for AVIBuildFilterW -- uses fixed size table
*/
#define MAX_FILTERS 30 /* 30 => 7kB */
typedef struct _AVIFilter {
WCHAR szClsid[40];
WCHAR szExtensions[MAX_FILTERS * 7];
} AVIFilter;
/***********************************************************************
* for AVISaveOptions
*/
static struct {
UINT uFlags;
INT nStreams;
PAVISTREAM *ppavis;
LPAVICOMPRESSOPTIONS *ppOptions;
INT nCurrent;
} SaveOpts;
/***********************************************************************
* copied from dlls/ole32/compobj.c
*/
static HRESULT AVIFILE_CLSIDFromString(LPCSTR idstr, LPCLSID id)
{
BYTE const *s;
BYTE *p;
INT i;
BYTE table[256];
if (!idstr) {
memset(id, 0, sizeof(CLSID));
return S_OK;
}
/* validate the CLSID string */
if (lstrlenA(idstr) != 38)
return CO_E_CLASSSTRING;
s = (BYTE const*)idstr;
if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') ||
(s[24]!='-') || (s[37]!='}'))
return CO_E_CLASSSTRING;
for (i = 1; i < 37; i++) {
if ((i == 9) || (i == 14) || (i == 19) || (i == 24))
continue;
if (!(((s[i] >= '0') && (s[i] <= '9')) ||
((s[i] >= 'a') && (s[i] <= 'f')) ||
((s[i] >= 'A') && (s[i] <= 'F')))
)
return CO_E_CLASSSTRING;
}
TRACE("%s -> %p\n", s, id);
/* quick lookup table */
memset(table, 0, 256);
for (i = 0; i < 10; i++)
table['0' + i] = i;
for (i = 0; i < 6; i++) {
table['A' + i] = i+10;
table['a' + i] = i+10;
}
/* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
p = (BYTE *) id;
s++; /* skip leading brace */
for (i = 0; i < 4; i++) {
p[3 - i] = table[*s]<<4 | table[*(s+1)];
s += 2;
}
p += 4;
s++; /* skip - */
for (i = 0; i < 2; i++) {
p[1-i] = table[*s]<<4 | table[*(s+1)];
s += 2;
}
p += 2;
s++; /* skip - */
for (i = 0; i < 2; i++) {
p[1-i] = table[*s]<<4 | table[*(s+1)];
s += 2;
}
p += 2;
s++; /* skip - */
/* these are just sequential bytes */
for (i = 0; i < 2; i++) {
*p++ = table[*s]<<4 | table[*(s+1)];
s += 2;
}
s++; /* skip - */
for (i = 0; i < 6; i++) {
*p++ = table[*s]<<4 | table[*(s+1)];
s += 2;
}
return S_OK;
}
static BOOL AVIFILE_GetFileHandlerByExtension(LPCWSTR szFile, LPCLSID lpclsid)
{
CHAR szRegKey[25];
CHAR szValue[100];
LPWSTR szExt = strrchrW(szFile, '.');
LONG len = sizeof(szValue) / sizeof(szValue[0]);
if (szExt == NULL)
return FALSE;
szExt++;
wsprintfA(szRegKey, "AVIFile\\Extensions\\%.3ls", szExt);
if (RegQueryValueA(HKEY_CLASSES_ROOT, szRegKey, szValue, &len) != ERROR_SUCCESS)
return FALSE;
return (AVIFILE_CLSIDFromString(szValue, lpclsid) == S_OK);
}
/***********************************************************************
* AVIFileInit (AVIFIL32.@)
* AVIFileInit (AVIFILE.100)
*/
void WINAPI AVIFileInit(void) {
OleInitialize(NULL);
}
/***********************************************************************
* AVIFileExit (AVIFIL32.@)
* AVIFileExit (AVIFILE.101)
*/
void WINAPI AVIFileExit(void) {
/* need to free ole32.dll if we are the last exit call */
/* OleUnitialize() */
FIXME("(): stub!\n");
}
/***********************************************************************
* AVIFileOpen (AVIFIL32.@)
* AVIFileOpenA (AVIFIL32.@)
* AVIFileOpen (AVIFILE.102)
*/
HRESULT WINAPI AVIFileOpenA(PAVIFILE *ppfile, LPCSTR szFile, UINT uMode,
LPCLSID lpHandler)
{
LPWSTR wszFile = NULL;
HRESULT hr;
int len;
TRACE("(%p,%s,0x%08X,%s)\n", ppfile, debugstr_a(szFile), uMode,
debugstr_guid(lpHandler));
/* check parameters */
if (ppfile == NULL || szFile == NULL)
return AVIERR_BADPARAM;
/* convert ASCII string to Unicode and call unicode function */
len = MultiByteToWideChar(CP_ACP, 0, szFile, -1, NULL, 0);
if (len <= 0)
return AVIERR_BADPARAM;
wszFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (wszFile == NULL)
return AVIERR_MEMORY;
MultiByteToWideChar(CP_ACP, 0, szFile, -1, wszFile, len);
hr = AVIFileOpenW(ppfile, wszFile, uMode, lpHandler);
HeapFree(GetProcessHeap(), 0, wszFile);
return hr;
}
/***********************************************************************
* AVIFileOpenW (AVIFIL32.@)
*/
HRESULT WINAPI AVIFileOpenW(PAVIFILE *ppfile, LPCWSTR szFile, UINT uMode,
LPCLSID lpHandler)
{
IPersistFile *ppersist = NULL;
CLSID clsidHandler;
HRESULT hr;
TRACE("(%p,%s,0x%X,%s)\n", ppfile, debugstr_w(szFile), uMode,
debugstr_guid(lpHandler));
/* check parameters */
if (ppfile == NULL || szFile == NULL)
return AVIERR_BADPARAM;
*ppfile = NULL;
/* if no handler then try guessing it by extension */
if (lpHandler == NULL) {
if (! AVIFILE_GetFileHandlerByExtension(szFile, &clsidHandler))
return AVIERR_UNSUPPORTED;
} else
memcpy(&clsidHandler, lpHandler, sizeof(clsidHandler));
/* create instance of handler */
hr = CoCreateInstance(&clsidHandler, NULL, CLSCTX_INPROC, &IID_IAVIFile, (LPVOID*)ppfile);
if (FAILED(hr) || *ppfile == NULL)
return hr;
/* ask for IPersistFile interface for loading/creating the file */
hr = IAVIFile_QueryInterface(*ppfile, &IID_IPersistFile, (LPVOID*)&ppersist);
if (FAILED(hr) || ppersist == NULL) {
IAVIFile_Release(*ppfile);
*ppfile = NULL;
return hr;
}
hr = IPersistFile_Load(ppersist, szFile, uMode);
IPersistFile_Release(ppersist);
if (FAILED(hr)) {
IAVIFile_Release(*ppfile);
*ppfile = NULL;
}
return hr;
}
/***********************************************************************
* AVIFileAddRef (AVIFIL32.@)
* AVIFileAddRef (AVIFILE.140)
*/
ULONG WINAPI AVIFileAddRef(PAVIFILE pfile)
{
TRACE("(%p)\n", pfile);
if (pfile == NULL) {
ERR(": bad handle passed!\n");
return 0;
}
return IAVIFile_AddRef(pfile);
}
/***********************************************************************
* AVIFileRelease (AVIFIL32.@)
* AVIFileRelease (AVIFILE.141)
*/
ULONG WINAPI AVIFileRelease(PAVIFILE pfile)
{
TRACE("(%p)\n", pfile);
if (pfile == NULL) {
ERR(": bad handle passed!\n");
return 0;
}
return IAVIFile_Release(pfile);
}
/***********************************************************************
* AVIFileInfo (AVIFIL32.@)
* AVIFileInfoA (AVIFIL32.@)
* AVIFileInfo (AVIFILE.142)
*/
HRESULT WINAPI AVIFileInfoA(PAVIFILE pfile, LPAVIFILEINFOA afi, LONG size)
{
AVIFILEINFOW afiw;
HRESULT hres;
TRACE("(%p,%p,%d)\n", pfile, afi, size);
if (pfile == NULL)
return AVIERR_BADHANDLE;
if ((DWORD)size < sizeof(AVIFILEINFOA))
return AVIERR_BADSIZE;
hres = IAVIFile_Info(pfile, &afiw, sizeof(afiw));
memcpy(afi, &afiw, sizeof(*afi) - sizeof(afi->szFileType));
WideCharToMultiByte(CP_ACP, 0, afiw.szFileType, -1, afi->szFileType,
sizeof(afi->szFileType), NULL, NULL);
afi->szFileType[sizeof(afi->szFileType) - 1] = 0;
return hres;
}
/***********************************************************************
* AVIFileInfoW (AVIFIL32.@)
*/
HRESULT WINAPI AVIFileInfoW(PAVIFILE pfile, LPAVIFILEINFOW afiw, LONG size)
{
TRACE("(%p,%p,%d)\n", pfile, afiw, size);
if (pfile == NULL)
return AVIERR_BADHANDLE;
return IAVIFile_Info(pfile, afiw, size);
}
/***********************************************************************
* AVIFileGetStream (AVIFIL32.@)
* AVIFileGetStream (AVIFILE.143)
*/
HRESULT WINAPI AVIFileGetStream(PAVIFILE pfile, PAVISTREAM *avis,
DWORD fccType, LONG lParam)
{
TRACE("(%p,%p,'%4.4s',%d)\n", pfile, avis, (char*)&fccType, lParam);
if (pfile == NULL)
return AVIERR_BADHANDLE;
return IAVIFile_GetStream(pfile, avis, fccType, lParam);
}
/***********************************************************************
* AVIFileCreateStream (AVIFIL32.@)
* AVIFileCreateStreamA (AVIFIL32.@)
* AVIFileCreateStream (AVIFILE.144)
*/
HRESULT WINAPI AVIFileCreateStreamA(PAVIFILE pfile, PAVISTREAM *ppavi,
LPAVISTREAMINFOA psi)
{
AVISTREAMINFOW psiw;
TRACE("(%p,%p,%p)\n", pfile, ppavi, psi);
if (pfile == NULL)
return AVIERR_BADHANDLE;
/* Only the szName at the end is different */
memcpy(&psiw, psi, sizeof(*psi) - sizeof(psi->szName));
MultiByteToWideChar(CP_ACP, 0, psi->szName, -1, psiw.szName,
sizeof(psiw.szName) / sizeof(psiw.szName[0]));
return IAVIFile_CreateStream(pfile, ppavi, &psiw);
}
/***********************************************************************
* AVIFileCreateStreamW (AVIFIL32.@)
*/
HRESULT WINAPI AVIFileCreateStreamW(PAVIFILE pfile, PAVISTREAM *avis,
LPAVISTREAMINFOW asi)
{
TRACE("(%p,%p,%p)\n", pfile, avis, asi);
if (pfile == NULL)
return AVIERR_BADHANDLE;
return IAVIFile_CreateStream(pfile, avis, asi);
}
/***********************************************************************
* AVIFileWriteData (AVIFIL32.@)
* AVIFileWriteData (AVIFILE.146)
*/
HRESULT WINAPI AVIFileWriteData(PAVIFILE pfile,DWORD fcc,LPVOID lp,LONG size)
{
TRACE("(%p,'%4.4s',%p,%d)\n", pfile, (char*)&fcc, lp, size);
if (pfile == NULL)
return AVIERR_BADHANDLE;
return IAVIFile_WriteData(pfile, fcc, lp, size);
}
/***********************************************************************
* AVIFileReadData (AVIFIL32.@)
* AVIFileReadData (AVIFILE.147)
*/
HRESULT WINAPI AVIFileReadData(PAVIFILE pfile,DWORD fcc,LPVOID lp,LPLONG size)
{
TRACE("(%p,'%4.4s',%p,%p)\n", pfile, (char*)&fcc, lp, size);
if (pfile == NULL)
return AVIERR_BADHANDLE;
return IAVIFile_ReadData(pfile, fcc, lp, size);
}
/***********************************************************************
* AVIFileEndRecord (AVIFIL32.@)
* AVIFileEndRecord (AVIFILE.148)
*/
HRESULT WINAPI AVIFileEndRecord(PAVIFILE pfile)
{
TRACE("(%p)\n", pfile);
if (pfile == NULL)
return AVIERR_BADHANDLE;
return IAVIFile_EndRecord(pfile);
}
/***********************************************************************
* AVIStreamAddRef (AVIFIL32.@)
* AVIStreamAddRef (AVIFILE.160)
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -