00001
00002
00003
00004
00005
00006 #include <streams.h>
00007
00008 #ifndef COINIT_DISABLE_OLE1DDE
00009 #define COINIT_DISABLE_OLE1DDE (0x4)
00010 #endif
00011
00012 #ifndef _X86_
00013
00014 #define LLtoU64(x) (*(unsigned __int64*)(void*)(&(x)))
00015
00016 __inline
00017 ULONG
00018 WINAPI
00019 EnlargedUnsignedDivide (
00020 IN ULARGE_INTEGER Dividend,
00021 IN ULONG Divisor,
00022 IN PULONG Remainder
00023 )
00024 {
00025
00026 if (Remainder != NULL)
00027 *Remainder = (ULONG)(LLtoU64(Dividend) % Divisor);
00028 return (ULONG)(LLtoU64(Dividend) / Divisor);
00029 }
00030
00031 #else
00032 __inline
00033 ULONG
00034 WINAPI
00035 EnlargedUnsignedDivide (
00036 IN ULARGE_INTEGER Dividend,
00037 IN ULONG Divisor,
00038 IN PULONG Remainder
00039 )
00040 {
00041 ULONG ulResult;
00042 _asm {
00043 mov eax,Dividend.LowPart
00044 mov edx,Dividend.HighPart
00045 mov ecx,Remainder
00046 div Divisor
00047 or ecx,ecx
00048 jz short label
00049 mov [ecx],edx
00050 label:
00051 mov ulResult,eax
00052 }
00053 return ulResult;
00054 }
00055 #endif
00056
00057 CAMEvent::CAMEvent(BOOL fManualReset)
00058 {
00059 m_hEvent = CreateEvent(NULL, fManualReset, FALSE, NULL);
00060 ASSERT(m_hEvent);
00061 }
00062
00063 CAMEvent::~CAMEvent()
00064 {
00065 if (m_hEvent) {
00066 EXECUTE_ASSERT(CloseHandle(m_hEvent));
00067 }
00068 }
00069
00070 BOOL CAMMsgEvent::WaitMsg(DWORD dwTimeout)
00071 {
00072
00073
00074
00075 DWORD dwWait;
00076 DWORD dwStartTime;
00077
00078
00079 DWORD dwWaitTime = dwTimeout;
00080
00081
00082
00083
00084 if (dwWaitTime != INFINITE) {
00085 dwStartTime = timeGetTime();
00086 }
00087
00088 do {
00089 dwWait = MsgWaitForMultipleObjects(1,&m_hEvent,FALSE, dwWaitTime, QS_SENDMESSAGE);
00090 if (dwWait == WAIT_OBJECT_0 + 1) {
00091 MSG Message;
00092 PeekMessage(&Message,NULL,0,0,PM_NOREMOVE);
00093
00094
00095
00096
00097 if (dwWaitTime != INFINITE) {
00098
00099 DWORD dwElapsed = timeGetTime()-dwStartTime;
00100
00101 dwWaitTime =
00102 (dwElapsed >= dwTimeout)
00103 ? 0
00104 : dwTimeout-dwElapsed;
00105 }
00106 }
00107 } while (dwWait == WAIT_OBJECT_0 + 1);
00108
00109
00110
00111 return (dwWait == WAIT_OBJECT_0);
00112 }
00113
00114 CAMThread::CAMThread()
00115 : m_EventSend(TRUE)
00116 {
00117 m_hThread = NULL;
00118 }
00119
00120 CAMThread::~CAMThread() {
00121 Close();
00122 }
00123
00124 DWORD WINAPI
00125 CAMThread::InitialThreadProc(LPVOID pv)
00126 {
00127 HRESULT hrCoInit = CAMThread::CoInitializeHelper();
00128 if(FAILED(hrCoInit)) {
00129 DbgLog((LOG_ERROR, 1, TEXT("CoInitializeEx failed.")));
00130 }
00131
00132 CAMThread * pThread = (CAMThread *) pv;
00133
00134 HRESULT hr = pThread->ThreadProc();
00135
00136 if(SUCCEEDED(hrCoInit)) {
00137 CoUninitialize();
00138 }
00139
00140 return hr;
00141 }
00142
00143 BOOL
00144 CAMThread::Create()
00145 {
00146 DWORD threadid;
00147
00148 CAutoLock lock(&m_AccessLock);
00149
00150 if (ThreadExists()) {
00151 return FALSE;
00152 }
00153
00154 m_hThread = CreateThread(
00155 NULL,
00156 0,
00157 CAMThread::InitialThreadProc,
00158 this,
00159 0,
00160 &threadid);
00161
00162 if (!m_hThread) {
00163 return FALSE;
00164 }
00165
00166 return TRUE;
00167 }
00168
00169 DWORD
00170 CAMThread::CallWorker(DWORD dwParam)
00171 {
00172
00173 CAutoLock lock(&m_AccessLock);
00174
00175 if (!ThreadExists()) {
00176 return (DWORD) E_FAIL;
00177 }
00178
00179
00180 m_dwParam = dwParam;
00181
00182
00183 m_EventSend.Set();
00184
00185
00186 m_EventComplete.Wait();
00187
00188
00189 return m_dwReturnVal;
00190 }
00191
00192 DWORD
00193 CAMThread::GetRequest()
00194 {
00195 m_EventSend.Wait();
00196 return m_dwParam;
00197 }
00198
00199 BOOL
00200 CAMThread::CheckRequest(DWORD * pParam)
00201 {
00202 if (!m_EventSend.Check()) {
00203 return FALSE;
00204 } else {
00205 if (pParam) {
00206 *pParam = m_dwParam;
00207 }
00208 return TRUE;
00209 }
00210 }
00211
00212 void
00213 CAMThread::Reply(DWORD dw)
00214 {
00215 m_dwReturnVal = dw;
00216
00217
00218
00219
00220
00221
00222
00223
00224 m_EventSend.Reset();
00225
00226
00227
00228 m_EventComplete.Set();
00229 }
00230
00231 HRESULT CAMThread::CoInitializeHelper()
00232 {
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 HRESULT hr = E_FAIL;
00246 HINSTANCE hOle = GetModuleHandle(TEXT("ole32.dll"));
00247 if(hOle)
00248 {
00249 typedef HRESULT (STDAPICALLTYPE *PCoInitializeEx)(
00250 LPVOID pvReserved, DWORD dwCoInit);
00251 PCoInitializeEx pCoInitializeEx =
00252 (PCoInitializeEx)(GetProcAddress(hOle, "CoInitializeEx"));
00253 if(pCoInitializeEx)
00254 {
00255 hr = (*pCoInitializeEx)(0, COINIT_DISABLE_OLE1DDE );
00256 }
00257 }
00258 else
00259 {
00260
00261 DbgBreak("couldn't locate ole32.dll");
00262 }
00263
00264 return hr;
00265 }
00266
00267 CMsgThread::~CMsgThread()
00268 {
00269 if (m_hThread != NULL) {
00270 WaitForSingleObject(m_hThread, INFINITE);
00271 EXECUTE_ASSERT(CloseHandle(m_hThread));
00272 }
00273
00274 POSITION pos = m_ThreadQueue.GetHeadPosition();
00275 while (pos) {
00276 CMsg * pMsg = m_ThreadQueue.GetNext(pos);
00277 delete pMsg;
00278 }
00279 m_ThreadQueue.RemoveAll();
00280
00281 if (m_hSem != NULL) {
00282 EXECUTE_ASSERT(CloseHandle(m_hSem));
00283 }
00284 }
00285
00286 BOOL
00287 CMsgThread::CreateThread(
00288 )
00289 {
00290 m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL);
00291 if (m_hSem == NULL) {
00292 return FALSE;
00293 }
00294
00295 m_hThread = ::CreateThread(NULL, 0, DefaultThreadProc,
00296 (LPVOID)this, 0, &m_ThreadId);
00297 return m_hThread != NULL;
00298 }
00299
00300 DWORD WINAPI
00301 CMsgThread::DefaultThreadProc(
00302 LPVOID lpParam
00303 )
00304 {
00305 CMsgThread *lpThis = (CMsgThread *)lpParam;
00306 CMsg msg;
00307 LRESULT lResult;
00308
00309
00310 CoInitialize(NULL);
00311
00312
00313 lpThis->OnThreadInit();
00314
00315 do {
00316 lpThis->GetThreadMsg(&msg);
00317 lResult = lpThis->ThreadMessageProc(msg.uMsg,msg.dwFlags,
00318 msg.lpParam, msg.pEvent);
00319 } while (lResult == 0L);
00320
00321
00322 CoUninitialize();
00323
00324 return (DWORD)lResult;
00325 }
00326
00327 void
00328 CMsgThread::GetThreadMsg(CMsg *msg)
00329 {
00330 CMsg * pmsg = NULL;
00331
00332
00333 while (TRUE) {
00334 {
00335 CAutoLock lck(&m_Lock);
00336 pmsg = m_ThreadQueue.RemoveHead();
00337 if (pmsg == NULL) {
00338 m_lWaiting++;
00339 } else {
00340 break;
00341 }
00342 }
00343
00344 WaitForSingleObject(m_hSem, INFINITE);
00345 }
00346
00347 *msg = *pmsg;
00348
00349
00350 delete pmsg;
00351
00352 }
00353
00354 #ifndef UNICODE
00355
00356 LPWSTR
00357 WINAPI
00358 lstrcpyWInternal(
00359 LPWSTR lpString1,
00360 LPCWSTR lpString2
00361 )
00362 {
00363 LPWSTR lpReturn = lpString1;
00364 while (*lpString1++ = *lpString2++);
00365
00366 return lpReturn;
00367 }
00368
00369 LPWSTR
00370 WINAPI
00371 lstrcpynWInternal(
00372 LPWSTR lpString1,
00373 LPCWSTR lpString2,
00374 int iMaxLength
00375 )
00376 {
00377 ASSERT(iMaxLength);
00378 LPWSTR lpReturn = lpString1;
00379 if (iMaxLength) {
00380 while (--iMaxLength && (*lpString1++ = *lpString2++));
00381
00382
00383
00384
00385 if (!iMaxLength) *lpString1 = L'\0';
00386 }
00387 return lpReturn;
00388 }
00389
00390 int
00391 WINAPI
00392 lstrcmpWInternal(
00393 LPCWSTR lpString1,
00394 LPCWSTR lpString2
00395 )
00396 {
00397 do {
00398 WCHAR c1 = *lpString1;
00399 WCHAR c2 = *lpString2;
00400 if (c1 != c2)
00401 return (int) c1 - (int) c2;
00402 } while (*lpString1++ && *lpString2++);
00403 return 0;
00404 }
00405
00406 int
00407 WINAPI
00408 lstrcmpiWInternal(
00409 LPCWSTR lpString1,
00410 LPCWSTR lpString2
00411 )
00412 {
00413 do {
00414 WCHAR c1 = *lpString1;
00415 WCHAR c2 = *lpString2;
00416 if (c1 >= L'A' && c1 <= L'Z')
00417 c1 -= (WCHAR) (L'A' - L'a');
00418 if (c2 >= L'A' && c2 <= L'Z')
00419 c2 -= (WCHAR) (L'A' - L'a');
00420
00421 if (c1 != c2)
00422 return (int) c1 - (int) c2;
00423 } while (*lpString1++ && *lpString2++);
00424
00425 return 0;
00426 }
00427
00428 int
00429 WINAPI
00430 lstrlenWInternal(
00431 LPCWSTR lpString
00432 )
00433 {
00434 int i = -1;
00435 while (*(lpString+(++i)))
00436 ;
00437 return i;
00438 }
00439
00440 int WINAPIV wsprintfWInternal(LPWSTR wszOut, LPCWSTR pszFmt, ...)
00441 {
00442 char fmt[256];
00443 char ach[256];
00444 int i;
00445
00446 va_list va;
00447 va_start(va, pszFmt);
00448 WideCharToMultiByte(GetACP(), 0, pszFmt, -1, fmt, 256, NULL, NULL);
00449 i = wvsprintfA(ach, fmt, va);
00450 va_end(va);
00451
00452 MultiByteToWideChar(CP_ACP, 0, ach, -1, wszOut, i+1);
00453
00454 return i;
00455 }
00456 #else
00457
00458 LPWSTR WINAPI lstrcpyWInternal(
00459 LPWSTR lpString1,
00460 LPCWSTR lpString2
00461 )
00462 {
00463 return lstrcpyW(lpString1, lpString2);
00464 }
00465
00466 LPWSTR WINAPI lstrcpynWInternal(
00467 LPWSTR lpString1,
00468 LPCWSTR lpString2,
00469 int iMaxLength
00470 )
00471 {
00472 return lstrcpynW(lpString1, lpString2, iMaxLength);
00473 }
00474
00475 int WINAPI lstrcmpWInternal(
00476 LPCWSTR lpString1,
00477 LPCWSTR lpString2
00478 )
00479 {
00480 return lstrcmpW(lpString1, lpString2);
00481 }
00482
00483 int WINAPI lstrcmpiWInternal(
00484 LPCWSTR lpString1,
00485 LPCWSTR lpString2
00486 )
00487 {
00488 return lstrcmpiW(lpString1, lpString2);
00489 }
00490
00491 int WINAPI lstrlenWInternal(
00492 LPCWSTR lpString
00493 )
00494 {
00495 return lstrlenW(lpString);
00496 }
00497
00498 int WINAPIV wsprintfWInternal(
00499 LPWSTR wszOut, LPCWSTR pszFmt, ...)
00500 {
00501 va_list va;
00502 va_start(va, pszFmt);
00503 int i = wvsprintfW(wszOut, pszFmt, va);
00504 va_end(va);
00505 return i;
00506 }
00507 #endif
00508
00509 void WINAPI IntToWstr(int i, LPWSTR wstr)
00510 {
00511 #ifdef UNICODE
00512 wsprintf(wstr, L"%d", i);
00513 #else
00514 TCHAR temp[32];
00515 wsprintf(temp, "%d", i);
00516 MultiByteToWideChar(CP_ACP, 0, temp, -1, wstr, 32);
00517 #endif
00518 }
00519
00520 #if 0
00521 void * memchrInternal(const void *pv, int c, size_t sz)
00522 {
00523 BYTE *pb = (BYTE *) pv;
00524 while (sz--) {
00525 if (*pb == c)
00526 return (void *) pb;
00527 pb++;
00528 }
00529 return NULL;
00530 }
00531 #endif
00532
00533 #define MEMORY_ALIGNMENT 4
00534 #define MEMORY_ALIGNMENT_LOG2 2
00535 #define MEMORY_ALIGNMENT_MASK MEMORY_ALIGNMENT - 1
00536
00537 void * __stdcall memmoveInternal(void * dst, const void * src, size_t count)
00538 {
00539 void * ret = dst;
00540
00541 #ifdef _X86_
00542 if (dst <= src || (char *)dst >= ((char *)src + count)) {
00543
00544
00545 _asm {
00546 mov esi,src
00547 mov edi,dst
00548 mov ecx,count
00549 cld
00550 mov edx,ecx
00551 and edx,MEMORY_ALIGNMENT_MASK
00552 shr ecx,MEMORY_ALIGNMENT_LOG2
00553 rep movsd
00554 or ecx,edx
00555 jz memmove_done
00556 rep movsb
00557 memmove_done:
00558 }
00559 }
00560 else {
00561
00562
00563 _asm {
00564 mov esi,src
00565 mov edi,dst
00566 mov ecx,count
00567 std
00568 add esi,ecx
00569 add edi,ecx
00570 dec esi
00571 dec edi
00572 rep movsb
00573 cld
00574 }
00575 }
00576 #else
00577 MoveMemory(dst, src, count);
00578 #endif
00579
00580 return ret;
00581 }
00582
00583 #ifdef _M_ALPHA
00584
00585 #undef UInt32x32To64
00586 #define UInt32x32To64(a, b) (((ULONGLONG)((ULONG)(a)) & 0xffffffff) * ((ULONGLONG)((ULONG)(b)) & 0xffffffff))
00587 #endif
00588
00589 LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG d)
00590 {
00591
00592 ULARGE_INTEGER ua, ub;
00593 DWORDLONG uc;
00594
00595 ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a);
00596 ub.QuadPart = (DWORDLONG)(b >= 0 ? b : -b);
00597 uc = (DWORDLONG)(c >= 0 ? c : -c);
00598 BOOL bSign = (a < 0) ^ (b < 0);
00599
00600
00601 ULARGE_INTEGER p[2];
00602 p[0].QuadPart = UInt32x32To64(ua.LowPart, ub.LowPart);
00603
00604
00605
00606 ULARGE_INTEGER x;
00607 x.QuadPart = UInt32x32To64(ua.LowPart, ub.HighPart) +
00608 UInt32x32To64(ua.HighPart, ub.LowPart) +
00609 p[0].HighPart;
00610 p[0].HighPart = x.LowPart;
00611 p[1].QuadPart = UInt32x32To64(ua.HighPart, ub.HighPart) + x.HighPart;
00612
00613 if (d != 0) {
00614 ULARGE_INTEGER ud[2];
00615 if (bSign) {
00616 ud[0].QuadPart = (DWORDLONG)(-d);
00617 if (d > 0) {
00618
00619 ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1;
00620 } else {
00621 ud[1].QuadPart = (DWORDLONG)0;
00622 }
00623 } else {
00624 ud[0].QuadPart = (DWORDLONG)d;
00625 if (d < 0) {
00626 ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1;
00627 } else {
00628 ud[1].QuadPart = (DWORDLONG)0;
00629 }
00630 }
00631
00632 ULARGE_INTEGER uliTotal;
00633
00634
00635 uliTotal.QuadPart = (DWORDLONG)ud[0].LowPart + p[0].LowPart;
00636 p[0].LowPart = uliTotal.LowPart;
00637
00638
00639 uliTotal.LowPart = uliTotal.HighPart;
00640 uliTotal.HighPart = 0;
00641
00642
00643 uliTotal.QuadPart += (DWORDLONG)ud[0].HighPart + p[0].HighPart;
00644 p[0].HighPart = uliTotal.LowPart;
00645
00646
00647 uliTotal.LowPart = uliTotal.HighPart;
00648 uliTotal.HighPart = 0;
00649
00650
00651 p[1].QuadPart += ud[1].QuadPart + uliTotal.QuadPart;
00652
00653
00654 if ((LONG)p[1].HighPart < 0) {
00655 bSign = !bSign;
00656
00657
00658 p[0].QuadPart = ~p[0].QuadPart;
00659 p[1].QuadPart = ~p[1].QuadPart;
00660 p[0].QuadPart += 1;
00661 p[1].QuadPart += (p[0].QuadPart == 0);
00662 }
00663 }
00664
00665
00666 if (c < 0) {
00667 bSign = !bSign;
00668 }
00669
00670
00671 if (uc <= p[1].QuadPart) {
00672 return bSign ? (LONGLONG)0x8000000000000000 :
00673 (LONGLONG)0x7FFFFFFFFFFFFFFF;
00674 }
00675
00676 DWORDLONG ullResult;
00677
00678
00679
00680 if (p[1].QuadPart == 0) {
00681 ullResult = p[0].QuadPart / uc;
00682 return bSign ? -(LONGLONG)ullResult : (LONGLONG)ullResult;
00683 }
00684
00685
00686 ULARGE_INTEGER ulic;
00687 ulic.QuadPart = uc;
00688 if (ulic.HighPart == 0) {
00689 ULARGE_INTEGER uliDividend;
00690 ULARGE_INTEGER uliResult;
00691 DWORD dwDivisor = (DWORD)uc;
00692
00693 uliDividend.HighPart = p[1].LowPart;
00694 uliDividend.LowPart = p[0].HighPart;
00695 #ifndef USE_LARGEINT
00696 uliResult.HighPart = (DWORD)(uliDividend.QuadPart / dwDivisor);
00697 p[0].HighPart = (DWORD)(uliDividend.QuadPart % dwDivisor);
00698 uliResult.LowPart = 0;
00699 uliResult.QuadPart = p[0].QuadPart / dwDivisor + uliResult.QuadPart;
00700 #else
00701
00702 if (uliDividend.QuadPart >= (DWORDLONG)dwDivisor) {
00703 uliResult.HighPart = EnlargedUnsignedDivide(
00704 uliDividend,
00705 dwDivisor,
00706 &p[0].HighPart);
00707 } else {
00708 uliResult.HighPart = 0;
00709 }
00710 uliResult.LowPart = EnlargedUnsignedDivide(
00711 p[0],
00712 dwDivisor,
00713 NULL);
00714 #endif
00715 return bSign ? -(LONGLONG)uliResult.QuadPart :
00716 (LONGLONG)uliResult.QuadPart;
00717 }
00718
00719 ullResult = 0;
00720
00721
00722 for (int i = 0; i < 64; i++) {
00723 ullResult <<= 1;
00724
00725
00726 p[1].QuadPart <<= 1;
00727 if ((p[0].HighPart & 0x80000000) != 0) {
00728 p[1].LowPart++;
00729 }
00730 p[0].QuadPart <<= 1;
00731
00732
00733 if (uc <= p[1].QuadPart) {
00734 p[1].QuadPart -= uc;
00735 ullResult += 1;
00736 }
00737 }
00738
00739 return bSign ? - (LONGLONG)ullResult : (LONGLONG)ullResult;
00740 }
00741
00742 LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG d)
00743 {
00744 ULARGE_INTEGER ua;
00745 DWORD ub;
00746 DWORD uc;
00747
00748
00749 ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a);
00750 ub = (DWORD)(b >= 0 ? b : -b);
00751 uc = (DWORD)(c >= 0 ? c : -c);
00752 BOOL bSign = (a < 0) ^ (b < 0);
00753
00754
00755 ULARGE_INTEGER p0;
00756 DWORD p1;
00757 p0.QuadPart = UInt32x32To64(ua.LowPart, ub);
00758
00759 if (ua.HighPart != 0) {
00760 ULARGE_INTEGER x;
00761 x.QuadPart = UInt32x32To64(ua.HighPart, ub) + p0.HighPart;
00762 p0.HighPart = x.LowPart;
00763 p1 = x.HighPart;
00764 } else {
00765 p1 = 0;
00766 }
00767
00768 if (d != 0) {
00769 ULARGE_INTEGER ud0;
00770 DWORD ud1;
00771
00772 if (bSign) {
00773
00774
00775
00776
00777 ud0.QuadPart = (DWORDLONG)(-(LONGLONG)d);
00778 if (d > 0) {
00779
00780 ud1 = (DWORD)-1;
00781 } else {
00782 ud1 = (DWORD)0;
00783 }
00784 } else {
00785 ud0.QuadPart = (DWORDLONG)d;
00786 if (d < 0) {
00787 ud1 = (DWORD)-1;
00788 } else {
00789 ud1 = (DWORD)0;
00790 }
00791 }
00792
00793 ULARGE_INTEGER uliTotal;
00794
00795
00796 uliTotal.QuadPart = (DWORDLONG)ud0.LowPart + p0.LowPart;
00797 p0.LowPart = uliTotal.LowPart;
00798
00799
00800 uliTotal.LowPart = uliTotal.HighPart;
00801 uliTotal.HighPart = 0;
00802
00803
00804 uliTotal.QuadPart += (DWORDLONG)ud0.HighPart + p0.HighPart;
00805 p0.HighPart = uliTotal.LowPart;
00806
00807
00808 p1 += ud1 + uliTotal.HighPart;
00809
00810
00811 if ((LONG)p1 < 0) {
00812 bSign = !bSign;
00813
00814
00815 p0.QuadPart = ~p0.QuadPart;
00816 p1 = ~p1;
00817 p0.QuadPart += 1;
00818 p1 += (p0.QuadPart == 0);
00819 }
00820 }
00821
00822
00823 if (c < 0) {
00824 bSign = !bSign;
00825 }
00826
00827
00828 if (uc <= p1) {
00829 return bSign ? (LONGLONG)0x8000000000000000 :
00830 (LONGLONG)0x7FFFFFFFFFFFFFFF;
00831 }
00832
00833
00834
00835
00836 ULARGE_INTEGER uliDividend;
00837 ULARGE_INTEGER uliResult;
00838 DWORD dwDivisor = uc;
00839 uliDividend.HighPart = p1;
00840 uliDividend.LowPart = p0.HighPart;
00841
00842 if (uliDividend.QuadPart >= (DWORDLONG)dwDivisor) {
00843 uliResult.HighPart = EnlargedUnsignedDivide(
00844 uliDividend,
00845 dwDivisor,
00846 &p0.HighPart);
00847 } else {
00848 uliResult.HighPart = 0;
00849 }
00850 uliResult.LowPart = EnlargedUnsignedDivide(
00851 p0,
00852 dwDivisor,
00853 NULL);
00854 return bSign ? -(LONGLONG)uliResult.QuadPart :
00855 (LONGLONG)uliResult.QuadPart;
00856 }
00857
00858 #ifdef DEBUG
00859
00860 CCritSec::CCritSec()
00861 {
00862 InitializeCriticalSection(&m_CritSec);
00863 m_currentOwner = m_lockCount = 0;
00864 m_fTrace = FALSE;
00865 }
00866
00867 CCritSec::~CCritSec()
00868 {
00869 DeleteCriticalSection(&m_CritSec);
00870 }
00871
00872 void CCritSec::Lock()
00873 {
00874 UINT tracelevel=3;
00875 DWORD us = GetCurrentThreadId();
00876 DWORD currentOwner = m_currentOwner;
00877 if (currentOwner && (currentOwner != us)) {
00878
00879 if (m_fTrace) {
00880 DbgLog((LOG_LOCKING, 2, TEXT("Thread %d about to wait for lock %x owned by %d"),
00881 GetCurrentThreadId(), &m_CritSec, currentOwner));
00882 tracelevel=2;
00883
00884
00885
00886 }
00887 }
00888 EnterCriticalSection(&m_CritSec);
00889 if (0 == m_lockCount++) {
00890
00891 m_currentOwner = us;
00892
00893 if (m_fTrace) {
00894 DbgLog((LOG_LOCKING, tracelevel, TEXT("Thread %d now owns lock %x"), m_currentOwner, &m_CritSec));
00895 }
00896 }
00897 }
00898
00899 void CCritSec::Unlock() {
00900 if (0 == --m_lockCount) {
00901
00902 if (m_fTrace) {
00903 DbgLog((LOG_LOCKING, 3, TEXT("Thread %d releasing lock %x"), m_currentOwner, &m_CritSec));
00904 }
00905
00906 m_currentOwner = 0;
00907 }
00908 LeaveCriticalSection(&m_CritSec);
00909 }
00910
00911 void WINAPI DbgLockTrace(CCritSec * pcCrit, BOOL fTrace)
00912 {
00913 pcCrit->m_fTrace = fTrace;
00914 }
00915
00916 BOOL WINAPI CritCheckIn(CCritSec * pcCrit)
00917 {
00918 return (GetCurrentThreadId() == pcCrit->m_currentOwner);
00919 }
00920
00921 BOOL WINAPI CritCheckIn(const CCritSec * pcCrit)
00922 {
00923 return (GetCurrentThreadId() == pcCrit->m_currentOwner);
00924 }
00925
00926 BOOL WINAPI CritCheckOut(CCritSec * pcCrit)
00927 {
00928 return (GetCurrentThreadId() != pcCrit->m_currentOwner);
00929 }
00930
00931 BOOL WINAPI CritCheckOut(const CCritSec * pcCrit)
00932 {
00933 return (GetCurrentThreadId() != pcCrit->m_currentOwner);
00934 }
00935 #endif
00936
00937 STDAPI WriteBSTR(BSTR *pstrDest, LPCWSTR szSrc)
00938 {
00939 *pstrDest = SysAllocString( szSrc );
00940 if( !(*pstrDest) ) return E_OUTOFMEMORY;
00941 return NOERROR;
00942 }
00943
00944 STDAPI FreeBSTR(BSTR* pstr)
00945 {
00946 if( *pstr == NULL ) return S_FALSE;
00947 SysFreeString( *pstr );
00948 return NOERROR;
00949 }
00950
00951 STDAPI AMGetWideString(LPCWSTR psz, LPWSTR *ppszReturn)
00952 {
00953 CheckPointer(ppszReturn, E_POINTER);
00954 ValidateReadWritePtr(ppszReturn, sizeof(LPWSTR));
00955 DWORD nameLen = sizeof(WCHAR) * (lstrlenW(psz)+1);
00956 *ppszReturn = (LPWSTR)CoTaskMemAlloc(nameLen);
00957 if (*ppszReturn == NULL) {
00958 return E_OUTOFMEMORY;
00959 }
00960 CopyMemory(*ppszReturn, psz, nameLen);
00961 return NOERROR;
00962 }
00963
00964 DWORD WINAPI WaitDispatchingMessages(
00965 HANDLE hObject,
00966 DWORD dwWait,
00967 HWND hwnd,
00968 UINT uMsg,
00969 HANDLE hEvent)
00970 {
00971 BOOL bPeeked = FALSE;
00972 DWORD dwResult;
00973 DWORD dwStart;
00974 DWORD dwThreadPriority;
00975
00976 static UINT uMsgId = 0;
00977
00978 HANDLE hObjects[2] = { hObject, hEvent };
00979 if (dwWait != INFINITE && dwWait != 0) {
00980 dwStart = GetTickCount();
00981 }
00982 for (; ; ) {
00983 DWORD nCount = NULL != hEvent ? 2 : 1;
00984
00985
00986
00987 dwResult = WaitForMultipleObjects(nCount, hObjects, FALSE, 0);
00988 if (dwResult < WAIT_OBJECT_0 + nCount) {
00989 return dwResult;
00990 }
00991
00992 DWORD dwTimeOut = dwWait;
00993 if (dwTimeOut > 10) {
00994 dwTimeOut = 10;
00995 }
00996 dwResult = MsgWaitForMultipleObjects(
00997 nCount,
00998 hObjects,
00999 FALSE,
01000 dwTimeOut,
01001 hwnd == NULL ? QS_SENDMESSAGE :
01002 QS_SENDMESSAGE + QS_POSTMESSAGE);
01003 if (dwResult == WAIT_OBJECT_0 + nCount ||
01004 dwResult == WAIT_TIMEOUT && dwTimeOut != dwWait) {
01005 MSG msg;
01006 if (hwnd != NULL) {
01007 while (PeekMessage(&msg, hwnd, uMsg, uMsg, PM_REMOVE)) {
01008 DispatchMessage(&msg);
01009 }
01010 }
01011
01012
01013 PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
01014
01015 if (dwWait != INFINITE && dwWait != 0) {
01016 DWORD dwNow = GetTickCount();
01017
01018
01019 DWORD dwDiff = dwNow - dwStart;
01020 if (dwDiff > dwWait) {
01021 dwWait = 0;
01022 } else {
01023 dwWait -= dwDiff;
01024 }
01025 dwStart = dwNow;
01026 }
01027 if (!bPeeked) {
01028
01029
01030 dwThreadPriority = GetThreadPriority(GetCurrentThread());
01031 if (dwThreadPriority < THREAD_PRIORITY_HIGHEST) {
01032 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
01033 }
01034 bPeeked = TRUE;
01035 }
01036 } else {
01037 break;
01038 }
01039 }
01040 if (bPeeked) {
01041 SetThreadPriority(GetCurrentThread(), dwThreadPriority);
01042 if (HIWORD(GetQueueStatus(QS_POSTMESSAGE)) & QS_POSTMESSAGE) {
01043 if (uMsgId == 0) {
01044 uMsgId = RegisterWindowMessage(TEXT("AMUnblock"));
01045 }
01046 if (uMsgId != 0) {
01047 MSG msg;
01048
01049 while (PeekMessage(&msg, (HWND)-1, uMsgId, uMsgId, PM_REMOVE)) {
01050 }
01051 }
01052 PostThreadMessage(GetCurrentThreadId(), uMsgId, 0, 0);
01053 }
01054 }
01055 return dwResult;
01056 }
01057
01058 HRESULT AmGetLastErrorToHResult()
01059 {
01060 DWORD dwLastError = GetLastError();
01061 if(dwLastError != 0)
01062 {
01063 return HRESULT_FROM_WIN32(dwLastError);
01064 }
01065 else
01066 {
01067 return E_FAIL;
01068 }
01069 }
01070
01071 IUnknown* QzAtlComPtrAssign(IUnknown** pp, IUnknown* lp)
01072 {
01073 if (lp != NULL)
01074 lp->AddRef();
01075 if (*pp)
01076 (*pp)->Release();
01077 *pp = lp;
01078 return lp;
01079 }
01080