527 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			527 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								//------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// File: WXUtil.h
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Desc: DirectShow base classes - defines helper classes and functions for
							 | 
						||
| 
								 | 
							
								//       building multimedia filters.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
							 | 
						||
| 
								 | 
							
								//------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef __WXUTIL__
							 | 
						||
| 
								 | 
							
								#define __WXUTIL__
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// eliminate spurious "statement has no effect" warnings.
							 | 
						||
| 
								 | 
							
								#pragma warning(disable: 4705)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// wrapper for whatever critical section we have
							 | 
						||
| 
								 | 
							
								class CCritSec {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // make copy constructor and assignment operator inaccessible
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CCritSec(const CCritSec &refCritSec);
							 | 
						||
| 
								 | 
							
								    CCritSec &operator=(const CCritSec &refCritSec);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CRITICAL_SECTION m_CritSec;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    DWORD   m_currentOwner;
							 | 
						||
| 
								 | 
							
								    DWORD   m_lockCount;
							 | 
						||
| 
								 | 
							
								    BOOL    m_fTrace;        // Trace this one
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    CCritSec();
							 | 
						||
| 
								 | 
							
								    ~CCritSec();
							 | 
						||
| 
								 | 
							
								    void Lock();
							 | 
						||
| 
								 | 
							
								    void Unlock();
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    CCritSec() {
							 | 
						||
| 
								 | 
							
								        InitializeCriticalSection(&m_CritSec);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ~CCritSec() {
							 | 
						||
| 
								 | 
							
								        DeleteCriticalSection(&m_CritSec);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void Lock() {
							 | 
						||
| 
								 | 
							
								        EnterCriticalSection(&m_CritSec);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void Unlock() {
							 | 
						||
| 
								 | 
							
								        LeaveCriticalSection(&m_CritSec);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// To make deadlocks easier to track it is useful to insert in the
							 | 
						||
| 
								 | 
							
								// code an assertion that says whether we own a critical section or
							 | 
						||
| 
								 | 
							
								// not.  We make the routines that do the checking globals to avoid
							 | 
						||
| 
								 | 
							
								// having different numbers of member functions in the debug and
							 | 
						||
| 
								 | 
							
								// retail class implementations of CCritSec.  In addition we provide
							 | 
						||
| 
								 | 
							
								// a routine that allows usage of specific critical sections to be
							 | 
						||
| 
								 | 
							
								// traced.  This is NOT on by default - there are far too many.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG
							 | 
						||
| 
								 | 
							
								    BOOL WINAPI CritCheckIn(CCritSec * pcCrit);
							 | 
						||
| 
								 | 
							
								    BOOL WINAPI CritCheckIn(const CCritSec * pcCrit);
							 | 
						||
| 
								 | 
							
								    BOOL WINAPI CritCheckOut(CCritSec * pcCrit);
							 | 
						||
| 
								 | 
							
								    BOOL WINAPI CritCheckOut(const CCritSec * pcCrit);
							 | 
						||
| 
								 | 
							
								    void WINAPI DbgLockTrace(CCritSec * pcCrit, BOOL fTrace);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    #define CritCheckIn(x) TRUE
							 | 
						||
| 
								 | 
							
								    #define CritCheckOut(x) TRUE
							 | 
						||
| 
								 | 
							
								    #define DbgLockTrace(pc, fT)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// locks a critical section, and unlocks it automatically
							 | 
						||
| 
								 | 
							
								// when the lock goes out of scope
							 | 
						||
| 
								 | 
							
								class CAutoLock {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // make copy constructor and assignment operator inaccessible
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CAutoLock(const CAutoLock &refAutoLock);
							 | 
						||
| 
								 | 
							
								    CAutoLock &operator=(const CAutoLock &refAutoLock);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								protected:
							 | 
						||
| 
								 | 
							
								    CCritSec * m_pLock;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    CAutoLock(CCritSec * plock)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        m_pLock = plock;
							 | 
						||
| 
								 | 
							
								        m_pLock->Lock();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ~CAutoLock() {
							 | 
						||
| 
								 | 
							
								        m_pLock->Unlock();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// wrapper for event objects
							 | 
						||
| 
								 | 
							
								class CAMEvent
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // make copy constructor and assignment operator inaccessible
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CAMEvent(const CAMEvent &refEvent);
							 | 
						||
| 
								 | 
							
								    CAMEvent &operator=(const CAMEvent &refEvent);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								protected:
							 | 
						||
| 
								 | 
							
								    HANDLE m_hEvent;
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    CAMEvent(BOOL fManualReset = FALSE, __inout_opt HRESULT *phr = NULL);
							 | 
						||
| 
								 | 
							
								    CAMEvent(__inout_opt HRESULT *phr);
							 | 
						||
| 
								 | 
							
								    ~CAMEvent();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Cast to HANDLE - we don't support this as an lvalue
							 | 
						||
| 
								 | 
							
								    operator HANDLE () const { return m_hEvent; };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void Set() {EXECUTE_ASSERT(SetEvent(m_hEvent));};
							 | 
						||
| 
								 | 
							
								    BOOL Wait(DWORD dwTimeout = INFINITE) {
							 | 
						||
| 
								 | 
							
									return (WaitForSingleObject(m_hEvent, dwTimeout) == WAIT_OBJECT_0);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    void Reset() { ResetEvent(m_hEvent); };
							 | 
						||
| 
								 | 
							
								    BOOL Check() { return Wait(0); };
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// wrapper for event objects that do message processing
							 | 
						||
| 
								 | 
							
								// This adds ONE method to the CAMEvent object to allow sent
							 | 
						||
| 
								 | 
							
								// messages to be processed while waiting
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class CAMMsgEvent : public CAMEvent
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CAMMsgEvent(__inout_opt HRESULT *phr = NULL);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Allow SEND messages to be processed while waiting
							 | 
						||
| 
								 | 
							
								    BOOL WaitMsg(DWORD dwTimeout = INFINITE);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// old name supported for the time being
							 | 
						||
| 
								 | 
							
								#define CTimeoutEvent CAMEvent
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// support for a worker thread
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef AM_NOVTABLE
							 | 
						||
| 
								 | 
							
								// simple thread class supports creation of worker thread, synchronization
							 | 
						||
| 
								 | 
							
								// and communication. Can be derived to simplify parameter passing
							 | 
						||
| 
								 | 
							
								class AM_NOVTABLE CAMThread {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // make copy constructor and assignment operator inaccessible
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CAMThread(const CAMThread &refThread);
							 | 
						||
| 
								 | 
							
								    CAMThread &operator=(const CAMThread &refThread);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CAMEvent m_EventSend;
							 | 
						||
| 
								 | 
							
								    CAMEvent m_EventComplete;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    DWORD m_dwParam;
							 | 
						||
| 
								 | 
							
								    DWORD m_dwReturnVal;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								protected:
							 | 
						||
| 
								 | 
							
								    HANDLE m_hThread;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // thread will run this function on startup
							 | 
						||
| 
								 | 
							
								    // must be supplied by derived class
							 | 
						||
| 
								 | 
							
								    virtual DWORD ThreadProc() = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    CAMThread(__inout_opt HRESULT *phr = NULL);
							 | 
						||
| 
								 | 
							
								    virtual ~CAMThread();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CCritSec m_AccessLock;	// locks access by client threads
							 | 
						||
| 
								 | 
							
								    CCritSec m_WorkerLock;	// locks access to shared objects
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // thread initially runs this. param is actually 'this'. function
							 | 
						||
| 
								 | 
							
								    // just gets this and calls ThreadProc
							 | 
						||
| 
								 | 
							
								    static DWORD WINAPI InitialThreadProc(__inout LPVOID pv);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // start thread running  - error if already running
							 | 
						||
| 
								 | 
							
								    BOOL Create();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // signal the thread, and block for a response
							 | 
						||
| 
								 | 
							
								    //
							 | 
						||
| 
								 | 
							
								    DWORD CallWorker(DWORD);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // accessor thread calls this when done with thread (having told thread
							 | 
						||
| 
								 | 
							
								    // to exit)
							 | 
						||
| 
								 | 
							
								    void Close() {
							 | 
						||
| 
								 | 
							
								        HANDLE hThread = (HANDLE)InterlockedExchangePointer(&m_hThread, 0);
							 | 
						||
| 
								 | 
							
								        if (hThread) {
							 | 
						||
| 
								 | 
							
								            WaitForSingleObject(hThread, INFINITE);
							 | 
						||
| 
								 | 
							
								            CloseHandle(hThread);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // ThreadExists
							 | 
						||
| 
								 | 
							
								    // Return TRUE if the thread exists. FALSE otherwise
							 | 
						||
| 
								 | 
							
								    BOOL ThreadExists(void) const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (m_hThread == 0) {
							 | 
						||
| 
								 | 
							
								            return FALSE;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            return TRUE;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // wait for the next request
							 | 
						||
| 
								 | 
							
								    DWORD GetRequest();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // is there a request?
							 | 
						||
| 
								 | 
							
								    BOOL CheckRequest(__out_opt DWORD * pParam);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // reply to the request
							 | 
						||
| 
								 | 
							
								    void Reply(DWORD);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // If you want to do WaitForMultipleObjects you'll need to include
							 | 
						||
| 
								 | 
							
								    // this handle in your wait list or you won't be responsive
							 | 
						||
| 
								 | 
							
								    HANDLE GetRequestHandle() const { return m_EventSend; };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Find out what the request was
							 | 
						||
| 
								 | 
							
								    DWORD GetRequestParam() const { return m_dwParam; };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // call CoInitializeEx (COINIT_DISABLE_OLE1DDE) if
							 | 
						||
| 
								 | 
							
								    // available. S_FALSE means it's not available.
							 | 
						||
| 
								 | 
							
								    static HRESULT CoInitializeHelper();
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								#endif // AM_NOVTABLE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// CQueue
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Implements a simple Queue ADT.  The queue contains a finite number of
							 | 
						||
| 
								 | 
							
								// objects, access to which is controlled by a semaphore.  The semaphore
							 | 
						||
| 
								 | 
							
								// is created with an initial count (N).  Each time an object is added
							 | 
						||
| 
								 | 
							
								// a call to WaitForSingleObject is made on the semaphore's handle.  When
							 | 
						||
| 
								 | 
							
								// this function returns a slot has been reserved in the queue for the new
							 | 
						||
| 
								 | 
							
								// object.  If no slots are available the function blocks until one becomes
							 | 
						||
| 
								 | 
							
								// available.  Each time an object is removed from the queue ReleaseSemaphore
							 | 
						||
| 
								 | 
							
								// is called on the semaphore's handle, thus freeing a slot in the queue.
							 | 
						||
| 
								 | 
							
								// If no objects are present in the queue the function blocks until an
							 | 
						||
| 
								 | 
							
								// object has been added.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define DEFAULT_QUEUESIZE   2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class T> class CQueue {
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    HANDLE          hSemPut;        // Semaphore controlling queue "putting"
							 | 
						||
| 
								 | 
							
								    HANDLE          hSemGet;        // Semaphore controlling queue "getting"
							 | 
						||
| 
								 | 
							
								    CRITICAL_SECTION CritSect;      // Thread seriallization
							 | 
						||
| 
								 | 
							
								    int             nMax;           // Max objects allowed in queue
							 | 
						||
| 
								 | 
							
								    int             iNextPut;       // Array index of next "PutMsg"
							 | 
						||
| 
								 | 
							
								    int             iNextGet;       // Array index of next "GetMsg"
							 | 
						||
| 
								 | 
							
								    T              *QueueObjects;   // Array of objects (ptr's to void)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void Initialize(int n) {
							 | 
						||
| 
								 | 
							
								        iNextPut = iNextGet = 0;
							 | 
						||
| 
								 | 
							
								        nMax = n;
							 | 
						||
| 
								 | 
							
								        InitializeCriticalSection(&CritSect);
							 | 
						||
| 
								 | 
							
								        hSemPut = CreateSemaphore(NULL, n, n, NULL);
							 | 
						||
| 
								 | 
							
								        hSemGet = CreateSemaphore(NULL, 0, n, NULL);
							 | 
						||
| 
								 | 
							
								        QueueObjects = new T[n];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    CQueue(int n) {
							 | 
						||
| 
								 | 
							
								        Initialize(n);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CQueue() {
							 | 
						||
| 
								 | 
							
								        Initialize(DEFAULT_QUEUESIZE);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ~CQueue() {
							 | 
						||
| 
								 | 
							
								        delete [] QueueObjects;
							 | 
						||
| 
								 | 
							
								        DeleteCriticalSection(&CritSect);
							 | 
						||
| 
								 | 
							
								        CloseHandle(hSemPut);
							 | 
						||
| 
								 | 
							
								        CloseHandle(hSemGet);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    T GetQueueObject() {
							 | 
						||
| 
								 | 
							
								        int iSlot;
							 | 
						||
| 
								 | 
							
								        T Object;
							 | 
						||
| 
								 | 
							
								        LONG lPrevious;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Wait for someone to put something on our queue, returns straight
							 | 
						||
| 
								 | 
							
								        // away is there is already an object on the queue.
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        WaitForSingleObject(hSemGet, INFINITE);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        EnterCriticalSection(&CritSect);
							 | 
						||
| 
								 | 
							
								        iSlot = iNextGet++ % nMax;
							 | 
						||
| 
								 | 
							
								        Object = QueueObjects[iSlot];
							 | 
						||
| 
								 | 
							
								        LeaveCriticalSection(&CritSect);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Release anyone waiting to put an object onto our queue as there
							 | 
						||
| 
								 | 
							
								        // is now space available in the queue.
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        ReleaseSemaphore(hSemPut, 1L, &lPrevious);
							 | 
						||
| 
								 | 
							
								        return Object;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void PutQueueObject(T Object) {
							 | 
						||
| 
								 | 
							
								        int iSlot;
							 | 
						||
| 
								 | 
							
								        LONG lPrevious;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Wait for someone to get something from our queue, returns straight
							 | 
						||
| 
								 | 
							
								        // away is there is already an empty slot on the queue.
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        WaitForSingleObject(hSemPut, INFINITE);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        EnterCriticalSection(&CritSect);
							 | 
						||
| 
								 | 
							
								        iSlot = iNextPut++ % nMax;
							 | 
						||
| 
								 | 
							
								        QueueObjects[iSlot] = Object;
							 | 
						||
| 
								 | 
							
								        LeaveCriticalSection(&CritSect);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Release anyone waiting to remove an object from our queue as there
							 | 
						||
| 
								 | 
							
								        // is now an object available to be removed.
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        ReleaseSemaphore(hSemGet, 1L, &lPrevious);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Ensures that memory is not read past the length source buffer
							 | 
						||
| 
								 | 
							
								// and that memory is not written past the length of the dst buffer
							 | 
						||
| 
								 | 
							
								//   dst - buffer to copy to
							 | 
						||
| 
								 | 
							
								//   dst_size - total size of destination buffer
							 | 
						||
| 
								 | 
							
								//   cb_dst_offset - offset, first byte copied to dst+cb_dst_offset
							 | 
						||
| 
								 | 
							
								//   src - buffer to copy from
							 | 
						||
| 
								 | 
							
								//   src_size - total size of source buffer
							 | 
						||
| 
								 | 
							
								//   cb_src_offset - offset, first byte copied from src+cb_src_offset
							 | 
						||
| 
								 | 
							
								//   count - number of bytes to copy
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Returns:
							 | 
						||
| 
								 | 
							
								//    S_OK          - no error
							 | 
						||
| 
								 | 
							
								//    E_INVALIDARG  - values passed would lead to overrun
							 | 
						||
| 
								 | 
							
								HRESULT AMSafeMemMoveOffset(
							 | 
						||
| 
								 | 
							
								    __in_bcount(dst_size) void * dst,
							 | 
						||
| 
								 | 
							
								    __in size_t dst_size,
							 | 
						||
| 
								 | 
							
								    __in DWORD cb_dst_offset,
							 | 
						||
| 
								 | 
							
								    __in_bcount(src_size) const void * src,
							 | 
						||
| 
								 | 
							
								    __in size_t src_size,
							 | 
						||
| 
								 | 
							
								    __in DWORD cb_src_offset,
							 | 
						||
| 
								 | 
							
								    __in size_t count);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								extern "C"
							 | 
						||
| 
								 | 
							
								void * __stdcall memmoveInternal(void *, const void *, size_t);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline void * __cdecl memchrInternal(const void *buf, int chr, size_t cnt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#ifdef _X86_
							 | 
						||
| 
								 | 
							
								    void *pRet = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    _asm {
							 | 
						||
| 
								 | 
							
								        cld                 // make sure we get the direction right
							 | 
						||
| 
								 | 
							
								        mov     ecx, cnt    // num of bytes to scan
							 | 
						||
| 
								 | 
							
								        mov     edi, buf    // pointer byte stream
							 | 
						||
| 
								 | 
							
								        mov     eax, chr    // byte to scan for
							 | 
						||
| 
								 | 
							
								        repne   scasb       // look for the byte in the byte stream
							 | 
						||
| 
								 | 
							
								        jnz     exit_memchr // Z flag set if byte found
							 | 
						||
| 
								 | 
							
								        dec     edi         // scasb always increments edi even when it
							 | 
						||
| 
								 | 
							
								                            // finds the required byte
							 | 
						||
| 
								 | 
							
								        mov     pRet, edi
							 | 
						||
| 
								 | 
							
								exit_memchr:
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return pRet;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    while ( cnt && (*(unsigned char *)buf != (unsigned char)chr) ) {
							 | 
						||
| 
								 | 
							
								        buf = (unsigned char *)buf + 1;
							 | 
						||
| 
								 | 
							
								        cnt--;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return(cnt ? (void *)buf : NULL);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void WINAPI IntToWstr(int i, __out_ecount(12) LPWSTR wstr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define WstrToInt(sz) _wtoi(sz)
							 | 
						||
| 
								 | 
							
								#define atoiW(sz) _wtoi(sz)
							 | 
						||
| 
								 | 
							
								#define atoiA(sz) atoi(sz)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// These are available to help managing bitmap VIDEOINFOHEADER media structures
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								extern const DWORD bits555[3];
							 | 
						||
| 
								 | 
							
								extern const DWORD bits565[3];
							 | 
						||
| 
								 | 
							
								extern const DWORD bits888[3];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// These help convert between VIDEOINFOHEADER and BITMAPINFO structures
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDAPI_(const GUID) GetTrueColorType(const BITMAPINFOHEADER *pbmiHeader);
							 | 
						||
| 
								 | 
							
								STDAPI_(const GUID) GetBitmapSubtype(const BITMAPINFOHEADER *pbmiHeader);
							 | 
						||
| 
								 | 
							
								STDAPI_(WORD) GetBitCount(const GUID *pSubtype);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// strmbase.lib implements this for compatibility with people who
							 | 
						||
| 
								 | 
							
								// managed to link to this directly.  we don't want to advertise it.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// STDAPI_(/* T */ CHAR *) GetSubtypeName(const GUID *pSubtype);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDAPI_(const CHAR *) GetSubtypeNameA(const GUID *pSubtype);
							 | 
						||
| 
								 | 
							
								STDAPI_(const WCHAR *) GetSubtypeNameW(const GUID *pSubtype);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef UNICODE
							 | 
						||
| 
								 | 
							
								#define GetSubtypeName GetSubtypeNameW
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#define GetSubtypeName GetSubtypeNameA
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDAPI_(LONG) GetBitmapFormatSize(const BITMAPINFOHEADER *pHeader);
							 | 
						||
| 
								 | 
							
								STDAPI_(DWORD) GetBitmapSize(const BITMAPINFOHEADER *pHeader);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef __AMVIDEO__
							 | 
						||
| 
								 | 
							
								STDAPI_(BOOL) ContainsPalette(const VIDEOINFOHEADER *pVideoInfo);
							 | 
						||
| 
								 | 
							
								STDAPI_(const RGBQUAD *) GetBitmapPalette(const VIDEOINFOHEADER *pVideoInfo);
							 | 
						||
| 
								 | 
							
								#endif // __AMVIDEO__
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Compares two interfaces and returns TRUE if they are on the same object
							 | 
						||
| 
								 | 
							
								BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// This is for comparing pins
							 | 
						||
| 
								 | 
							
								#define EqualPins(pPin1, pPin2) IsEqualObject(pPin1, pPin2)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Arithmetic helper functions
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Compute (a * b + rnd) / c
							 | 
						||
| 
								 | 
							
								LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG rnd);
							 | 
						||
| 
								 | 
							
								LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG rnd);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Avoids us dyna-linking to SysAllocString to copy BSTR strings
							 | 
						||
| 
								 | 
							
								STDAPI WriteBSTR(__deref_out BSTR * pstrDest, LPCWSTR szSrc);
							 | 
						||
| 
								 | 
							
								STDAPI FreeBSTR(__deref_in BSTR* pstr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Return a wide string - allocating memory for it
							 | 
						||
| 
								 | 
							
								// Returns:
							 | 
						||
| 
								 | 
							
								//    S_OK          - no error
							 | 
						||
| 
								 | 
							
								//    E_POINTER     - ppszReturn == NULL
							 | 
						||
| 
								 | 
							
								//    E_OUTOFMEMORY - can't allocate memory for returned string
							 | 
						||
| 
								 | 
							
								STDAPI AMGetWideString(LPCWSTR pszString, __deref_out LPWSTR *ppszReturn);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Special wait for objects owning windows
							 | 
						||
| 
								 | 
							
								DWORD WINAPI WaitDispatchingMessages(
							 | 
						||
| 
								 | 
							
								    HANDLE hObject,
							 | 
						||
| 
								 | 
							
								    DWORD dwWait,
							 | 
						||
| 
								 | 
							
								    HWND hwnd = NULL,
							 | 
						||
| 
								 | 
							
								    UINT uMsg = 0,
							 | 
						||
| 
								 | 
							
								    HANDLE hEvent = NULL);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// HRESULT_FROM_WIN32 converts ERROR_SUCCESS to a success code, but in
							 | 
						||
| 
								 | 
							
								// our use of HRESULT_FROM_WIN32, it typically means a function failed
							 | 
						||
| 
								 | 
							
								// to call SetLastError(), and we still want a failure code.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								#define AmHresultFromWin32(x) (MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, x))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// call GetLastError and return an HRESULT value that will fail the
							 | 
						||
| 
								 | 
							
								// SUCCEEDED() macro.
							 | 
						||
| 
								 | 
							
								HRESULT AmGetLastErrorToHResult(void);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// duplicate of ATL's CComPtr to avoid linker conflicts.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								IUnknown* QzAtlComPtrAssign(__deref_inout_opt IUnknown** pp, __in_opt IUnknown* lp);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class T>
							 | 
						||
| 
								 | 
							
								class QzCComPtr
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
									typedef T _PtrClass;
							 | 
						||
| 
								 | 
							
									QzCComPtr() {p=NULL;}
							 | 
						||
| 
								 | 
							
									QzCComPtr(T* lp)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ((p = lp) != NULL)
							 | 
						||
| 
								 | 
							
											p->AddRef();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									QzCComPtr(const QzCComPtr<T>& lp)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										if ((p = lp.p) != NULL)
							 | 
						||
| 
								 | 
							
											p->AddRef();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									~QzCComPtr() {if (p) p->Release();}
							 | 
						||
| 
								 | 
							
									void Release() {if (p) p->Release(); p=NULL;}
							 | 
						||
| 
								 | 
							
									operator T*() {return (T*)p;}
							 | 
						||
| 
								 | 
							
									T& operator*() {ASSERT(p!=NULL); return *p; }
							 | 
						||
| 
								 | 
							
									//The assert on operator& usually indicates a bug.  If this is really
							 | 
						||
| 
								 | 
							
									//what is needed, however, take the address of the p member explicitly.
							 | 
						||
| 
								 | 
							
									T** operator&() { ASSERT(p==NULL); return &p; }
							 | 
						||
| 
								 | 
							
									T* operator->() { ASSERT(p!=NULL); return p; }
							 | 
						||
| 
								 | 
							
									T* operator=(T* lp){return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp);}
							 | 
						||
| 
								 | 
							
									T* operator=(const QzCComPtr<T>& lp)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp.p);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								#if _MSC_VER>1020
							 | 
						||
| 
								 | 
							
									bool operator!(){return (p == NULL);}
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									BOOL operator!(){return (p == NULL) ? TRUE : FALSE;}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									T* p;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								MMRESULT CompatibleTimeSetEvent( UINT uDelay, UINT uResolution, __in LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent );
							 | 
						||
| 
								 | 
							
								bool TimeKillSynchronousFlagAvailable( void );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//  Helper to replace lstrcpmi
							 | 
						||
| 
								 | 
							
								__inline int lstrcmpiLocaleIndependentW(LPCWSTR lpsz1, LPCWSTR lpsz2)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return  CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, lpsz1, -1, lpsz2, -1) - CSTR_EQUAL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								__inline int lstrcmpiLocaleIndependentA(LPCSTR lpsz1, LPCSTR lpsz2)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return  CompareStringA(LOCALE_INVARIANT, NORM_IGNORECASE, lpsz1, -1, lpsz2, -1) - CSTR_EQUAL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif /* __WXUTIL__ */
							 |