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.

502 lines
14 KiB

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