NTSTATUS NTAPI ConMgrSetCurrentChannel(IN PSAC_CHANNEL Channel) { NTSTATUS Status; BOOLEAN HasRedrawEvent; /* Make sure the lock is held */ SacAssertMutexLockHeld(); /* Check if we have a redraw event */ Status = ChannelHasRedrawEvent(CurrentChannel, &HasRedrawEvent); if (!NT_SUCCESS(Status)) return Status; /* Clear it */ if (HasRedrawEvent) ChannelClearRedrawEvent(CurrentChannel); /* Disable writes on the current channel */ _InterlockedExchange(&CurrentChannel->WriteEnabled, 0); /* Release the current channel */ Status = ChanMgrReleaseChannel(CurrentChannel); if (!NT_SUCCESS(Status)) return Status; /* Set the new channel and also disable writes on it */ CurrentChannel = Channel; _InterlockedExchange(&Channel->WriteEnabled, 0); return STATUS_SUCCESS; }
// Callback proc for MM timers // N.B. This routine is called from a separate thread (in Win32), rather than in // interrupt time, but careful coding is still important. The recommended // list of routines is limited to: // EnterCriticalSection ReleaseSemaphore // LeaveCriticalSection SetEvent // timeGetSystemTime timeGetTime // OutputDebugString timeKillEvent // PostMessage timeSetEvent // // "If a Win32 low-level audio callback [we are using mm timers here] shares data // with other code, a Critical Section or similar mutual exclusion mechanism should // be used to protect the integrity of the data". // Access to the asynchronous semaphore array is protected by a critical section // in the asynchronousSignal and CheckProcessSwitch routines. We don't really care // that much about the timerID void CALLBACK Interpreter::TimeProc(UINT uID, UINT /*uMsg*/, DWORD /*dwUser*/, DWORD /*dw1*/, DWORD /*dw2*/) { // Avoid firing a timer which has been cancelled (or is about to be cancelled!) // We use an InterlockedExchange() to set the value to 0 so that the main thread // can recognise that the timer has fired without race conditions if (_InterlockedExchange(reinterpret_cast<SHAREDLONG*>(&timerID), 0) != 0) { // If not previously killed (which is very unlikely except in certain exceptional // circumstances where the timer is killed at the exact moment it is about to fire) // then go ahead and signal the semaphore and the wakeup event // We mustn't access Pointers from an async thread when object memory is compacting // as the Pointer will be wrong GrabAsyncProtect(); SemaphoreOTE* timerSemaphore = Pointers.TimingSemaphore; HARDASSERT(!ObjectMemoryIsIntegerObject(timerSemaphore)); HARDASSERT(!timerSemaphore->isFree()); HARDASSERT(timerSemaphore->m_oteClass == Pointers.ClassSemaphore); // Asynchronously signal the required semaphore asynchronously, which will be detected // in sync. with the dispatching of byte codes, and properly signalled asynchronousSignalNoProtect(timerSemaphore); // Signal the timing Event, in case the idle process has put the VM to sleep SetWakeupEvent(); RelinquishAsyncProtect(); } else // An old timer (which should have been cancelled) has fired trace("Old timer %d fired, current %d\n", uID, timerID); }
NTSTATUS NTAPI ConMgrDisplayCurrentChannel(VOID) { NTSTATUS Status; BOOLEAN HasRedraw; /* Make sure the lock is held */ SacAssertMutexLockHeld(); /* Check if we can redraw */ Status = ChannelHasRedrawEvent(CurrentChannel, &HasRedraw); if (NT_SUCCESS(Status)) { /* Enable writes */ _InterlockedExchange(&CurrentChannel->WriteEnabled, 1); if (HasRedraw) { /* If we can redraw, set the event */ ChannelSetRedrawEvent(CurrentChannel); } /* Flush the output */ Status = ChannelOFlush(CurrentChannel); } /* All done, return the status */ return Status; }
/* _Atomic_exchange_4 */ static _Uint4_t _Exchange_seq_cst_4( volatile _Uint4_t *_Tgt, _Uint4_t _Value) { /* exchange _Value and *_Tgt atomically with sequentially consistent memory order */ _Value = _InterlockedExchange((volatile long *)_Tgt, _Value); return (_Value); }
//178 int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status) { sc_spu.Warning("sys_spu_thread_group_join(id=0x%x, cause_addr=0x%x, status_addr=0x%x)", id, cause.GetAddr(), status.GetAddr()); SpuGroupInfo* group_info; if(!Emu.GetIdManager().GetIDData(id, group_info)) { return CELL_ESRCH; } if (_InterlockedCompareExchange(&group_info->lock, 1, 0)) //get lock { return CELL_EBUSY; } cause = SYS_SPU_THREAD_GROUP_JOIN_ALL_THREADS_EXIT; status = 0; //unspecified because of ALL_THREADS_EXIT for(int i=0; i<g_spu_group_thr_count; i++) { if(group_info->threads[i]) { while (!group_info->threads[i]->IsStopped()) Sleep(1); } } _InterlockedExchange(&group_info->lock, 0); //release lock return CELL_OK; }
int pthread_cond_broadcast(pthread_cond_t *cond) { _InterlockedExchange(&(*cond)->Broadcast, 1); SetEvent((*cond)->EV); return 0; }
ULONG ProcessDotNetTrace( _In_ PASMPAGE_QUERY_CONTEXT Context ) { ULONG result; TRACEHANDLE traceHandle; EVENT_TRACE_LOGFILE logFile; memset(&logFile, 0, sizeof(EVENT_TRACE_LOGFILE)); logFile.LoggerName = DotNetLoggerName.Buffer; logFile.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD; logFile.BufferCallback = DotNetBufferCallback; logFile.EventRecordCallback = DotNetEventCallback; logFile.Context = Context; traceHandle = OpenTrace(&logFile); if (traceHandle == INVALID_PROCESSTRACE_HANDLE) return GetLastError(); Context->TraceHandleActive = 1; Context->TraceHandle = traceHandle; result = ProcessTrace(&traceHandle, 1, NULL, NULL); if (_InterlockedExchange(&Context->TraceHandleActive, 0) == 1) { CloseTrace(traceHandle); } return result; }
/* * @implemented */ LONG WINAPI InterlockedExchange(IN OUT LONG volatile *Target, IN LONG Value) { return _InterlockedExchange(Target, Value); }
int TransportSocket::close() { int s = _InterlockedExchange((long*)&sock6,0); if (s == 0) { s = _InterlockedExchange((long*)&sock,0); if (s == 0) return 0; } else closesocket(sock); shutdown(s, SD_BOTH); //Wait for gracefully shutdown. In normal network condition TCP should shutdown in 1 sec. //As only (20(IP) + 20(TCP)) * 2(FIN&ACK, ACK) = 80 bytes needed to be transmitted. LARGE_INTEGER sleep_time = {-10000000, -1}; NtDelayExecution(0,&sleep_time); return closesocket(s); }
NTSTATUS NTAPI VTUTF8ChannelOWrite(IN PSAC_CHANNEL Channel, IN PCHAR String, IN ULONG Length) { NTSTATUS Status; CHECK_PARAMETER1(Channel); CHECK_PARAMETER2(String); /* Call the lower level function */ Status = VTUTF8ChannelOWrite2(Channel, (PWCHAR)String, Length / sizeof(WCHAR)); if (NT_SUCCESS(Status)) { /* Is the channel enabled for output? */ if ((ConMgrIsWriteEnabled(Channel)) && (Channel->WriteEnabled)) { /* Go ahead and output it */ Status = VTUTF8ChannelOEcho(Channel, String, Length); } else { /* Otherwise, just remember that we have new data */ _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 1); } } /* We're done */ return Status; }
NTKERNELAPI LONG FASTCALL InterlockedExchange( LONG volatile *Target, LONG Value) { return _InterlockedExchange(Target, Value); }
LONG NTAPI Exi386InterlockedExchangeUlong( PLONG Target, LONG Exchange) { return _InterlockedExchange(Target, Exchange); }
ULONG FASTCALL Exfi386InterlockedExchangeUlong( IN OUT PULONG Target, IN ULONG Exchange) { return _InterlockedExchange((PLONG)Target, Exchange); }
CProcessesHandles::CEntry::CEntry(__in DWORD _dwPid, __in HANDLE _h, __in LONG _nPlatform) : TNktLnkLstNode<CEntry>(), CNktNtHeapBaseObj() { dwPid = _dwPid; h = _h; nPlatform = _nPlatform; _InterlockedExchange(&nRefCount, 1); return; }
ULONG NTAPI ExInterlockedExchangeUlong( IN PULONG Target, IN ULONG Value, IN PKSPIN_LOCK Lock) { return (ULONG)_InterlockedExchange((PLONG)Target, (LONG)Value); }
LONG WINAPI redirect_InterlockedExchange( __inout __drv_interlocked LONG volatile *Target, __in LONG Value ) { return _InterlockedExchange(Target, Value); }
NTSTATUS NTAPI RawChannelORead(IN PSAC_CHANNEL Channel, IN PCHAR Buffer, IN ULONG BufferSize, OUT PULONG ByteCount) { NTSTATUS Status; ULONG NextIndex; CHECK_PARAMETER1(Channel); CHECK_PARAMETER2(Buffer); CHECK_PARAMETER3(BufferSize > 0); CHECK_PARAMETER4(ByteCount); *ByteCount = 0; if (ChannelHasNewOBufferData(Channel)) { Status = STATUS_SUCCESS; while (TRUE) { Buffer[(*ByteCount)++] = Channel->OBuffer[Channel->OBufferFirstGoodIndex]; NextIndex = (Channel->OBufferFirstGoodIndex + 1) & (SAC_OBUFFER_SIZE - 1); Channel->OBufferFirstGoodIndex = NextIndex; if (NextIndex == Channel->OBufferIndex) { _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 0); break; } ASSERT(*ByteCount > 0); if (*ByteCount >= BufferSize) break; } } else { Status = STATUS_NO_DATA_DETECTED; } if (Channel->OBufferFirstGoodIndex == Channel->OBufferIndex) { ASSERT(ChannelHasNewOBufferData(Channel) == FALSE); } if (ChannelHasNewOBufferData(Channel) == FALSE) { ASSERT(Channel->OBufferFirstGoodIndex == Channel->OBufferIndex); } return Status; }
bool try_lock() { #if BOOST_WINDOWS long r = _InterlockedExchange(&v_, 1); _ReadWriteBarrier(); return r == 0; #else int r = __sync_lock_test_and_set(&v_, 1); return r == 0; #endif }
int TransportSocket::socket() { int s = _InterlockedExchange((long*)&sock,1); if (s == 0) { s = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if (s != INVALID_SOCKET) sock = s; return s; } else sock = 0; return -1; }
LONG CProcessesHandles::CEntry::GetCurrPlatform() { LONG volatile nPlatform = (LONG)-1; if (nPlatform == (LONG)-1) { LONG _plat = NktHookLibHelpers::GetProcessPlatform(NKTHOOKLIB_CurrentProcess); if (NT_SUCCESS(_plat)) _InterlockedExchange(&nPlatform, _plat); } return nPlatform; }
/* #define try_lck_P(lk) (!((lk)->FLG--)) */ int try_lck_P(LCK *lk) { #ifdef _MSC_VER return 0==_InterlockedExchange(&lk->FLG, 1); #else # ifdef unix return !pthread_mutex_trylock(&lk->FLG); # else return !(lk->FLG--); # endif #endif }
static VOID InitializeInternals() { //because we are using NKTHOOKLIB_CurrentProcess and ScanMappedImages to FALSE, we are avoiding the recursion LPVOID _hNtDll = ::NktHookLib::GetRemoteModuleBaseAddress(NKTHOOKLIB_CurrentProcess, L"ntdll.dll", FALSE); if (_hNtDll != NULL) { #define NKT_PARSE_NTAPI_NTSTATUS(name, _notused, _notused2) \ lpfn_##name __fn_##name = (lpfn_##name)::NktHookLib::GetRemoteProcedureAddress(NKTHOOKLIB_CurrentProcess, \ _hNtDll, # name); #define NKT_PARSE_NTAPI_VOID NKT_PARSE_NTAPI_NTSTATUS #define NKT_PARSE_NTAPI_PVOID NKT_PARSE_NTAPI_NTSTATUS #define NKT_PARSE_NTAPI_BOOLEAN NKT_PARSE_NTAPI_NTSTATUS #define NKT_PARSE_NTAPI_ULONG NKT_PARSE_NTAPI_NTSTATUS #include "NtApiDeclarations.h" #undef NKT_PARSE_NTAPI_NTSTATUS #undef NKT_PARSE_NTAPI_VOID #undef NKT_PARSE_NTAPI_PVOID #undef NKT_PARSE_NTAPI_BOOLEAN #undef NKT_PARSE_NTAPI_ULONG #if defined(_M_IX86) #define NKT_PARSE_NTAPI_NTSTATUS(name, _notused, _notused2) \ _InterlockedExchange((long volatile*)&(NktHookLib_fn_##name), (long)(__fn_##name)); #elif defined(_M_X64) #define NKT_PARSE_NTAPI_NTSTATUS(name, _notused, _notused2) \ _InterlockedExchangePointer((void* volatile*)&(NktHookLib_fn_##name), (__fn_##name)); #endif #define NKT_PARSE_NTAPI_VOID NKT_PARSE_NTAPI_NTSTATUS #define NKT_PARSE_NTAPI_PVOID NKT_PARSE_NTAPI_NTSTATUS #define NKT_PARSE_NTAPI_BOOLEAN NKT_PARSE_NTAPI_NTSTATUS #define NKT_PARSE_NTAPI_ULONG NKT_PARSE_NTAPI_NTSTATUS #include "NtApiDeclarations.h" #undef NKT_PARSE_NTAPI_NTSTATUS #undef NKT_PARSE_NTAPI_VOID #undef NKT_PARSE_NTAPI_PVOID #undef NKT_PARSE_NTAPI_BOOLEAN #undef NKT_PARSE_NTAPI_ULONG //---- NktHookLib_fn_vsnprintf = ::NktHookLib::GetRemoteProcedureAddress(NKTHOOKLIB_CurrentProcess, _hNtDll, "_vsnprintf"); NktHookLib_fn_vsnwprintf = ::NktHookLib::GetRemoteProcedureAddress(NKTHOOKLIB_CurrentProcess, _hNtDll, "_vsnwprintf"); NktHookLib_fn_DbgPrint = ::NktHookLib::GetRemoteProcedureAddress(NKTHOOKLIB_CurrentProcess, _hNtDll, "DbgPrint"); } #if defined(_M_IX86) _InterlockedExchange((long volatile*)&hNtDll, (long)_hNtDll); #elif defined(_M_X64) _InterlockedExchangePointer((volatile PVOID*)&hNtDll, _hNtDll); #endif return; }
void lck(LCK *lk) { #ifdef _MSC_VER while (1==_InterlockedExchange(&lk->FLG, 1)) dprintf((diagout,">>>>ERROR<<<< spinning on lck %d\n",(lk)->NAME)); #else # ifdef unix pthread_mutex_lock(&lk->FLG); # else if (lk->FLG--) dprintf((diagout,">>>>ERROR<<<< lck %d already locked\n",(lk)->NAME)); # endif #endif }
void unlck(LCK *lk) { #ifdef _MSC_VER if (0==_InterlockedExchange(&lk->FLG, 0)) dprintf((diagout,">>>>ERROR<<<< unlcking unlck %d\n",lk->NAME)); #else # ifdef unix pthread_mutex_unlock(&lk->FLG); # else if (lk->FLG) lk->FLG=0; else dprintf((diagout,">>>>ERROR<<<< unlcking unlck %d\n",lk->NAME)); # endif #endif }
NTSTATUS NTAPI VTUTF8ChannelCreate(IN PSAC_CHANNEL Channel) { NTSTATUS Status; CHECK_PARAMETER(Channel); /* Allocate the output buffer */ Channel->OBuffer = SacAllocatePool(SAC_VTUTF8_OBUFFER_SIZE, GLOBAL_BLOCK_TAG); CHECK_ALLOCATION(Channel->OBuffer); /* Allocate the input buffer */ Channel->IBuffer = SacAllocatePool(SAC_VTUTF8_IBUFFER_SIZE, GLOBAL_BLOCK_TAG); CHECK_ALLOCATION(Channel->IBuffer); /* Initialize the output stream */ Status = VTUTF8ChannelOInit(Channel); if (NT_SUCCESS(Status)) return Status; /* Reset all flags and return success */ _InterlockedExchange(&Channel->ChannelHasNewOBufferData, 0); _InterlockedExchange(&Channel->ChannelHasNewIBufferData, 0); return STATUS_SUCCESS; }
BOOL NktIsMultiProcessor() { if (nProcessorsCount == 0) { SYSTEM_BASIC_INFORMATION sBasicInfo; LONG nTemp; NTSTATUS nNtStatus; nNtStatus = NktRtlGetNativeSystemInformation(SystemBasicInformation, &sBasicInfo, sizeof(sBasicInfo), NULL); if (nNtStatus == STATUS_NOT_IMPLEMENTED) nNtStatus = NktNtQuerySystemInformation(SystemBasicInformation, &sBasicInfo, sizeof(sBasicInfo), NULL); nTemp = 1; if (NT_SUCCESS(nNtStatus) && sBasicInfo.NumberOfProcessors > 1) nTemp = (LONG)(sBasicInfo.NumberOfProcessors); _InterlockedExchange(&nProcessorsCount, nTemp); } return (nProcessorsCount > 1) ? TRUE : FALSE; }
ULONG UpdateDotNetTraceInfoWithTimeout( _In_ PASMPAGE_QUERY_CONTEXT Context, _In_ BOOLEAN ClrV2, _In_opt_ PLARGE_INTEGER Timeout ) { HANDLE threadHandle; BOOLEAN timeout = FALSE; // ProcessDotNetTrace is not guaranteed to complete within any period of time, because // the target process might terminate before it writes the DCStartComplete_V1 event. // If the timeout is reached, the trace handle is closed, forcing ProcessTrace to stop // processing. Context->TraceClrV2 = ClrV2; Context->TraceResult = 0; Context->TraceHandleActive = 0; Context->TraceHandle = 0; threadHandle = PhCreateThread(0, UpdateDotNetTraceInfoThreadStart, Context); if (NtWaitForSingleObject(threadHandle, FALSE, Timeout) != STATUS_WAIT_0) { // Timeout has expired. Stop the trace processing if it's still active. // BUG: This assumes that the thread is in ProcessTrace. It might still be // setting up though! if (_InterlockedExchange(&Context->TraceHandleActive, 0) == 1) { CloseTrace(Context->TraceHandle); timeout = TRUE; } NtWaitForSingleObject(threadHandle, FALSE, NULL); } NtClose(threadHandle); if (timeout) return ERROR_TIMEOUT; return Context->TraceResult; }
static NTSTATUS InsertConsole(IN PCONSOLE Console) { ASSERT(Console); /* All went right, so add the console to the list */ ConDrvLockConsoleListExclusive(); DPRINT("Insert in the list\n"); InsertTailList(&ConsoleList, &Console->ListEntry); // FIXME: Move this code to the caller function!! /* Get a new console ID */ _InterlockedExchange((PLONG)&Console->ConsoleID, CurrentConsoleID); _InterlockedIncrement((PLONG)&CurrentConsoleID); /* Unlock the console list and return success */ ConDrvUnlockConsoleList(); return STATUS_SUCCESS; }
static VOID Initialize() { if (nInitialized == 0) { NktHookLib::Internals::CNktSimpleLockNonReentrant cLock(&nMutex); if (nInitialized == 0) { LONG nResult = -1; //are we running in a X64 processor? if (NktHookLibHelpers::GetProcessorArchitecture() == PROCESSOR_ARCHITECTURE_AMD64) { if (NktHookLib_InitializeWow64() != 0) nResult = 1; } _InterlockedExchange(&nInitialized, nResult); } } return; }
VOID NTAPI RawChannelSetIBufferIndex(IN PSAC_CHANNEL Channel, IN ULONG BufferIndex) { NTSTATUS Status; ASSERT(Channel); ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE); /* Set the new index, and if it's not zero, it means we have data */ Channel->IBufferIndex = BufferIndex; _InterlockedExchange(&Channel->ChannelHasNewIBufferData, BufferIndex != 0); /* If we have new data, and an event has been registered... */ if (!(Channel->IBufferIndex) && (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT)) { /* Go ahead and signal it */ ChannelClearEvent(Channel, HasNewDataEvent); UNREFERENCED_PARAMETER(Status); } }