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