/* Loop to install all queued devices installations */ static ULONG NTAPI DeviceInstallThread(IN PVOID Parameter) { HINF hSetupInf = *(HINF*)Parameter; PSLIST_ENTRY ListEntry; DeviceInstallParams* Params; LARGE_INTEGER Timeout; for (;;) { ListEntry = RtlInterlockedPopEntrySList(&DeviceInstallListHead); if (ListEntry == NULL) { /* * The list is now empty, but there may be a new enumerated device * that is going to be added to the list soon. In order to avoid * setting the hNoPendingInstalls event to release it soon after, * we wait for maximum 1 second for no PnP enumeration event being * received before declaring that no pending installations are * taking place and setting the corresponding event. */ Timeout.QuadPart = -10000000LL; /* Wait for 1 second */ if (NtWaitForSingleObject(hDeviceInstallListNotEmpty, FALSE, &Timeout) == STATUS_TIMEOUT) { /* We timed out: set the event and do the actual wait */ NtSetEvent(hNoPendingInstalls, NULL); NtWaitForSingleObject(hDeviceInstallListNotEmpty, FALSE, NULL); } } else { NtResetEvent(hNoPendingInstalls, NULL); Params = CONTAINING_RECORD(ListEntry, DeviceInstallParams, ListEntry); InstallDevice(hSetupInf, hEnumKey, hServicesKey, Params->DeviceIds); RtlFreeHeap(ProcessHeap, 0, Params); } } return 0; }
/* * @implemented */ DWORD WINAPI WaitForSingleObjectEx(IN HANDLE hHandle, IN DWORD dwMilliseconds, IN BOOL bAlertable) { PLARGE_INTEGER TimePtr; LARGE_INTEGER Time; NTSTATUS Status; RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActCtx; /* APCs must execute with the default activation context */ if (bAlertable) { /* Setup the frame */ RtlZeroMemory(&ActCtx, sizeof(ActCtx)); ActCtx.Size = sizeof(ActCtx); ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER; RtlActivateActivationContextUnsafeFast(&ActCtx, NULL); } /* Get real handle */ hHandle = TranslateStdHandle(hHandle); /* Check for console handle */ if ((IsConsoleHandle(hHandle)) && (VerifyConsoleIoHandle(hHandle))) { /* Get the real wait handle */ hHandle = GetConsoleInputWaitHandle(); } /* Convert the timeout */ TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds); /* Start wait loop */ do { /* Do the wait */ Status = NtWaitForSingleObject(hHandle, (BOOLEAN)bAlertable, TimePtr); if (!NT_SUCCESS(Status)) { /* The wait failed */ BaseSetLastNTError(Status); Status = WAIT_FAILED; } } while ((Status == STATUS_ALERTED) && (bAlertable)); /* Cleanup the activation context */ if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx); /* Return wait status */ return Status; }
/* * @implemented */ BOOL WINAPI LockFile(IN HANDLE hFile, IN DWORD dwFileOffsetLow, IN DWORD dwFileOffsetHigh, IN DWORD nNumberOfBytesToLockLow, IN DWORD nNumberOfBytesToLockHigh) { IO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status; LARGE_INTEGER BytesToLock, Offset; /* Is this a console handle? */ if (IsConsoleHandle(hFile)) { /* Can't "lock" a console! */ BaseSetLastNTError(STATUS_INVALID_HANDLE); return FALSE; } /* Setup the parameters in NT style and call the native API */ BytesToLock.u.LowPart = nNumberOfBytesToLockLow; BytesToLock.u.HighPart = nNumberOfBytesToLockHigh; Offset.u.LowPart = dwFileOffsetLow; Offset.u.HighPart = dwFileOffsetHigh; Status = NtLockFile(hFile, NULL, NULL, NULL, &IoStatusBlock, &Offset, &BytesToLock, 0, TRUE, TRUE); if (Status == STATUS_PENDING) { /* Wait for completion if needed */ Status = NtWaitForSingleObject(hFile, FALSE, NULL); if (NT_SUCCESS(Status)) Status = IoStatusBlock.Status; } /* Check if we failed */ if (!NT_SUCCESS(Status)) { /* Convert the error code and fail */ BaseSetLastNTError(Status); return FALSE; } /* Success! */ return TRUE; }
IHFSERVICE DWORD IHFAPI IHF_ActiveDetachProcess(DWORD pid) { DWORD module, engine, dwWrite; HANDLE hProc, hThread, hCmd; IO_STATUS_BLOCK ios; //man->LockHookman(); ProcessRecord* pr = man->GetProcessRecord(pid); hCmd = man->GetCmdHandleByPID(pid); if (pr == 0 || hCmd == 0) return FALSE; //hProc = pr->process_handle; //This handle may be closed(thus invalid) during the detach process. NtDuplicateObject(NtCurrentProcess(), pr->process_handle, NtCurrentProcess(), &hProc, 0, 0, DUPLICATE_SAME_ACCESS); //Make a copy of the process handle. module = pr->module_register; if (module == 0) return FALSE; engine = pr->engine_register; engine &= ~0xFF; SendParam sp = {}; sp.type = 4; NtWriteFile(hCmd, 0,0,0, &ios, &sp, sizeof(SendParam),0,0); //cmdq->AddRequest(sp, pid); dwWrite = 0x1000; hThread = IthCreateThread(LdrUnloadDll, engine, hProc); if (hThread == 0 || hThread == INVALID_HANDLE_VALUE) return FALSE; NtWaitForSingleObject(hThread, 0, 0); NtClose(hThread); hThread = IthCreateThread(LdrUnloadDll, module, hProc); if (hThread == 0 || hThread == INVALID_HANDLE_VALUE) return FALSE; NtWaitForSingleObject(hThread, 0, 0); //man->UnlockHookman(); THREAD_BASIC_INFORMATION info; NtQueryInformationThread(hThread, ThreadBasicInformation, &info, sizeof(info), 0); NtClose(hThread); NtSetEvent(hPipeExist, 0); FreeThreadStart(hProc); NtClose(hProc); dwWrite = 0x1000; return info.ExitStatus; }
NTSTATUS PhpTailQueryObjectHack( __out_opt PULONG ReturnLength ) { NTSTATUS status; LARGE_INTEGER timeout; PhQueryObjectContext.Initialized = TRUE; // Allow the worker thread to start. NtSetEvent(PhQueryObjectStartEvent, NULL); // Wait for the work to complete, with a timeout of 1 second. timeout.QuadPart = -1000 * PH_TIMEOUT_MS; status = NtWaitForSingleObject(PhQueryObjectCompletedEvent, FALSE, &timeout); PhQueryObjectContext.Initialized = FALSE; // Return normally if the work was completed. if (status == STATUS_WAIT_0) { ULONG returnLength; status = PhQueryObjectContext.Status; returnLength = PhQueryObjectContext.ReturnLength; PhReleaseQueuedLockExclusive(&PhQueryObjectMutex); if (ReturnLength) *ReturnLength = returnLength; return status; } // Kill the worker thread if it took too long. // else if (status == STATUS_TIMEOUT) else { // Kill the thread. if (NT_SUCCESS(NtTerminateThread(PhQueryObjectThreadHandle, STATUS_TIMEOUT))) { PhQueryObjectThreadHandle = NULL; // Delete the fiber (and free the thread stack). DeleteFiber(PhQueryObjectFiber); PhQueryObjectFiber = NULL; } PhReleaseQueuedLockExclusive(&PhQueryObjectMutex); return STATUS_UNSUCCESSFUL; } }
static NTSTATUS PhpWfsoThreadStart( _In_ PVOID Parameter ) { HANDLE eventHandle; LARGE_INTEGER timeout; eventHandle = Parameter; timeout.QuadPart = -(LONGLONG)UInt32x32To64(5, PH_TIMEOUT_SEC); NtWaitForSingleObject(eventHandle, FALSE, &timeout); return STATUS_SUCCESS; }
void ClearDumpInfo (void) { NTSTATUS Status; // // Pause profiling? // if (fPause) { Status = NtPulseEvent (hPauseEvent, NULL); if (!NT_SUCCESS(Status)) { fprintf (pfLog, "WSTDUMP: ClearDumpInfo () - NtPulseEvent() " "failed for PAUSE event - %lx\n", Status); exit (1); } } // // Dump data? // else if (fDump) { Status = NtPulseEvent (hDumpEvent, NULL); if (!NT_SUCCESS(Status)) { fprintf (pfLog, "WSTDUMP: ClearDumpInfo () - NtPulseEvent() " "failed for DUMP event - %lx\n", Status); exit (1); } } // // Clear data? // else if (fClear) { Status = NtPulseEvent (hClearEvent, NULL); if (!NT_SUCCESS(Status)) { fprintf (pfLog, "WSTDUMP: ClearDumpInfo () - NtPulseEvent() " "failed for CLEAR event - %lx\n", Status); exit (1); } } // // Wait for the DONE event.. // Sleep (500); Status = NtWaitForSingleObject (hDoneEvent, FALSE, NULL); if (!NT_SUCCESS(Status)) { fprintf (pfLog, "WSTDUMP: ClearDumpInfo () - NtWaitForSingleObject() " "failed for DONE event - %lx\n", Status); exit (1); } } /* ClearDumpInfo() */
ULONG UpdateDotNetTraceInfoWithTimeout( __in PASMPAGE_CONTEXT Context, __in BOOLEAN ClrV2, __in_opt PLARGE_INTEGER Timeout ) { HANDLE threadHandle; // 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); } NtWaitForSingleObject(threadHandle, FALSE, NULL); } NtClose(threadHandle); return Context->TraceResult; }
NTSTATUS FsRtlpRegisterProviderWithMUP(IN HANDLE MupHandle, IN PCUNICODE_STRING RedirectorDeviceName, IN BOOLEAN MailslotsSupported) { NTSTATUS Status; ULONG BufferSize; IO_STATUS_BLOCK IoStatusBlock; PMUP_PROVIDER_REGISTRATION_INFO RegistrationInfo; PAGED_CODE(); DPRINT1("FsRtlpRegisterProviderWithMUP(%p, %wZ, %u)\n", (PVOID)MupHandle, RedirectorDeviceName, MailslotsSupported); /* We have to be able to store the name and the registration information */ BufferSize = RedirectorDeviceName->Length + sizeof(MUP_PROVIDER_REGISTRATION_INFO); RegistrationInfo = ExAllocatePoolWithTag(NonPagedPool, BufferSize, TAG_UNC); if (RegistrationInfo == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } /* Set the information about the provider (including its name) */ RegistrationInfo->RedirectorDeviceNameOffset = sizeof(MUP_PROVIDER_REGISTRATION_INFO); RegistrationInfo->RedirectorDeviceNameLength = RedirectorDeviceName->Length; RegistrationInfo->MailslotsSupported = MailslotsSupported; RtlCopyMemory((PWSTR)((ULONG_PTR)RegistrationInfo + RegistrationInfo->RedirectorDeviceNameOffset), RedirectorDeviceName->Buffer, RedirectorDeviceName->Length); /* Call MUP with the registration FSCTL */ Status = NtFsControlFile(MupHandle, NULL, NULL, NULL, &IoStatusBlock, FSCTL_MUP_REGISTER_PROVIDER, RegistrationInfo, BufferSize, NULL, 0); if (Status == STATUS_PENDING) { Status = NtWaitForSingleObject(MupHandle, TRUE, NULL); } if (NT_SUCCESS(Status)) { Status = IoStatusBlock.Status; } /* And we're done! */ ASSERT(NT_SUCCESS(Status)); ExFreePoolWithTag(RegistrationInfo, TAG_UNC); return Status; }
IHFSERVICE DWORD IHFAPI IHF_ModifyHook(DWORD pid, HookParam* hp) { SendParam sp; HANDLE hModify,hCmd; hCmd = GetCmdHandleByPID(pid); if (hCmd == 0) return -1; hModify = IthCreateEvent(L"ITH_MODIFY_HOOK"); sp.type = IHF_COMMAND_MODIFY_HOOK; sp.hp = *hp; IO_STATUS_BLOCK ios; if (NT_SUCCESS(NtWriteFile(hCmd, 0,0,0, &ios, &sp, sizeof(SendParam), 0, 0))) NtWaitForSingleObject(hModify, 0, 0); NtClose(hModify); man -> RemoveSingleHook(pid, sp.hp.addr); return 0; }
/*++ * @name RtlClipWaitForInput * * The RtlClipWaitForInput routine waits for input from an input device. * * @param hDriver * Handle of the driver/device to get input from. * * @param Buffer * Input buffer. * * @param BufferSize * Size of the input buffer. * * @return STATUS_SUCCESS or error code from the read operation. * * @remarks This routine waits for input to be available. * *--*/ NTSTATUS RtlClipWaitForInput(IN HANDLE hDriver, IN PVOID Buffer, IN OUT PULONG BufferSize) { IO_STATUS_BLOCK Iosb; LARGE_INTEGER ByteOffset; NTSTATUS Status; // // Clean up the I/O Status block and read from byte 0 // RtlZeroMemory(&Iosb, sizeof(Iosb)); RtlZeroMemory(&ByteOffset, sizeof(ByteOffset)); // // Try to read the data // Status = NtReadFile(hDriver, hEvent, NULL, NULL, &Iosb, Buffer, *BufferSize, &ByteOffset, NULL); // // Check if data is pending // if (Status == STATUS_PENDING) { // // Wait on the data to be read // Status = NtWaitForSingleObject(hEvent, TRUE, NULL); } // // Return status and how much data was read // *BufferSize = (ULONG)Iosb.Information; return Status; }
BOOLEAN WeLockServerSharedData( __out PWE_HOOK_SHARED_DATA *Data ) { LARGE_INTEGER timeout; if (!WeServerSharedSectionLock) return FALSE; timeout.QuadPart = -WE_CLIENT_MESSAGE_TIMEOUT * PH_TIMEOUT_MS; if (NtWaitForSingleObject(WeServerSharedSectionLock, FALSE, &timeout) != WAIT_OBJECT_0) return FALSE; *Data = WeServerSharedData; return TRUE; }
IHFSERVICE DWORD IHFAPI IHF_RemoveHook(DWORD pid, DWORD addr) { HANDLE hRemoved,hCmd; hCmd = GetCmdHandleByPID(pid); if (hCmd == 0) return -1; hRemoved = IthCreateEvent(L"ITH_REMOVE_HOOK"); SendParam sp = {}; IO_STATUS_BLOCK ios; sp.type = IHF_COMMAND_REMOVE_HOOK; sp.hp.addr = addr; //cmdq -> AddRequest(sp, pid); NtWriteFile(hCmd, 0,0,0, &ios, &sp, sizeof(SendParam),0,0); NtWaitForSingleObject(hRemoved, 0, 0); NtClose(hRemoved); man -> RemoveSingleHook(pid, sp.hp.addr); return 0; }
BOOL WINAPI ReadConsoleInput( IN HANDLE hConsoleInput, OUT PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsRead) { LARGE_INTEGER Offset; IO_STATUS_BLOCK IoStatusBlock; KEYBOARD_INPUT_DATA InputData; NTSTATUS Status; Offset.QuadPart = 0; Status = NtReadFile(hConsoleInput, NULL, NULL, NULL, &IoStatusBlock, &InputData, sizeof(KEYBOARD_INPUT_DATA), &Offset, 0); if (Status == STATUS_PENDING) { Status = NtWaitForSingleObject(hConsoleInput, FALSE, NULL); Status = IoStatusBlock.Status; } if (!NT_SUCCESS(Status)) return FALSE; lpBuffer->EventType = KEY_EVENT; Status = IntTranslateKey(&InputData, &lpBuffer->Event.KeyEvent); if (!NT_SUCCESS(Status)) return FALSE; *lpNumberOfEventsRead = 1; return TRUE; }
static NTSTATUS GetAddrEntries( _In_ HANDLE TcpFile, _In_ TDIEntityID InterfaceID, _Out_ IPAddrEntry* Entries, _In_ ULONG NumEntries) { TCP_REQUEST_QUERY_INFORMATION_EX TcpQueryInfo; IO_STATUS_BLOCK StatusBlock; NTSTATUS Status; ZeroMemory(&TcpQueryInfo, sizeof(TcpQueryInfo)); TcpQueryInfo.ID.toi_class = INFO_CLASS_PROTOCOL; TcpQueryInfo.ID.toi_type = INFO_TYPE_PROVIDER; TcpQueryInfo.ID.toi_id = IP_MIB_ADDRTABLE_ENTRY_ID; TcpQueryInfo.ID.toi_entity = InterfaceID; Status = NtDeviceIoControlFile( TcpFile, NULL, NULL, NULL, &StatusBlock, IOCTL_TCP_QUERY_INFORMATION_EX, &TcpQueryInfo, sizeof(TcpQueryInfo), Entries, NumEntries * sizeof(Entries[0])); if (Status == STATUS_PENDING) { /* So we have to wait a bit */ Status = NtWaitForSingleObject(TcpFile, FALSE, NULL); if (NT_SUCCESS(Status)) Status = StatusBlock.Status; } return Status; }
int XWriteFile( int handle, void *buffer, unsigned int numberOfBytesToWrite, unsigned int *numberOfBytesWritten) { IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status; #ifdef DEBUG debugPrint("XWriteFile handle=%08x numberOfBytesToWrite=%08x\n", handle, numberOfBytesToWrite); #endif if(numberOfBytesWritten) *numberOfBytesWritten = 0; status = NtWriteFile( (void*)handle, NULL, NULL, NULL, &ioStatusBlock, buffer, numberOfBytesToWrite, NULL); if (status == STATUS_PENDING) status = NtWaitForSingleObject((void*)handle, FALSE, NULL); if (!NT_SUCCESS(status)) return RtlNtStatusToDosError(status); else { if (numberOfBytesWritten) *numberOfBytesWritten = (unsigned int)ioStatusBlock.Information; return STATUS_SUCCESS; } }
BOOLEAN EnableUserModePnpManager(VOID) { LARGE_INTEGER Timeout; /* Start the PnP thread */ if (hPnpThread != NULL) NtResumeThread(hPnpThread, NULL); /* * Wait a little bit so that we get a chance to have some events being * queued by the time the device-installation thread becomes resumed. */ Timeout.QuadPart = -10000000LL; /* Wait for 1 second */ NtWaitForSingleObject(hDeviceInstallListNotEmpty, FALSE, &Timeout); /* Start the device installation thread */ if (hDeviceInstallThread != NULL) NtResumeThread(hDeviceInstallThread, NULL); return TRUE; }
int XReadFile( int handle, void *buffer, unsigned int numberOfBytesToRead, unsigned int *numberOfBytesRead) { IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status; #ifdef DEBUG debugPrint("XReadFile handle=%08x numberOfBytesToRead=%08x\n", handle, numberOfBytesToRead); #endif if (numberOfBytesRead) *numberOfBytesRead = 0; status = NtReadFile( (void*)handle, NULL, NULL, NULL, (void*)&ioStatusBlock, (void*)buffer, numberOfBytesToRead, NULL); if (status == STATUS_SUCCESS) status = NtWaitForSingleObject((void*)handle, FALSE, (void*)NULL); if (!NT_SUCCESS(status)) return RtlNtStatusToDosError(status); else { if (numberOfBytesRead) *numberOfBytesRead = (unsigned int)ioStatusBlock.Information; return STATUS_SUCCESS; } }
/* * Fills the IFEntry buffer from tcpip.sys. * The buffer size MUST be FIELD_OFFSET(IFEntry, if_descr[MAX_ADAPTER_DESCRIPTION_LENGTH + 1]). * See MSDN IFEntry struct definition if you don't believe me. ;-) */ static NTSTATUS GetInterfaceEntry( _In_ HANDLE TcpFile, _In_ TDIEntityID InterfaceID, _Out_ IFEntry* Entry) { TCP_REQUEST_QUERY_INFORMATION_EX TcpQueryInfo; IO_STATUS_BLOCK StatusBlock; NTSTATUS Status; ZeroMemory(&TcpQueryInfo, sizeof(TcpQueryInfo)); TcpQueryInfo.ID.toi_class = INFO_CLASS_PROTOCOL; TcpQueryInfo.ID.toi_type = INFO_TYPE_PROVIDER; TcpQueryInfo.ID.toi_id = IP_MIB_STATS_ID; TcpQueryInfo.ID.toi_entity = InterfaceID; Status = NtDeviceIoControlFile( TcpFile, NULL, NULL, NULL, &StatusBlock, IOCTL_TCP_QUERY_INFORMATION_EX, &TcpQueryInfo, sizeof(TcpQueryInfo), Entry, FIELD_OFFSET(IFEntry, if_descr[MAX_ADAPTER_DESCRIPTION_LENGTH + 1])); if (Status == STATUS_PENDING) { /* So we have to wait a bit */ Status = NtWaitForSingleObject(TcpFile, FALSE, NULL); if (NT_SUCCESS(Status)) Status = StatusBlock.Status; } return Status; }
static DWORD WINAPI ThreadProc1(LPVOID parm) { LARGE_INTEGER waittime; NTSTATUS res; HANDLE e; GET_NTDLL(NtWaitForSingleObject, (IN HANDLE ObjectHandle, IN BOOLEAN Alertable, IN PLARGE_INTEGER TimeOut)); print("starting thread...\n"); e = CreateEvent(NULL, FALSE, FALSE, "foo"); waittime.QuadPart = -((int)500 * TIMER_UNITS_PER_MILLISECOND); control = 1; do { res = NtWaitForSingleObject(e, false /* not alertable */, &waittime); } while (control); __asm { mov reg_eax, eax mov reg_ebx, ebx mov reg_ecx, ecx mov reg_edx, edx mov reg_edi, edi mov reg_esi, esi mov reg_esp, esp mov reg_ebp, ebp } print("res is " PFMT " but shouldn't get here!!!\n", res); #if VERBOSE print("registers: " PFMT " " PFMT " " PFMT " " PFMT " " PFMT " " PFMT " " PFMT " " PFMT "\n", reg_eax, reg_ebx, reg_ecx, reg_edx, reg_edi, reg_esi, reg_esp, reg_ebp); #endif CloseHandle(e); print("exiting thread\n"); return -1; }
/* * @implemented */ BOOL WINAPI UnlockFile(IN HANDLE hFile, IN DWORD dwFileOffsetLow, IN DWORD dwFileOffsetHigh, IN DWORD nNumberOfBytesToUnlockLow, IN DWORD nNumberOfBytesToUnlockHigh) { OVERLAPPED Overlapped; NTSTATUS Status; BOOLEAN Result; /* Convert parameters to Ex format and call the new API */ Overlapped.Offset = dwFileOffsetLow; Overlapped.OffsetHigh = dwFileOffsetHigh; Result = UnlockFileEx(hFile, 0, nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh, &Overlapped); if (!(Result) && (GetLastError() == ERROR_IO_PENDING)) { /* Ex fails during STATUS_PENDING, handle that here by waiting */ Status = NtWaitForSingleObject(hFile, FALSE, NULL); if (NT_SUCCESS(Status)) Status = Overlapped.Internal; /* Now if the status is successful, return */ if (!NT_SUCCESS(Status)) return TRUE; /* Otherwise the asynchronous operation had a failure, so fail */ BaseSetLastNTError(Status); return FALSE; } /* Success or error case -- Ex took care of the rest, just return */ return Result; }
ULONG BaseSrvNlsSetUserInfo( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus) { PBASE_NLS_SET_USER_INFO_MSG a = (PBASE_NLS_SET_USER_INFO_MSG)&m->u.ApiMessageData; ULONG rc; /* return code */ /* * Get the cache mutant. */ NtWaitForSingleObject( hNlsCacheMutant, FALSE, NULL ); /* * Set the value in the registry and update the cache. */ rc = NlsSetRegAndCache( a->pValue, a->pCacheString, a->pData, a->DataLength ); /* * Release the cache mutant. */ NtReleaseMutant( hNlsCacheMutant, NULL ); /* * Return the result of NtSetValueKey. */ return (rc); ReplyStatus; // get rid of unreferenced parameter warning message }
BOOLEAN WeSendServerRequest( __in HWND hWnd ) { ULONG threadId; ULONG processId; LARGE_INTEGER timeout; if (!WeServerSharedData || !WeServerSharedSectionEvent) return FALSE; threadId = GetWindowThreadProcessId(hWnd, &processId); if (UlongToHandle(processId) == NtCurrentProcessId()) { // We are trying to get information about the server. Call the procedure directly. WepWriteClientData(hWnd); return TRUE; } // Call the client and wait for the client to finish. WeCurrentMessageId++; WeServerSharedData->MessageId = WeCurrentMessageId; NtResetEvent(WeServerSharedSectionEvent, NULL); if (!SendNotifyMessage(hWnd, WeServerMessage, (WPARAM)NtCurrentProcessId(), WeCurrentMessageId)) return FALSE; timeout.QuadPart = -WE_CLIENT_MESSAGE_TIMEOUT * PH_TIMEOUT_MS; if (NtWaitForSingleObject(WeServerSharedSectionEvent, FALSE, &timeout) != STATUS_WAIT_0) return FALSE; return TRUE; }
/* * @implemented */ BOOL WINAPI DisconnectNamedPipe(HANDLE hNamedPipe) { IO_STATUS_BLOCK Iosb; NTSTATUS Status; /* Send the FSCTL to the driver */ Status = NtFsControlFile(hNamedPipe, NULL, NULL, NULL, &Iosb, FSCTL_PIPE_DISCONNECT, NULL, 0, NULL, 0); if (Status == STATUS_PENDING) { /* Wait on NPFS to finish and get updated status */ Status = NtWaitForSingleObject(hNamedPipe, FALSE, NULL); if (NT_SUCCESS(Status)) Status = Iosb.Status; } /* Check for error */ if (!NT_SUCCESS(Status)) { /* Fail */ BaseSetLastNTError(Status); return FALSE; } return TRUE; }
DWORD WINAPI WaitForPipe(LPVOID lpThreadParameter) //Dynamic detect ITH main module status. { int i; TextHook *man; struct { DWORD pid; TextHook *man; DWORD module; DWORD engine; } u; HANDLE hMutex,hPipeExist; //swprintf(engine_event,L"ITH_ENGINE_%d",current_process_id); swprintf(detach_mutex,L"ITH_DETACH_%d",current_process_id); //swprintf(lose_event,L"ITH_LOSEPIPE_%d",current_process_id); //hEngine=IthCreateEvent(engine_event); //NtWaitForSingleObject(hEngine,0,0); //NtClose(hEngine); while (engine_base == 0) NtDelayExecution(0, &wait_time); //LoadEngine(L"ITH_Engine.dll"); u.module=module_base; u.pid=current_process_id; u.man=hookman; u.engine=engine_base; hPipeExist=IthOpenEvent(exist); IO_STATUS_BLOCK ios; //hLose=IthCreateEvent(lose_event,0,0); if (hPipeExist!=INVALID_HANDLE_VALUE) while (running) { hPipe=INVALID_HANDLE_VALUE; hCommand=INVALID_HANDLE_VALUE; while (NtWaitForSingleObject(hPipeExist,0,&wait_time)==WAIT_TIMEOUT) if (!running) goto _release; hMutex=IthCreateMutex(mutex,0); NtWaitForSingleObject(hMutex,0,0); while (hPipe==INVALID_HANDLE_VALUE|| hCommand==INVALID_HANDLE_VALUE) { NtDelayExecution(0,&sleep_time); if (hPipe==INVALID_HANDLE_VALUE) hPipe=IthOpenPipe(recv_pipe,GENERIC_WRITE); if (hCommand==INVALID_HANDLE_VALUE) hCommand=IthOpenPipe(command,GENERIC_READ); } //NtClearEvent(hLose); NtWriteFile(hPipe,0,0,0,&ios,&u,16,0,0); live=true; for (man=hookman,i=0;i<current_hook;man++) if (man->RecoverHook()) i++; OutputConsole(dll_name); OutputConsole(L"Pipe connected."); //OutputDWORD(tree->Count()); NtReleaseMutant(hMutex,0); NtClose(hMutex); if (!hook_inserted && engine_base) { hook_inserted=true; IdentifyEngine(); } hDetach=IthCreateMutex(detach_mutex,1); while (running&&NtWaitForSingleObject(hPipeExist,0,&sleep_time)==WAIT_OBJECT_0) NtDelayExecution(0,&sleep_time); live=false; for (man=hookman,i=0;i<current_hook;man++) if (man->RemoveHook()) i++; if (!running) { NtWriteFile(hPipe,0,0,0,&ios,man,4,0,0); IthReleaseMutex(hDetach); } NtClose(hDetach); NtClose(hPipe); } _release: //NtClose(hLose); NtClose(hPipeExist); return 0; }
DWORD WINAPI CommandPipe(LPVOID lpThreadParameter) { DWORD command; BYTE buff[0x400]={}; HANDLE hPipeExist; hPipeExist=IthOpenEvent(exist); IO_STATUS_BLOCK ios={0}; NTSTATUS status; if (hPipeExist!=INVALID_HANDLE_VALUE) while (running) { while (!live) { if (!running) goto _detach; NtDelayExecution(0,&sleep_time); } status=NtReadFile(hCommand,0,0,0,&ios,buff,0x200,0,0); if (status==STATUS_PIPE_BROKEN|| status==STATUS_PIPE_DISCONNECTED) { NtClearEvent(hPipeExist); continue; } if (status==STATUS_PENDING) { NtWaitForSingleObject(hCommand,0,0); switch (ios.Status) { case 0: break; case STATUS_PIPE_BROKEN: case STATUS_PIPE_DISCONNECTED: NtClearEvent(hPipeExist); continue; break; default: if (NtWaitForSingleObject(hDetach,0,&wait_time)==WAIT_OBJECT_0) goto _detach; } } if (ios.uInformation) if (live) { command=*(DWORD*)buff; switch(command) { case IHF_COMMAND_NEW_HOOK: //IthBreak(); buff[ios.uInformation] = 0; buff[ios.uInformation + 1] = 0; NewHook(*(HookParam*)(buff+4),(LPWSTR)(buff + 4 + sizeof(HookParam)),0); break; case IHF_COMMAND_REMOVE_HOOK: { DWORD rm_addr=*(DWORD*)(buff+4); HANDLE hRemoved=IthOpenEvent(L"ITH_REMOVE_HOOK"); TextHook* in=hookman; int i; for (i=0;i<current_hook;in++) { if (in->Address()) i++; if (in->Address()==rm_addr) break; } if (in->Address()) in->ClearHook(); IthSetEvent(hRemoved); NtClose(hRemoved); break; } case IHF_COMMAND_MODIFY_HOOK: { DWORD rm_addr=*(DWORD*)(buff+4); HANDLE hModify=IthOpenEvent(L"ITH_MODIFY_HOOK"); TextHook* in=hookman; int i; for (i=0;i<current_hook;in++) { if (in->Address()) i++; if (in->Address()==rm_addr) break; } if (in->Address()) in->ModifyHook(*(HookParam*)(buff+4)); IthSetEvent(hModify); NtClose(hModify); break; } break; case IHF_COMMAND_DETACH: running=false; live=false; goto _detach; default: break; } } } _detach: NtClose(hPipeExist); NtClose(hCommand); return 0; }
NTSTATUS LsapOpenSam( VOID ) /*++ Routine Description: This routine opens SAM for use during authentication. It opens a handle to both the BUILTIN domain and the ACCOUNT domain. Arguments: None. Return Value: STATUS_SUCCESS - Succeeded. --*/ { NTSTATUS Status, IgnoreStatus; PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo; SAMPR_HANDLE SamHandle; HANDLE EventHandle; OBJECT_ATTRIBUTES EventAttributes; UNICODE_STRING EventName; LARGE_INTEGER Timeout; if (LsapSamOpened == TRUE) { // Global variable return(STATUS_SUCCESS); } // // Make sure SAM has initialized // RtlInitUnicodeString( &EventName, L"\\SAM_SERVICE_STARTED"); InitializeObjectAttributes( &EventAttributes, &EventName, 0, 0, NULL ); Status = NtOpenEvent( &EventHandle, SYNCHRONIZE, &EventAttributes ); ASSERT( Status == STATUS_SUCCESS || Status == STATUS_OBJECT_NAME_NOT_FOUND ); if (NT_SUCCESS(Status)) { // // See if SAM has signalled that he is initialized. // Timeout.QuadPart = -10000000; // 1000 seconds Timeout.QuadPart *= 1000; Status = NtWaitForSingleObject( EventHandle, FALSE, &Timeout ); IgnoreStatus = NtClose( EventHandle ); ASSERT(NT_SUCCESS(IgnoreStatus)); } if ( !NT_SUCCESS(Status) || Status == STATUS_TIMEOUT ) { return( STATUS_INVALID_SERVER_STATE ); } // // Get the member Sid information for the account domain // Status = LsapGetAccountDomainInfo( &PolicyAccountDomainInfo ); if (!NT_SUCCESS(Status)) { return(Status); } // // Get our handles to the ACCOUNT and BUILTIN domains. // Status = SamIConnect( NULL, // No server name &SamHandle, SAM_SERVER_CONNECT, TRUE ); // Indicate we are privileged if ( NT_SUCCESS(Status) ) { // // Open the ACCOUNT domain. // Status = SamrOpenDomain( SamHandle, DOMAIN_ALL_ACCESS, PolicyAccountDomainInfo->DomainSid, &LsapAccountDomainHandle ); if (NT_SUCCESS(Status)) { // // Open the BUILTIN domain. // Status = SamrOpenDomain( SamHandle, DOMAIN_ALL_ACCESS, LsapBuiltInDomainSid, &LsapBuiltinDomainHandle ); if (NT_SUCCESS(Status)) { LsapSamOpened = TRUE; } else { IgnoreStatus = SamrCloseHandle( &LsapAccountDomainHandle ); ASSERT(NT_SUCCESS(IgnoreStatus)); } } IgnoreStatus = SamrCloseHandle( &SamHandle ); ASSERT(NT_SUCCESS(IgnoreStatus)); } // // Free the ACCOUNT domain information // LsaFreeMemory( PolicyAccountDomainInfo ); return(Status); }
NTSTATUS LsapInstallationPause( VOID ) /*++ Routine Description: This function checks to see if the system is in an installation state. If so, it suspends further initialization until the installation state is complete. Installation state is signified by the existance of a well known event. Arguments: None. Return Value: STATUS_SUCCESS - Proceed with initialization. Other status values are unexpected. --*/ { NTSTATUS NtStatus, TmpStatus; HANDLE InstallationEvent; OBJECT_ATTRIBUTES EventAttributes; UNICODE_STRING EventName; // // If the following event exists, it is an indication that // installation is in progress and that further security // initialization should be delayed until the event is // signalled. This is expected to be a NOTIFICATION event. // RtlInitUnicodeString( &EventName, L"\\INSTALLATION_SECURITY_HOLD"); InitializeObjectAttributes( &EventAttributes, &EventName, 0, 0, NULL ); NtStatus = NtOpenEvent( &InstallationEvent, SYNCHRONIZE, &EventAttributes ); if ( NT_SUCCESS(NtStatus)) { // // The event exists - installation created it and will signal it // when it is ok to proceed with security initialization. // LsapSetupWasRun = TRUE; // // Installation code is responsible for deleting the event after // signalling it. // NtStatus = NtWaitForSingleObject( InstallationEvent, TRUE, 0 ); TmpStatus = NtClose( InstallationEvent ); ASSERT(NT_SUCCESS(TmpStatus)); } else { NtStatus = STATUS_SUCCESS; // Indicate everything is as expected } return(NtStatus); }
NTSTATUS PhpWorkQueueThreadStart( _In_ PVOID Parameter ) { PPH_WORK_QUEUE workQueue = (PPH_WORK_QUEUE)Parameter; while (TRUE) { NTSTATUS status; HANDLE semaphoreHandle; LARGE_INTEGER timeout; PPH_WORK_QUEUE_ITEM workQueueItem = NULL; // Check if we have more threads than the limit. if (workQueue->CurrentThreads > workQueue->MaximumThreads) { BOOLEAN terminate = FALSE; // Lock and re-check. PhAcquireQueuedLockExclusive(&workQueue->StateLock); // Check the minimum as well. if (workQueue->CurrentThreads > workQueue->MaximumThreads && workQueue->CurrentThreads > workQueue->MinimumThreads) { workQueue->CurrentThreads--; terminate = TRUE; } PhReleaseQueuedLockExclusive(&workQueue->StateLock); if (terminate) break; } semaphoreHandle = PhpGetSemaphoreWorkQueue(workQueue); if (!workQueue->Terminating) { // Wait for work. status = NtWaitForSingleObject( semaphoreHandle, FALSE, PhTimeoutFromMilliseconds(&timeout, workQueue->NoWorkTimeout) ); } else { status = STATUS_UNSUCCESSFUL; } if (status == STATUS_WAIT_0 && !workQueue->Terminating) { PLIST_ENTRY listEntry; // Dequeue the work item. PhAcquireQueuedLockExclusive(&workQueue->QueueLock); listEntry = RemoveHeadList(&workQueue->QueueListHead); if (IsListEmpty(&workQueue->QueueListHead)) PhPulseCondition(&workQueue->QueueEmptyCondition); PhReleaseQueuedLockExclusive(&workQueue->QueueLock); // Make sure we got work. if (listEntry != &workQueue->QueueListHead) { workQueueItem = CONTAINING_RECORD(listEntry, PH_WORK_QUEUE_ITEM, ListEntry); PhpExecuteWorkQueueItem(workQueueItem); _InterlockedDecrement(&workQueue->BusyCount); PhpDestroyWorkQueueItem(workQueueItem); } } else { BOOLEAN terminate = FALSE; // No work arrived before the timeout passed, or we are terminating, or some error occurred. // Terminate the thread. PhAcquireQueuedLockExclusive(&workQueue->StateLock); if (workQueue->Terminating || workQueue->CurrentThreads > workQueue->MinimumThreads) { workQueue->CurrentThreads--; terminate = TRUE; } PhReleaseQueuedLockExclusive(&workQueue->StateLock); if (terminate) break; } } PhReleaseRundownProtection(&workQueue->RundownProtect); return STATUS_SUCCESS; }
VOID Directory( IN PCHAR String ) { NTSTATUS Status; HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; STRING NameString; IO_STATUS_BLOCK IoStatus; NTSTATUS NtStatus; PFILE_ADIRECTORY_INFORMATION FileInfo; ULONG i; // // Get the filename // simprintf("Directory ", 0); simprintf(String, 0); simprintf("\n", 0); // // Open the file for list directory access // RtlInitString( &NameString, String ); InitializeObjectAttributes( &ObjectAttributes, &NameString, 0, NULL, NULL ); if (!NT_SUCCESS(Status = NtOpenFile( &FileHandle, FILE_LIST_DIRECTORY | SYNCHRONIZE, &ObjectAttributes, &IoStatus, FILE_SHARE_READ, WriteThrough | FILE_DIRECTORY_FILE ))) { OpenFileError( Status , String ); return; } // // zero out the buffer so next time we'll recognize the end of data // for (i = 0; i < BUFFERSIZE; i += 1) { Buffer[i] = 0; } // // Do the directory loop // for (NtStatus = NtQueryDirectoryFile( FileHandle, (HANDLE)NULL, (PIO_APC_ROUTINE)NULL, (PVOID)NULL, &IoStatus, Buffer, BUFFERSIZE, FileADirectoryInformation, FALSE, (PSTRING)NULL, TRUE); NT_SUCCESS(NtStatus); NtStatus = NtQueryDirectoryFile( FileHandle, (HANDLE)NULL, (PIO_APC_ROUTINE)NULL, (PVOID)NULL, &IoStatus, Buffer, BUFFERSIZE, FileADirectoryInformation, FALSE, (PSTRING)NULL, FALSE) ) { if (!NT_SUCCESS(Status = NtWaitForSingleObject(FileHandle, TRUE, NULL))) { // NtPartyByNumber(50); WaitForSingleObjectError( Status ); return; } // // Check the Irp for success // if (!NT_SUCCESS(IoStatus.Status)) { break; } // // For every record in the buffer type out the directory information // // // Point to the first record in the buffer, we are guaranteed to have // one otherwise IoStatus would have been No More Files // FileInfo = (PFILE_ADIRECTORY_INFORMATION)&Buffer[0]; while (TRUE) { // // Print out information about the file // simprintf("%8lx ", FileInfo->FileAttributes); simprintf("%8lx/", FileInfo->EndOfFile.LowPart); simprintf("%8lx ", FileInfo->AllocationSize.LowPart); { CHAR Saved; Saved = FileInfo->FileName[FileInfo->FileNameLength]; FileInfo->FileName[FileInfo->FileNameLength] = 0; simprintf(FileInfo->FileName, 0); FileInfo->FileName[FileInfo->FileNameLength] = Saved; } simprintf("\n", 0); // // Check if there is another record, if there isn't then we // simply get out of this loop // if (FileInfo->NextEntryOffset == 0) { break; } // // There is another record so advance FileInfo to the next // record // FileInfo = (PFILE_ADIRECTORY_INFORMATION)(((PUCHAR)FileInfo) + FileInfo->NextEntryOffset); } // // zero out the buffer so next time we'll recognize the end of data // for (i = 0; i < BUFFERSIZE; i += 1) { Buffer[i] = 0; } } // // Now close the file // if (!NT_SUCCESS(Status = NtClose( FileHandle ))) { CloseError( Status ); } // // And return to our caller // return; }