
// ---------------------------------------------------------------------
//
// COMMON.CPP   - QuickTime for Windows Sample Decompressor
//
//                Version 1.1
//
//                (c) 1988-1993 Apple Computer, Inc. All Rights Reserved.
//
// ---------------------------------------------------------------------


// Windows header files
#include <windows.h>
#include <windowsx.h>

// Compiler header files
#include <ver.h>

// Application header files
#include "prototyp.hp"

// Local functions
static VOID FAR PASCAL FixupCM( ENTRYFUNC lpfnCM) ;
static VOID FAR PASCAL FixupTB( ENTRYFUNC lpfnTB) ;

// Global data
ENTRYFUNC lpfnQTComponentManager ;
ENTRYFUNC lpfnQTToolbox ;
extern "C" BOOL fQTInitPerformed ;
extern ComponentDescription cdTable[] ; // components in this DLL

/* function cfCanDoSelect:
   Report if a function is implemented
*/
ComponentResult QTAPI cfCanDoSelect( STKOFF_CMP so, LONG lFunctionSelector)
{
    switch ( lFunctionSelector)  { // switch on function selector
        case kComponentOpenSelect :
        case kComponentCloseSelect :
        case kComponentCanDoSelect :
        case kComponentVersionSelect :
        case kComponentRegisterSelect :
        case kComponentTargetSelect :
        case codecPreDecompress :
        case codecBandDecompress :
        case codecCDSequenceBusy :
        case codecGetCodecInfo :
            return TRUE ;
        default :
            return FALSE ;
    } // switch on function selector
} // cfCanDoSelect

/* function RegisterSelect:
   Return 0 as there is nothing to check before registering
*/
ComponentResult QTAPI cfRegisterSelect( STKOFF_CMP so, ComponentInstance ci)
{
    return 0;
} // cfRegisterSelect

/* function TargetSelect:
   Not implemented
*/
ComponentResult QTAPI cfTargetSelect( STKOFF_CMP so, ComponentInstance ci)
{
    // successful return
    return noErr ;
} // cfTargetSelect

/* function cfVersionSelect:
   Return the version of this component.  We take the information directly
   the Windows version information.
*/
ComponentResult QTAPI cfVersionSelect( STKOFF_CMP so, ComponentInstance ci)
{
    // load VER.DLL
    UINT uOldErrorMode = SetErrorMode( SEM_NOOPENFILEERRORBOX) ; // no message box
    HINSTANCE hLibrary = LoadLibrary( "ver.dll") ;
    SetErrorMode( uOldErrorMode) ;                               // restore application's settings
    if ( hLibrary < HINSTANCE_ERROR)                             // if load error
        return -1 ;                                              // take error return

    // locate the exported functions of interest
    typedef DWORD (WINAPI *PGETFILEVERSIONINFOSIZE) (LPCSTR, DWORD FAR *) ;
    typedef BOOL (WINAPI *PGETFILEVERSIONINFO) (LPCSTR, DWORD, DWORD, LPVOID) ;
    typedef BOOL ( WINAPI *PVERQUERYVALUE) ( const VOID FAR *
                                           , LPCSTR
                                           , VOID FAR * FAR *
                                           , UINT FAR *
                                           ) ;
    PGETFILEVERSIONINFOSIZE pGetFileVersionInfoSize
        = ( PGETFILEVERSIONINFOSIZE) GetProcAddress( hLibrary, "#6") ;
    PGETFILEVERSIONINFO pGetFileVersionInfo
        = ( PGETFILEVERSIONINFO) GetProcAddress( hLibrary, "#7") ;
    PVERQUERYVALUE pVerQueryValue
        = ( PVERQUERYVALUE) GetProcAddress( hLibrary, "#11") ;
    if ( pGetFileVersionInfoSize == 0
        ||  pGetFileVersionInfo == 0
        ||  pVerQueryValue == 0)  {
        FreeLibrary( hLibrary) ; // clean up
        return -1 ;              // take error return
    } // if any GetProcAddress call failed

    // get this module's file name
    char szFilename[ _MAX_PATH] ;
    if ( GetModuleFileName( GetInstOfThisMod()
        , szFilename
        , sizeof szFilename
        ) == 0)  {
        FreeLibrary( hLibrary) ; // clean up
        return -1 ;              // take error return
    } // if GetModuleFileName failed

    // get version data
    DWORD hVer
        , dwSize = ( *pGetFileVersionInfoSize)( szFilename, &hVer)
        ;
    if ( dwSize == 0)  {         // if error
        FreeLibrary( hLibrary) ; // clean up
        return -1 ;              // take error return
    } // if error from GetFileVersionInfoSize
    BYTE abData[ 512] ;
    if ( ( *pGetFileVersionInfo)( szFilename, hVer, dwSize, abData) == FALSE)  {
        FreeLibrary( hLibrary) ; // clean up
        return -1 ;              // take error return
    } // if error from GetFileVersionInfo
    UINT uiSize ;
    VS_FIXEDFILEINFO FAR *lpvsffi ;
    if ( ( *pVerQueryValue) ( abData
        , "\\"
        , ( VOID FAR * FAR *) &lpvsffi
        , &uiSize
        ) == FALSE)  {           // if error
        FreeLibrary( hLibrary) ; // clean up
        return -1 ;              // take error return
    } // if error from VerQueryValue
    LONG lVersion = ( HIWORD( lpvsffi->dwProductVersionMS) << 4)
        +  ( LOWORD( lpvsffi->dwProductVersionMS) << 8)
        +  HIWORD( lpvsffi->dwProductVersionLS)
        ;

    // clean up and return version number to caller
    FreeLibrary( hLibrary) ;
    return lVersion ;
} // cfVersionSelect

/* function FixupCM:
   Establish direct linkage to Component Manager
*/
static VOID FAR PASCAL FixupCM( ENTRYFUNC lpfnCM)
{
    lpfnQTComponentManager = lpfnCM;
    //fQTInitPerformed = TRUE;
} // FixupCM

/* function FixupTB:
   Establish direct linkage to Movie Toolbox
*/
static VOID FAR PASCAL FixupTB( ENTRYFUNC lpfnTB)
{
    lpfnQTToolbox = lpfnTB;
    //fQTInitPerformed = TRUE;
} // FixupTB

/* function THNGIDENTIFY:
   Entry point called by Component Manager

   The function fills the Component ID structure.
*/
OSType FAR PASCAL THNGIDENTIFY( LPCID FAR *lplpcid)
{
    // allocate memory for CID information
    // The memory will be freed by the Component Manager.
    LPCID lpcid = ( LPCID) GetMemory( sizeof CID) ;
    if ( lpcid == 0) // if allocation failed
        return 0 ;   // take error return

    // fill the structure
    lpcid->lVersion = CID_VERSION ;
    lpcid->sComponentCount = 1 ;
    lpcid->lpcdTable = ( LPCD) &cdTable ;
    lpcid->lpfnTBFixup = FixupTB ;
    lpcid->lpfnCMFixup = FixupCM ;
    *lplpcid = lpcid ;

    // return to caller
    return THING ;
} // THNGIDENTIFY
