Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

533 lines
15 KiB

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