Support unrar64.dll
[xy_vsfilter.git] / src / filters / BaseClasses / wxutil.h
blob8fdcb4189170c04099b846d81bfd35e4c7fcba69
1 //------------------------------------------------------------------------------
2 // File: WXUtil.h
3 //
4 // Desc: DirectShow base classes - defines helper classes and functions for
5 // building multimedia filters.
6 //
7 // Copyright (c) 1992-2002 Microsoft Corporation. All rights reserved.
8 //------------------------------------------------------------------------------
11 #ifndef __WXUTIL__
12 #define __WXUTIL__
14 // eliminate spurious "statement has no effect" warnings.
15 #pragma warning(disable: 4705)
17 // wrapper for whatever critical section we have
18 class CCritSec {
20 // make copy constructor and assignment operator inaccessible
22 CCritSec(const CCritSec &refCritSec);
23 CCritSec &operator=(const CCritSec &refCritSec);
25 CRITICAL_SECTION m_CritSec;
27 #ifdef DEBUG
28 public:
29 DWORD m_currentOwner;
30 DWORD m_lockCount;
31 BOOL m_fTrace; // Trace this one
32 public:
33 CCritSec();
34 ~CCritSec();
35 void Lock();
36 void Unlock();
37 #else
39 public:
40 CCritSec() {
41 InitializeCriticalSection(&m_CritSec);
44 ~CCritSec() {
45 DeleteCriticalSection(&m_CritSec);
48 void Lock() {
49 EnterCriticalSection(&m_CritSec);
52 void Unlock() {
53 LeaveCriticalSection(&m_CritSec);
55 #endif
59 // To make deadlocks easier to track it is useful to insert in the
60 // code an assertion that says whether we own a critical section or
61 // not. We make the routines that do the checking globals to avoid
62 // having different numbers of member functions in the debug and
63 // retail class implementations of CCritSec. In addition we provide
64 // a routine that allows usage of specific critical sections to be
65 // traced. This is NOT on by default - there are far too many.
68 #ifdef DEBUG
69 BOOL WINAPI CritCheckIn(CCritSec * pcCrit);
70 BOOL WINAPI CritCheckIn(const CCritSec * pcCrit);
71 BOOL WINAPI CritCheckOut(CCritSec * pcCrit);
72 BOOL WINAPI CritCheckOut(const CCritSec * pcCrit);
73 void WINAPI DbgLockTrace(CCritSec * pcCrit, BOOL fTrace);
74 #else
75 #define CritCheckIn(x) TRUE
76 #define CritCheckOut(x) TRUE
77 #define DbgLockTrace(pc, fT)
78 #endif
81 // locks a critical section, and unlocks it automatically
82 // when the lock goes out of scope
83 class CAutoLock {
85 // make copy constructor and assignment operator inaccessible
87 CAutoLock(const CAutoLock &refAutoLock);
88 CAutoLock &operator=(const CAutoLock &refAutoLock);
90 protected:
91 CCritSec * m_pLock;
93 public:
94 CAutoLock(CCritSec * plock)
96 m_pLock = plock;
97 m_pLock->Lock();
100 ~CAutoLock() {
101 m_pLock->Unlock();
107 // wrapper for event objects
108 class CAMEvent
111 // make copy constructor and assignment operator inaccessible
113 CAMEvent(const CAMEvent &refEvent);
114 CAMEvent &operator=(const CAMEvent &refEvent);
116 protected:
117 HANDLE m_hEvent;
118 public:
119 CAMEvent(BOOL fManualReset = FALSE);
120 ~CAMEvent();
122 // Cast to HANDLE - we don't support this as an lvalue
123 operator HANDLE () const { return m_hEvent; };
125 void Set() {EXECUTE_ASSERT(SetEvent(m_hEvent));};
126 BOOL Wait(DWORD dwTimeout = INFINITE) {
127 return (WaitForSingleObject(m_hEvent, dwTimeout) == WAIT_OBJECT_0);
129 void Reset() { ResetEvent(m_hEvent); };
130 BOOL Check() { return Wait(0); };
134 // wrapper for event objects that do message processing
135 // This adds ONE method to the CAMEvent object to allow sent
136 // messages to be processed while waiting
138 class CAMMsgEvent : public CAMEvent
141 public:
143 // Allow SEND messages to be processed while waiting
144 BOOL WaitMsg(DWORD dwTimeout = INFINITE);
147 // old name supported for the time being
148 #define CTimeoutEvent CAMEvent
150 // support for a worker thread
152 // simple thread class supports creation of worker thread, synchronization
153 // and communication. Can be derived to simplify parameter passing
154 class AM_NOVTABLE CAMThread {
156 // make copy constructor and assignment operator inaccessible
158 CAMThread(const CAMThread &refThread);
159 CAMThread &operator=(const CAMThread &refThread);
161 CAMEvent m_EventSend;
162 CAMEvent m_EventComplete;
164 DWORD m_dwParam;
165 DWORD m_dwReturnVal;
167 protected:
168 HANDLE m_hThread;
170 // thread will run this function on startup
171 // must be supplied by derived class
172 virtual DWORD ThreadProc() = 0;
174 public:
175 CAMThread();
176 virtual ~CAMThread();
178 CCritSec m_AccessLock; // locks access by client threads
179 CCritSec m_WorkerLock; // locks access to shared objects
181 // thread initially runs this. param is actually 'this'. function
182 // just gets this and calls ThreadProc
183 static DWORD WINAPI InitialThreadProc(LPVOID pv);
185 // start thread running - error if already running
186 BOOL Create();
188 // signal the thread, and block for a response
190 DWORD CallWorker(DWORD);
192 // accessor thread calls this when done with thread (having told thread
193 // to exit)
194 void Close() {
195 HANDLE hThread = (HANDLE)InterlockedExchangePointer(&m_hThread, 0);
196 if (hThread) {
197 WaitForSingleObject(hThread, INFINITE);
198 CloseHandle(hThread);
202 // ThreadExists
203 // Return TRUE if the thread exists. FALSE otherwise
204 BOOL ThreadExists(void) const
206 if (m_hThread == 0) {
207 return FALSE;
208 } else {
209 return TRUE;
213 // wait for the next request
214 DWORD GetRequest();
216 // is there a request?
217 BOOL CheckRequest(DWORD * pParam);
219 // reply to the request
220 void Reply(DWORD);
222 // If you want to do WaitForMultipleObjects you'll need to include
223 // this handle in your wait list or you won't be responsive
224 HANDLE GetRequestHandle() const { return m_EventSend; };
226 // Find out what the request was
227 DWORD GetRequestParam() const { return m_dwParam; };
229 // call CoInitializeEx (COINIT_DISABLE_OLE1DDE) if
230 // available. S_FALSE means it's not available.
231 static HRESULT CoInitializeHelper();
235 // CQueue
237 // Implements a simple Queue ADT. The queue contains a finite number of
238 // objects, access to which is controlled by a semaphore. The semaphore
239 // is created with an initial count (N). Each time an object is added
240 // a call to WaitForSingleObject is made on the semaphore's handle. When
241 // this function returns a slot has been reserved in the queue for the new
242 // object. If no slots are available the function blocks until one becomes
243 // available. Each time an object is removed from the queue ReleaseSemaphore
244 // is called on the semaphore's handle, thus freeing a slot in the queue.
245 // If no objects are present in the queue the function blocks until an
246 // object has been added.
248 #define DEFAULT_QUEUESIZE 2
250 template <class T> class CQueue {
251 private:
252 HANDLE hSemPut; // Semaphore controlling queue "putting"
253 HANDLE hSemGet; // Semaphore controlling queue "getting"
254 CRITICAL_SECTION CritSect; // Thread seriallization
255 int nMax; // Max objects allowed in queue
256 int iNextPut; // Array index of next "PutMsg"
257 int iNextGet; // Array index of next "GetMsg"
258 T *QueueObjects; // Array of objects (ptr's to void)
260 void Initialize(int n) {
261 iNextPut = iNextGet = 0;
262 nMax = n;
263 InitializeCriticalSection(&CritSect);
264 hSemPut = CreateSemaphore(NULL, n, n, NULL);
265 hSemGet = CreateSemaphore(NULL, 0, n, NULL);
266 QueueObjects = new T[n];
270 public:
271 CQueue(int n) {
272 Initialize(n);
275 CQueue() {
276 Initialize(DEFAULT_QUEUESIZE);
279 ~CQueue() {
280 delete [] QueueObjects;
281 DeleteCriticalSection(&CritSect);
282 CloseHandle(hSemPut);
283 CloseHandle(hSemGet);
286 T GetQueueObject() {
287 int iSlot;
288 T Object;
289 LONG lPrevious;
291 // Wait for someone to put something on our queue, returns straight
292 // away is there is already an object on the queue.
294 WaitForSingleObject(hSemGet, INFINITE);
296 EnterCriticalSection(&CritSect);
297 iSlot = iNextGet++ % nMax;
298 Object = QueueObjects[iSlot];
299 LeaveCriticalSection(&CritSect);
301 // Release anyone waiting to put an object onto our queue as there
302 // is now space available in the queue.
304 ReleaseSemaphore(hSemPut, 1L, &lPrevious);
305 return Object;
308 void PutQueueObject(T Object) {
309 int iSlot;
310 LONG lPrevious;
312 // Wait for someone to get something from our queue, returns straight
313 // away is there is already an empty slot on the queue.
315 WaitForSingleObject(hSemPut, INFINITE);
317 EnterCriticalSection(&CritSect);
318 iSlot = iNextPut++ % nMax;
319 QueueObjects[iSlot] = Object;
320 LeaveCriticalSection(&CritSect);
322 // Release anyone waiting to remove an object from our queue as there
323 // is now an object available to be removed.
325 ReleaseSemaphore(hSemGet, 1L, &lPrevious);
329 // miscellaneous string conversion functions
330 // NOTE: as we need to use the same binaries on Win95 as on NT this code should
331 // be compiled WITHOUT unicode being defined. Otherwise we will not pick up
332 // these internal routines and the binary will not run on Win95.
334 int WINAPIV wsprintfWInternal(LPWSTR, LPCWSTR, ...);
336 LPWSTR
337 WINAPI
338 lstrcpyWInternal(
339 LPWSTR lpString1,
340 LPCWSTR lpString2
342 LPWSTR
343 WINAPI
344 lstrcpynWInternal(
345 LPWSTR lpString1,
346 LPCWSTR lpString2,
347 int iMaxLength
350 WINAPI
351 lstrcmpWInternal(
352 LPCWSTR lpString1,
353 LPCWSTR lpString2
356 WINAPI
357 lstrcmpiWInternal(
358 LPCWSTR lpString1,
359 LPCWSTR lpString2
362 WINAPI
363 lstrlenWInternal(
364 LPCWSTR lpString
367 #ifndef UNICODE
368 #define wsprintfW wsprintfWInternal
369 #define lstrcpyW lstrcpyWInternal
370 #define lstrcpynW lstrcpynWInternal
371 #define lstrcmpW lstrcmpWInternal
372 #define lstrcmpiW lstrcmpiWInternal
373 #define lstrlenW lstrlenWInternal
374 #endif
376 extern "C"
377 void * __stdcall memmoveInternal(void *, const void *, size_t);
379 inline void * __cdecl memchrInternal(const void *buf, int chr, size_t cnt)
381 #ifdef _X86_
382 void *pRet = NULL;
384 _asm {
385 cld // make sure we get the direction right
386 mov ecx, cnt // num of bytes to scan
387 mov edi, buf // pointer byte stream
388 mov eax, chr // byte to scan for
389 repne scasb // look for the byte in the byte stream
390 jnz exit_memchr // Z flag set if byte found
391 dec edi // scasb always increments edi even when it
392 // finds the required byte
393 mov pRet, edi
394 exit_memchr:
396 return pRet;
398 #else
399 while ( cnt && (*(unsigned char *)buf != (unsigned char)chr) ) {
400 buf = (unsigned char *)buf + 1;
401 cnt--;
404 return(cnt ? (void *)buf : NULL);
405 #endif
408 void WINAPI IntToWstr(int i, LPWSTR wstr);
410 #define WstrToInt(sz) _wtoi(sz)
411 #define atoiW(sz) _wtoi(sz)
412 #define atoiA(sz) atoi(sz)
414 // These are available to help managing bitmap VIDEOINFOHEADER media structures
416 extern const DWORD bits555[3];
417 extern const DWORD bits565[3];
418 extern const DWORD bits888[3];
420 // These help convert between VIDEOINFOHEADER and BITMAPINFO structures
422 STDAPI_(const GUID) GetTrueColorType(const BITMAPINFOHEADER *pbmiHeader);
423 STDAPI_(const GUID) GetBitmapSubtype(const BITMAPINFOHEADER *pbmiHeader);
424 STDAPI_(WORD) GetBitCount(const GUID *pSubtype);
426 // strmbase.lib implements this for compatibility with people who
427 // managed to link to this directly. we don't want to advertise it.
429 // STDAPI_(/* T */ CHAR *) GetSubtypeName(const GUID *pSubtype);
431 STDAPI_(CHAR *) GetSubtypeNameA(const GUID *pSubtype);
432 STDAPI_(WCHAR *) GetSubtypeNameW(const GUID *pSubtype);
434 #ifdef UNICODE
435 #define GetSubtypeName GetSubtypeNameW
436 #else
437 #define GetSubtypeName GetSubtypeNameA
438 #endif
440 STDAPI_(LONG) GetBitmapFormatSize(const BITMAPINFOHEADER *pHeader);
441 STDAPI_(DWORD) GetBitmapSize(const BITMAPINFOHEADER *pHeader);
442 STDAPI_(BOOL) ContainsPalette(const VIDEOINFOHEADER *pVideoInfo);
443 STDAPI_(const RGBQUAD *) GetBitmapPalette(const VIDEOINFOHEADER *pVideoInfo);
446 // Compares two interfaces and returns TRUE if they are on the same object
447 BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond);
449 // This is for comparing pins
450 #define EqualPins(pPin1, pPin2) IsEqualObject(pPin1, pPin2)
453 // Arithmetic helper functions
455 // Compute (a * b + rnd) / c
456 LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG rnd);
457 LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG rnd);
460 // Avoids us dyna-linking to SysAllocString to copy BSTR strings
461 STDAPI WriteBSTR(BSTR * pstrDest, LPCWSTR szSrc);
462 STDAPI FreeBSTR(BSTR* pstr);
464 // Return a wide string - allocating memory for it
465 // Returns:
466 // S_OK - no error
467 // E_POINTER - ppszReturn == NULL
468 // E_OUTOFMEMORY - can't allocate memory for returned string
469 STDAPI AMGetWideString(LPCWSTR pszString, LPWSTR *ppszReturn);
471 // Special wait for objects owning windows
472 DWORD WINAPI WaitDispatchingMessages(
473 HANDLE hObject,
474 DWORD dwWait,
475 HWND hwnd = NULL,
476 UINT uMsg = 0,
477 HANDLE hEvent = NULL);
479 // HRESULT_FROM_WIN32 converts ERROR_SUCCESS to a success code, but in
480 // our use of HRESULT_FROM_WIN32, it typically means a function failed
481 // to call SetLastError(), and we still want a failure code.
483 #define AmHresultFromWin32(x) (MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, x))
485 // call GetLastError and return an HRESULT value that will fail the
486 // SUCCEEDED() macro.
487 HRESULT AmGetLastErrorToHResult(void);
489 // duplicate of ATL's CComPtr to avoid linker conflicts.
491 IUnknown* QzAtlComPtrAssign(IUnknown** pp, IUnknown* lp);
493 template <class T>
494 class QzCComPtr
496 public:
497 typedef T _PtrClass;
498 QzCComPtr() {p=NULL;}
499 QzCComPtr(T* lp)
501 if ((p = lp) != NULL)
502 p->AddRef();
504 QzCComPtr(const QzCComPtr<T>& lp)
506 if ((p = lp.p) != NULL)
507 p->AddRef();
509 ~QzCComPtr() {if (p) p->Release();}
510 void Release() {if (p) p->Release(); p=NULL;}
511 operator T*() {return (T*)p;}
512 T& operator*() {ASSERT(p!=NULL); return *p; }
513 //The assert on operator& usually indicates a bug. If this is really
514 //what is needed, however, take the address of the p member explicitly.
515 T** operator&() { ASSERT(p==NULL); return &p; }
516 T* operator->() { ASSERT(p!=NULL); return p; }
517 T* operator=(T* lp){return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp);}
518 T* operator=(const QzCComPtr<T>& lp)
520 return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp.p);
522 #if _MSC_VER>1020
523 bool operator!(){return (p == NULL);}
524 #else
525 BOOL operator!(){return (p == NULL) ? TRUE : FALSE;}
526 #endif
527 T* p;
530 MMRESULT CompatibleTimeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent );
531 bool TimeKillSynchronousFlagAvailable( void );
533 #endif /* __WXUTIL__ */