|
|
/*==========================================================================
* * Copyright (C) 1997 Microsoft Corporation. All Rights Reserved. * * File: factory.cpp * Content: DirectDraw Factory support * History: * Date By Reason * ==== == ====== * 24-feb-97 ralphl initial implementation * 25-feb-97 craige minor tweaks for dx checkin * 14-mar-97 jeffort version checking changed to support DX3 and above * 09-apr-97 jeffort version checking added for DX2 and NT * 30-apr-97 jeffort version >DX5 treated as DX5 * 10-jul-97 jeffort made OSVersion a static variable * 09-sep-97 mikear QI for IUnknown when aggregating ***************************************************************************/ #include "ddfactry.h"
//#defines for registry lookup
#define REGSTR_PATH_DDRAW "Software\\Microsoft\\DirectDraw"
#define REGSTR_VAL_DDRAW_OWNDC "OWNDC"
CDDFactory::CDDFactory(IUnknown *pUnkOuter) : m_cRef(1), m_pUnkOuter(pUnkOuter != 0 ? pUnkOuter : CAST_TO_IUNKNOWN(this)) { m_hDDrawDLL = NULL; DllAddRef(); }
STDAPI DirectDrawFactory_CreateInstance( IUnknown * pUnkOuter, REFIID riid, void ** ppv) { HRESULT hr; CDDFactory *pFactory = new CDDFactory(pUnkOuter);
if( !pFactory ) { hr = E_OUTOFMEMORY; } else { hr = pFactory->NonDelegatingQueryInterface(pUnkOuter ? IID_IUnknown : riid, ppv); pFactory->NonDelegatingRelease(); } return hr; }
STDMETHODIMP CDDFactory::NonDelegatingQueryInterface(REFIID riid, void ** ppv) { *ppv=NULL;
if (IID_IUnknown==riid) { *ppv=(INonDelegatingUnknown *)this; } else { if (IID_IDirectDrawFactory==riid) { *ppv=(IDirectDrawFactory *)this; } else { return E_NOINTERFACE; } }
((LPUNKNOWN)*ppv)->AddRef(); return NOERROR; }
STDMETHODIMP_(ULONG) CDDFactory::NonDelegatingAddRef() { return InterlockedIncrement(&m_cRef); }
STDMETHODIMP_(ULONG) CDDFactory::NonDelegatingRelease() { LONG lRefCount = InterlockedDecrement(&m_cRef); if( lRefCount ) { return lRefCount; } delete this; DllRelease(); return 0; }
// Standard IUnknown
STDMETHODIMP CDDFactory::QueryInterface(REFIID riid, void ** ppv) { return m_pUnkOuter->QueryInterface(riid, ppv); }
STDMETHODIMP_(ULONG) CDDFactory::AddRef(void) { return m_pUnkOuter->AddRef(); }
STDMETHODIMP_(ULONG) CDDFactory::Release(void) { return m_pUnkOuter->Release(); }
/*
* CDDFactory::CreateDirectDraw */ STDMETHODIMP CDDFactory::CreateDirectDraw( GUID * pGUID, HWND hWnd, DWORD dwCoopLevelFlags, DWORD dwReserved, IUnknown *pUnkOuter, IDirectDraw **ppDirectDraw ) { static OSVERSIONINFO osVer; CDirectDrawEx *pDirectDrawEx; HRESULT hr = S_OK; BOOL fDDrawDllVerFound = FALSE;
*ppDirectDraw = NULL; /*
* first, see if we can get at DirectDraw or not! */ if( m_hDDrawDLL == NULL ) { char path[_MAX_PATH]; char DllName[25]; DWORD dwRet;
// m_hDDrawDLL = LoadLibrary( "ddraw.dll" );
dwRet = GetProfileString("ddrawex","realdll","ddraw.dll",DllName,25); if( dwRet == 0 ) { return DDERR_GENERIC; } m_hDDrawDLL = LoadLibrary( DllName ); if( m_hDDrawDLL == NULL ) { return DDERR_LOADFAILED; }
/*
* get ddraw.dll version number */ if( GetModuleFileName( (HINSTANCE)m_hDDrawDLL, path, sizeof( path ) ) ) { int size; DWORD tmp; size = (int) GetFileVersionInfoSize( path, (LPDWORD) &tmp ); if( size != 0 ) { LPVOID vinfo; vinfo = (LPVOID) LocalAlloc( LPTR, size ); if(vinfo == NULL) { hr = DDERR_OUTOFMEMORY; goto CleanUp; }
if( GetFileVersionInfo( path, 0, size, vinfo ) ) { VS_FIXEDFILEINFO *ver=NULL; UINT cb;
if( VerQueryValue(vinfo, "\\", (LPVOID *)&ver, &cb) ) { if( ver != NULL ) { /*
* we only need the most significant dword, * the LS dword contains the build number only... * Hack: The '|5' forces recognition of DX6+ */ m_dwDDVerMS = ver->dwFileVersionMS | 5; fDDrawDllVerFound = TRUE; } } } LocalFree( vinfo ); } }
osVer.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if ( !fDDrawDllVerFound || !GetVersionEx(&osVer) ) { hr = DDERR_BADVERSIONINFO; goto CleanUp; }
//if we are on NT4.0 Gold, the DLL version will be 4.00
if (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT && LOWORD( m_dwDDVerMS) == 0) { //boost the LOWORD up so we will not fail the next check below
m_dwDDVerMS += 3; }
/*
* don't work on anything but DX2 DX 3 or DX 5. */ if( !((HIWORD( m_dwDDVerMS ) >= 4) && (LOWORD( m_dwDDVerMS) >= 3)) ) { hr = DDERR_UNSUPPORTED; goto CleanUp; }
if( LOWORD( m_dwDDVerMS) > 5) { //we will assume that any version >= DX5 will support what we need, so we
//will mark anything greater than 5 as DX5
m_dwDDVerMS = 5; }
/*
* get the various entry points we need */ m_pDirectDrawCreate = (LPDIRECTDRAWCREATE) GetProcAddress((HINSTANCE) m_hDDrawDLL, "DirectDrawCreate" ); if( m_pDirectDrawCreate == NULL ) { hr = DDERR_BADPROCADDRESS; goto CleanUp; }
m_pDirectDrawEnumerateW = (LPDIRECTDRAWENUMW) GetProcAddress( (HINSTANCE)m_hDDrawDLL, "DirectDrawEnumerateW" ); if( m_pDirectDrawEnumerateW == NULL ) { hr = DDERR_BADPROCADDRESS; goto CleanUp; }
m_pDirectDrawEnumerateA = (LPDIRECTDRAWENUMA) GetProcAddress((HINSTANCE) m_hDDrawDLL, "DirectDrawEnumerateA" ); if( m_pDirectDrawEnumerateA == NULL ) { hr = DDERR_BADPROCADDRESS; goto CleanUp; }
} // m_hDDrawDLL = NULL
/*
* create and initialize the ddrawex object */ pDirectDrawEx = new CDirectDrawEx(pUnkOuter); if( !pDirectDrawEx ) { hr = DDERR_OUTOFMEMORY; goto CleanUp; } else { hr = pDirectDrawEx->Init( pGUID, hWnd, dwCoopLevelFlags, dwReserved, m_pDirectDrawCreate );
if( SUCCEEDED(hr) ) { hr = pDirectDrawEx->NonDelegatingQueryInterface(IID_IDirectDraw, (void **)ppDirectDraw); /*
* save the ddraw version number... */ if (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT) { if( LOWORD( m_dwDDVerMS ) == 5 ) { DWORD type; DWORD value; DWORD cb; HKEY hkey;
//DX5 is busted with OwnDC for StretchBlt
//check a registry key to see if we are
//using dx5 style or dx3 style.
//default is dx3
pDirectDrawEx->m_dwDDVer = WINNT_DX5;
if( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, REGSTR_PATH_DDRAW, &hkey ) ) { cb = sizeof( value ); if( ERROR_SUCCESS == RegQueryValueEx( hkey, REGSTR_VAL_DDRAW_OWNDC, NULL, &type, (CONST LPBYTE)&value, &cb ) ) { pDirectDrawEx->m_dwDDVer = WINNT_DX5; } RegCloseKey(hkey); } } else if (LOWORD (m_dwDDVerMS) == 4 ) { pDirectDrawEx->m_dwDDVer = WINNT_DX3; } else if (LOWORD (m_dwDDVerMS) == 3 ) { pDirectDrawEx->m_dwDDVer = WINNT_DX2; } //should never get here, alread checked above, but be a bit anal
else { hr = DDERR_UNSUPPORTED; goto CleanUp; } } else { if( LOWORD( m_dwDDVerMS ) == 5 ) { pDirectDrawEx->m_dwDDVer = WIN95_DX5; } else if (LOWORD (m_dwDDVerMS) == 4 ) { pDirectDrawEx->m_dwDDVer = WIN95_DX3; } else if (LOWORD (m_dwDDVerMS) == 3 ) { pDirectDrawEx->m_dwDDVer = WIN95_DX2; } //should never get here, alread checked above, but be a bit anal
else { hr = DDERR_UNSUPPORTED; goto CleanUp; } } } pDirectDrawEx->NonDelegatingRelease(); }
CleanUp:
if( hr != S_OK && m_hDDrawDLL != NULL ) { FreeLibrary((HINSTANCE) m_hDDrawDLL ); m_hDDrawDLL = NULL; }
return hr; } /* CDDFactory::CreateDirectDraw */
/*
* CDDFactory::DirectDrawEnumerate * * implements ddraw enumerate. */ STDMETHODIMP CDDFactory::DirectDrawEnumerate(LPDDENUMCALLBACK lpCallback, LPVOID lpContext) { #pragma message( REMIND( "DDFactory::DirectDrawEnumerate assumes ANSI" ))
return m_pDirectDrawEnumerateA(lpCallback, lpContext);
} /* CDDFactory::DirectDrawEnumerate */
|