BOOL pthread_win32_process_attach_np () { TCHAR QuserExDLLPathBuf[1024]; BOOL result = TRUE; const UINT QuserExDLLPathBufSize = sizeof(QuserExDLLPathBuf) / sizeof(QuserExDLLPathBuf[0]); result = ptw32_processInitialize (); #if defined(_UWIN) pthread_count++; #endif #if defined(__GNUC__) ptw32_features = 0; #else /* * This is obsolete now. */ ptw32_features = PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE; #endif /* * Load QUSEREX.DLL and try to get address of QueueUserAPCEx. * Because QUSEREX.DLL requires a driver to be installed we will * assume the DLL is in the system directory. * * This should take care of any security issues. */ #if defined(__GNUC__) || defined(PTW32_CONFIG_MSVC7) if(GetSystemDirectory(QuserExDLLPathBuf, QuserExDLLPathBufSize)) { (void) strncat(QuserExDLLPathBuf, "\\QUSEREX.DLL", QuserExDLLPathBufSize - strlen(QuserExDLLPathBuf) - 1); ptw32_h_quserex = LoadLibrary(QuserExDLLPathBuf); } #else /* strncat is secure - this is just to avoid a warning */ if(GetSystemDirectory(QuserExDLLPathBuf, QuserExDLLPathBufSize) && 0 == _tcsncat_s(QuserExDLLPathBuf, QuserExDLLPathBufSize, _T("\\QUSEREX.DLL"), 12)) { ptw32_h_quserex = LoadLibrary(QuserExDLLPathBuf); } #endif if (ptw32_h_quserex != NULL) { ptw32_register_cancellation = (DWORD (*)(PAPCFUNC, HANDLE, DWORD)) #if defined(NEED_UNICODE_CONSTS) GetProcAddress (ptw32_h_quserex, (const TCHAR *) TEXT ("QueueUserAPCEx")); #else GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx"); #endif } if (NULL == ptw32_register_cancellation) { ptw32_register_cancellation = ptw32_Registercancellation; if (ptw32_h_quserex != NULL) { (void) FreeLibrary (ptw32_h_quserex); } ptw32_h_quserex = 0; } else { /* Initialise QueueUserAPCEx */ BOOL (*queue_user_apc_ex_init) (VOID); queue_user_apc_ex_init = (BOOL (*)(VOID)) #if defined(NEED_UNICODE_CONSTS) GetProcAddress (ptw32_h_quserex, (const TCHAR *) TEXT ("QueueUserAPCEx_Init")); #else GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx_Init"); #endif if (queue_user_apc_ex_init == NULL || !queue_user_apc_ex_init ()) { ptw32_register_cancellation = ptw32_Registercancellation; (void) FreeLibrary (ptw32_h_quserex); ptw32_h_quserex = 0; } } if (ptw32_h_quserex) { ptw32_features |= PTW32_ALERTABLE_ASYNC_CANCEL; } return result; }
BOOL pthread_win32_process_attach_np () { BOOL result = TRUE; result = ptw32_processInitialize (); #ifdef _UWIN pthread_count++; #endif ptw32_features = 0; #ifndef TEST_ICE /* * Load KERNEL32 and try to get address of InterlockedCompareExchange */ ptw32_h_kernel32 = LoadLibrary (TEXT ("KERNEL32.DLL")); ptw32_interlocked_compare_exchange = (PTW32_INTERLOCKED_LONG (WINAPI *) (PTW32_INTERLOCKED_LPLONG, PTW32_INTERLOCKED_LONG, PTW32_INTERLOCKED_LONG)) #if defined(NEED_UNICODE_CONSTS) GetProcAddress (ptw32_h_kernel32, (const TCHAR *) TEXT ("InterlockedCompareExchange")); #else GetProcAddress (ptw32_h_kernel32, (LPCSTR) "InterlockedCompareExchange"); #endif if (ptw32_interlocked_compare_exchange == NULL) { ptw32_interlocked_compare_exchange = ptw32_InterlockedCompareExchange; /* * If InterlockedCompareExchange is not being used, then free * the kernel32.dll handle now, rather than leaving it until * DLL_PROCESS_DETACH. * * Note: this is not a pedantic exercise in freeing unused * resources! It is a work-around for a bug in Windows 95 * (see microsoft knowledge base article, Q187684) which * does Bad Things when FreeLibrary is called within * the DLL_PROCESS_DETACH code, in certain situations. * Since w95 just happens to be a platform which does not * provide InterlockedCompareExchange, the bug will be * effortlessly avoided. */ (void) FreeLibrary (ptw32_h_kernel32); ptw32_h_kernel32 = 0; } else { ptw32_features |= PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE; } #else /* TEST_ICE */ ptw32_interlocked_compare_exchange = ptw32_InterlockedCompareExchange; #endif /* TEST_ICE */ /* * Load QUSEREX.DLL and try to get address of QueueUserAPCEx */ ptw32_h_quserex = LoadLibrary (TEXT ("QUSEREX.DLL")); if (ptw32_h_quserex != NULL) { ptw32_register_cancelation = (DWORD (*)(PAPCFUNC, HANDLE, DWORD)) #if defined(NEED_UNICODE_CONSTS) GetProcAddress (ptw32_h_quserex, (const TCHAR *) TEXT ("QueueUserAPCEx")); #else GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx"); #endif } if (NULL == ptw32_register_cancelation) { ptw32_register_cancelation = ptw32_RegisterCancelation; if (ptw32_h_quserex != NULL) { (void) FreeLibrary (ptw32_h_quserex); } ptw32_h_quserex = 0; } else { /* Initialise QueueUserAPCEx */ BOOL (*queue_user_apc_ex_init) (VOID); queue_user_apc_ex_init = (BOOL (*)(VOID)) #if defined(NEED_UNICODE_CONSTS) GetProcAddress (ptw32_h_quserex, (const TCHAR *) TEXT ("QueueUserAPCEx_Init")); #else GetProcAddress (ptw32_h_quserex, (LPCSTR) "QueueUserAPCEx_Init"); #endif if (queue_user_apc_ex_init == NULL || !queue_user_apc_ex_init ()) { ptw32_register_cancelation = ptw32_RegisterCancelation; (void) FreeLibrary (ptw32_h_quserex); ptw32_h_quserex = 0; } } if (ptw32_h_quserex) { ptw32_features |= PTW32_ALERTABLE_ASYNC_CANCEL; } return result; }