/* * @implemented */ BOOL WINAPI EmptyWorkingSet(HANDLE hProcess) { SYSTEM_INFO SystemInfo; QUOTA_LIMITS QuotaLimits; NTSTATUS Status; GetSystemInfo(&SystemInfo); /* Query the working set */ Status = NtQueryInformationProcess(hProcess, ProcessQuotaLimits, &QuotaLimits, sizeof(QuotaLimits), NULL); if (!NT_SUCCESS(Status)) { SetLastError(RtlNtStatusToDosError(Status)); return FALSE; } /* Empty the working set */ QuotaLimits.MinimumWorkingSetSize = -1; QuotaLimits.MaximumWorkingSetSize = -1; /* Set the working set */ Status = NtSetInformationProcess(hProcess, ProcessQuotaLimits, &QuotaLimits, sizeof(QuotaLimits)); if (!NT_SUCCESS(Status) && Status != STATUS_PRIVILEGE_NOT_HELD) { SetLastError(RtlNtStatusToDosError(Status)); return FALSE; } return TRUE; }
int _cdecl _main(int argc, char *argv[], char *envp[], int DebugFlag) { KPRIORITY BasePriority = (8 + 1) + 4; NTSTATUS Status; //ULONG Response; // see the #if 0 UNREFERENCED_PARAMETER(envp); UNREFERENCED_PARAMETER(DebugFlag); /* Set the Priority */ NtSetInformationProcess(NtCurrentProcess(), ProcessBasePriority, &BasePriority, sizeof(KPRIORITY)); /* Give us IOPL so that we can access the VGA registers */ Status = NtSetInformationProcess(NtCurrentProcess(), ProcessUserModeIOPL, NULL, 0); if (!NT_SUCCESS(Status)) { /* Raise a hard error */ DPRINT1("CSRSS: Could not raise IOPL, Status: 0x%08lx\n", Status); #if 0 Status = NtRaiseHardError(STATUS_IO_PRIVILEGE_FAILED, 0, 0, NULL, OptionOk, &Response); #endif } /* Initialize CSR through CSRSRV */ Status = CsrServerInitialization(argc, argv); if (!NT_SUCCESS(Status)) { /* Kill us */ DPRINT1("CSRSS: Unable to initialize server, Status: 0x%08lx\n", Status); NtTerminateProcess(NtCurrentProcess(), Status); } /* Disable errors */ CsrpSetDefaultProcessHardErrorMode(); /* If this is Session 0, make sure killing us bugchecks the system */ if (NtCurrentPeb()->SessionId == 0) RtlSetProcessIsCritical(TRUE, NULL, FALSE); /* Kill this thread. CSRSRV keeps us going */ NtTerminateThread(NtCurrentThread(), Status); return 0; }
/* * @implemented */ BOOL WINAPI CreateProcessAsUserA(HANDLE hToken, LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { PROCESS_ACCESS_TOKEN AccessToken; NTSTATUS Status; TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName), debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation); /* Create the process with a suspended main thread */ if (!CreateProcessA(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags | CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation)) { ERR("CreateProcessA failed! GLE: %d\n", GetLastError()); return FALSE; } AccessToken.Token = hToken; AccessToken.Thread = NULL; /* Set the new process token */ Status = NtSetInformationProcess(lpProcessInformation->hProcess, ProcessAccessToken, (PVOID)&AccessToken, sizeof(AccessToken)); if (!NT_SUCCESS (Status)) { ERR("NtSetInformationProcess failed: 0x%08x\n", Status); TerminateProcess(lpProcessInformation->hProcess, Status); SetLastError(RtlNtStatusToDosError(Status)); return FALSE; } /* Resume the main thread */ if (!(dwCreationFlags & CREATE_SUSPENDED)) { ResumeThread(lpProcessInformation->hThread); } return TRUE; }
/* * @implemented */ BOOL WINAPI SetPriorityClass(HANDLE hProcess, DWORD dwPriorityClass) { NTSTATUS Status; PROCESS_PRIORITY_CLASS PriorityClass; switch (dwPriorityClass) { case IDLE_PRIORITY_CLASS: PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_IDLE; break; case BELOW_NORMAL_PRIORITY_CLASS: PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL; break; case NORMAL_PRIORITY_CLASS: PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL; break; case ABOVE_NORMAL_PRIORITY_CLASS: PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL; break; case HIGH_PRIORITY_CLASS: PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; break; case REALTIME_PRIORITY_CLASS: PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME; break; default: SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } PriorityClass.Foreground = FALSE; Status = NtSetInformationProcess(hProcess, ProcessPriorityClass, &PriorityClass, sizeof(PROCESS_PRIORITY_CLASS)); if (!NT_SUCCESS(Status)) { SetLastErrorByStatus(Status); return FALSE; } return TRUE; }
/*++ * @name CsrSetToNormalPriority * * The CsrSetToNormalPriority routine sets the current NT Process' * priority to the normal priority for CSR Processes. * * @param None. * * @return None. * * @remarks The "Normal" Priority corresponds to the Normal Foreground * Priority (9) plus a boost of 4. * *--*/ VOID NTAPI CsrSetToNormalPriority(VOID) { KPRIORITY BasePriority = (8 + 1) + 4; /* Set the Priority */ NtSetInformationProcess(NtCurrentProcess(), ProcessBasePriority, &BasePriority, sizeof(BasePriority)); }
VOID NTAPI CsrpSetDefaultProcessHardErrorMode(VOID) { ULONG DefaultHardErrorMode = 0; /* Disable hard errors */ NtSetInformationProcess(NtCurrentProcess(), ProcessDefaultHardErrorMode, &DefaultHardErrorMode, sizeof(DefaultHardErrorMode)); }
/*++ * @name CsrSetForegroundPriority * @implemented NT4 * * The CsrSetForegroundPriority routine sets the priority for the given CSR * Process as a Foreground priority. * * @param CsrProcess * Pointer to the CSR Process whose priority will be modified. * * @return None. * * @remarks None. * *--*/ VOID NTAPI CsrSetForegroundPriority(IN PCSR_PROCESS CsrProcess) { PROCESS_FOREGROUND_BACKGROUND ProcessPriority; /* Set the Foreground bit on */ ProcessPriority.Foreground = TRUE; /* Set the new priority */ NtSetInformationProcess(CsrProcess->ProcessHandle, ProcessForegroundInformation, &ProcessPriority, sizeof(ProcessPriority)); }
/* * @implemented */ BOOL WINAPI SetProcessAffinityMask(HANDLE hProcess, DWORD_PTR dwProcessAffinityMask) { NTSTATUS Status; Status = NtSetInformationProcess(hProcess, ProcessAffinityMask, (PVOID)&dwProcessAffinityMask, sizeof(DWORD)); if (!NT_SUCCESS(Status)) { SetLastErrorByStatus(Status); return FALSE; } return TRUE; }
/* * @implemented */ BOOL WINAPI SetProcessPriorityBoost(HANDLE hProcess, BOOL bDisablePriorityBoost) { NTSTATUS Status; ULONG PriorityBoost = (bDisablePriorityBoost ? TRUE : FALSE); /* prevent setting values other than 1 and 0 */ Status = NtSetInformationProcess(hProcess, ProcessPriorityBoost, &PriorityBoost, sizeof(ULONG)); if (!NT_SUCCESS(Status)) { SetLastErrorByStatus(Status); return FALSE; } return TRUE; }
/*++ * @name CsrSetToShutdownPriority * * The CsrSetToShutdownPriority routine sets the current NT Process' * priority to the boosted priority for CSR Processes doing shutdown. * Additonally, it acquires the Shutdown Privilege required for shutdown. * * @param None. * * @return None. * * @remarks The "Shutdown" Priority corresponds to the Normal Foreground * Priority (9) plus a boost of 6. * *--*/ VOID NTAPI CsrSetToShutdownPriority(VOID) { KPRIORITY BasePriority = (8 + 1) + 6; BOOLEAN Old; /* Get the shutdown privilege */ if (NT_SUCCESS(RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &Old))) { /* Set the Priority */ NtSetInformationProcess(NtCurrentProcess(), ProcessBasePriority, &BasePriority, sizeof(BasePriority)); } }
NTSYSAPI NTSTATUS STDAPIVCALLTYPE RtlSetProcessIsCritical( IN BOOLEAN NewValue, OUT PBOOLEAN OldValue OPTIONAL, IN BOOLEAN CheckFlag ) { PPEB Peb; ULONG Enable; NTSTATUS Status; if ( ARGUMENT_PRESENT(OldValue) ) { *OldValue = FALSE; } Peb = RtlGetCurrentPeb(); if ( CheckFlag && ! (Peb->NtGlobalFlag & FLG_ENABLE_SYSTEM_CRIT_BREAKS) ) { return STATUS_UNSUCCESSFUL; } if ( ARGUMENT_PRESENT(OldValue) ) { NtQueryInformationProcess(NtCurrentProcess(), ProcessBreakOnTermination, &Enable, sizeof(Enable), NULL); *OldValue = (BOOLEAN) Enable; } Enable = NewValue; Status = NtSetInformationProcess(NtCurrentProcess(), ProcessBreakOnTermination, &Enable, sizeof(Enable)); return Status; }
NTSTATUS NTAPI SmpSetProcessMuSessionId(IN HANDLE ProcessHandle, IN ULONG SessionId) { NTSTATUS Status; /* Tell the kernel about the session ID */ Status = NtSetInformationProcess(ProcessHandle, ProcessSessionInformation, &SessionId, sizeof(SessionId)); if (!NT_SUCCESS(Status)) { DPRINT1("SMSS: SetProcessMuSessionId, Process=%p, Status=%x\n", ProcessHandle, Status); } /* Return */ return Status; }
/* * @implemented */ BOOL WINAPI SetProcessWorkingSetSize(HANDLE hProcess, SIZE_T dwMinimumWorkingSetSize, SIZE_T dwMaximumWorkingSetSize) { QUOTA_LIMITS QuotaLimits; NTSTATUS Status; QuotaLimits.MinimumWorkingSetSize = dwMinimumWorkingSetSize; QuotaLimits.MaximumWorkingSetSize = dwMaximumWorkingSetSize; Status = NtSetInformationProcess(hProcess, ProcessQuotaLimits, &QuotaLimits, sizeof(QUOTA_LIMITS)); if (!NT_SUCCESS(Status)) { SetLastErrorByStatus(Status); return FALSE; } return TRUE; }
/*++ * @name CsrSbCreateSession * * The CsrSbCreateSession API is called by the Session Manager whenever a new * session is created. * * @param ApiMessage * Pointer to the Session Manager API Message. * * @return TRUE in case of success, FALSE otherwise. * * @remarks The CsrSbCreateSession routine will initialize a new CSR NT * Session and allocate a new CSR Process for the subsystem process. * *--*/ BOOLEAN NTAPI CsrSbCreateSession(IN PSB_API_MSG ApiMessage) { PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession; HANDLE hProcess, hThread; PCSR_PROCESS CsrProcess; NTSTATUS Status; KERNEL_USER_TIMES KernelTimes; PCSR_THREAD CsrThread; //PVOID ProcessData; //ULONG i; /* Save the Process and Thread Handles */ hProcess = CreateSession->ProcessInfo.ProcessHandle; hThread = CreateSession->ProcessInfo.ThreadHandle; /* Lock the Processes */ CsrAcquireProcessLock(); /* Allocate a new process */ CsrProcess = CsrAllocateProcess(); if (!CsrProcess) { /* Fail */ ApiMessage->ReturnValue = STATUS_NO_MEMORY; CsrReleaseProcessLock(); return TRUE; } /* Set the exception port */ Status = NtSetInformationProcess(hProcess, ProcessExceptionPort, &CsrApiPort, sizeof(HANDLE)); /* Check for success */ if (!NT_SUCCESS(Status)) { /* Fail the request */ CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); /* Strange as it seems, NTSTATUSes are actually returned */ return (BOOLEAN)STATUS_NO_MEMORY; } /* Get the Create Time */ Status = NtQueryInformationThread(hThread, ThreadTimes, &KernelTimes, sizeof(KERNEL_USER_TIMES), NULL); /* Check for success */ if (!NT_SUCCESS(Status)) { /* Fail the request */ CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); /* Strange as it seems, NTSTATUSes are actually returned */ return (BOOLEAN)Status; } /* Allocate a new Thread */ CsrThread = CsrAllocateThread(CsrProcess); if (!CsrThread) { /* Fail the request */ CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); ApiMessage->ReturnValue = STATUS_NO_MEMORY; return TRUE; } /* Setup the Thread Object */ CsrThread->CreateTime = KernelTimes.CreateTime; CsrThread->ClientId = CreateSession->ProcessInfo.ClientId; CsrThread->ThreadHandle = hThread; ProtectHandle(hThread); CsrThread->Flags = 0; /* Insert it into the Process List */ CsrInsertThread(CsrProcess, CsrThread); /* Setup Process Data */ CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId; CsrProcess->ProcessHandle = hProcess; CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId); /* Set the Process Priority */ CsrSetBackgroundPriority(CsrProcess); #if 0 /* Get the first data location */ ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX]; /* Loop every DLL */ for (i = 0; i < CSR_SERVER_DLL_MAX; i++) { /* Check if the DLL is loaded and has Process Data */ if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData) { /* Write the pointer to the data */ CsrProcess->ServerData[i] = ProcessData; /* Move to the next data location */ ProcessData = (PVOID)((ULONG_PTR)ProcessData + CsrLoadedServerDll[i]->SizeOfProcessData); } else { /* Nothing for this Process */ CsrProcess->ServerData[i] = NULL; } } #else /* HACKZ: should go in BaseSrv part of CreateCallback done in Insert below */ RtlInitializeCriticalSection(&CsrProcess->HandleTableLock); #endif /* Insert the Process */ CsrInsertProcess(NULL, NULL, CsrProcess); /* Activate the Thread */ ApiMessage->ReturnValue = NtResumeThread(hThread, NULL); /* Release lock and return */ CsrReleaseProcessLock(); return TRUE; }
INT WINAPI wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR lpCmdLine, _In_ INT nCmdShow ) { LONG result; #ifdef DEBUG PHP_BASE_THREAD_DBG dbg; #endif CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); #ifndef DEBUG SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); #endif PhInstanceHandle = (HINSTANCE)NtCurrentPeb()->ImageBaseAddress; if (!NT_SUCCESS(PhInitializePhLib())) return 1; if (!PhInitializeAppSystem()) return 1; PhInitializeCommonControls(); if (PhCurrentTokenQueryHandle) { PTOKEN_USER tokenUser; if (NT_SUCCESS(PhGetTokenUser(PhCurrentTokenQueryHandle, &tokenUser))) { PhCurrentUserName = PhGetSidFullName(tokenUser->User.Sid, TRUE, NULL); PhFree(tokenUser); } } PhLocalSystemName = PhGetSidFullName(&PhSeLocalSystemSid, TRUE, NULL); // There has been a report of the above call failing. if (!PhLocalSystemName) PhLocalSystemName = PhCreateString(L"NT AUTHORITY\\SYSTEM"); PhApplicationFileName = PhGetApplicationFileName(); PhApplicationDirectory = PhGetApplicationDirectory(); // Just in case if (!PhApplicationFileName) PhApplicationFileName = PhCreateString(L"ProcessHacker.exe"); if (!PhApplicationDirectory) PhApplicationDirectory = PhReferenceEmptyString(); PhpProcessStartupParameters(); PhSettingsInitialization(); PhpEnablePrivileges(); if (PhStartupParameters.RunAsServiceMode) { RtlExitUserProcess(PhRunAsServiceStart(PhStartupParameters.RunAsServiceMode)); } PhpInitializeSettings(); // Activate a previous instance if required. if (PhGetIntegerSetting(L"AllowOnlyOneInstance") && !PhStartupParameters.NewInstance && !PhStartupParameters.ShowOptions && !PhStartupParameters.CommandMode && !PhStartupParameters.PhSvc) { PhActivatePreviousInstance(); } if (PhGetIntegerSetting(L"EnableKph") && !PhStartupParameters.NoKph && !PhIsExecutingInWow64()) PhInitializeKph(); if (PhStartupParameters.CommandMode && PhStartupParameters.CommandType && PhStartupParameters.CommandAction) { NTSTATUS status; status = PhCommandModeStart(); if (!NT_SUCCESS(status) && !PhStartupParameters.Silent) { PhShowStatus(NULL, L"Unable to execute the command", status, 0); } RtlExitUserProcess(status); } #ifdef DEBUG dbg.ClientId = NtCurrentTeb()->ClientId; dbg.StartAddress = wWinMain; dbg.Parameter = NULL; InsertTailList(&PhDbgThreadListHead, &dbg.ListEntry); TlsSetValue(PhDbgThreadDbgTlsIndex, &dbg); #endif PhInitializeAutoPool(&BaseAutoPool); PhEmInitialization(); PhGuiSupportInitialization(); PhTreeNewInitialization(); PhGraphControlInitialization(); PhHexEditInitialization(); PhColorBoxInitialization(); PhSmallIconSize.X = GetSystemMetrics(SM_CXSMICON); PhSmallIconSize.Y = GetSystemMetrics(SM_CYSMICON); PhLargeIconSize.X = GetSystemMetrics(SM_CXICON); PhLargeIconSize.Y = GetSystemMetrics(SM_CYICON); if (PhStartupParameters.ShowOptions) { // Elevated options dialog for changing the value of Replace Task Manager with Process Hacker. PhShowOptionsDialog(PhStartupParameters.WindowHandle); RtlExitUserProcess(STATUS_SUCCESS); } #ifndef DEBUG if (PhIsExecutingInWow64() && !PhStartupParameters.PhSvc) { PhShowWarning( NULL, L"You are attempting to run the 32-bit version of Process Hacker on 64-bit Windows. " L"Most features will not work correctly.\n\n" L"Please run the 64-bit version of Process Hacker instead." ); } #endif PhPluginsEnabled = PhGetIntegerSetting(L"EnablePlugins") && !PhStartupParameters.NoPlugins; if (PhPluginsEnabled) { PhPluginsInitialization(); PhLoadPlugins(); } if (PhStartupParameters.PhSvc) { MSG message; // Turn the feedback cursor off. PostMessage(NULL, WM_NULL, 0, 0); GetMessage(&message, NULL, 0, 0); RtlExitUserProcess(PhSvcMain(NULL, NULL, NULL)); } // Create a mutant for the installer. { HANDLE mutantHandle; OBJECT_ATTRIBUTES oa; UNICODE_STRING mutantName; RtlInitUnicodeString(&mutantName, L"\\BaseNamedObjects\\ProcessHacker2Mutant"); InitializeObjectAttributes( &oa, &mutantName, 0, NULL, NULL ); NtCreateMutant(&mutantHandle, MUTANT_ALL_ACCESS, &oa, FALSE); } // Set priority. { PROCESS_PRIORITY_CLASS priorityClass; priorityClass.Foreground = FALSE; priorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; if (PhStartupParameters.PriorityClass != 0) priorityClass.PriorityClass = (UCHAR)PhStartupParameters.PriorityClass; NtSetInformationProcess(NtCurrentProcess(), ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS)); } if (!PhMainWndInitialization(nCmdShow)) { PhShowError(NULL, L"Unable to initialize the main window."); return 1; } PhDrainAutoPool(&BaseAutoPool); result = PhMainMessageLoop(); RtlExitUserProcess(result); }
NTSTATUS PhCommandModeStart( VOID ) { static PH_COMMAND_LINE_OPTION options[] = { { PH_COMMAND_OPTION_HWND, L"hwnd", MandatoryArgumentType } }; NTSTATUS status; PPH_STRING commandLine; if (!NT_SUCCESS(status = PhGetProcessCommandLine(NtCurrentProcess(), &commandLine))) return status; PhParseCommandLine( &commandLine->sr, options, sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION), PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS, PhpCommandModeOptionCallback, NULL ); PhDereferenceObject(commandLine); if (PhEqualString2(PhStartupParameters.CommandType, L"process", TRUE)) { SIZE_T i; SIZE_T processIdLength; HANDLE processId; HANDLE processHandle; if (!PhStartupParameters.CommandObject) return STATUS_INVALID_PARAMETER; processIdLength = PhStartupParameters.CommandObject->Length / 2; for (i = 0; i < processIdLength; i++) { if (!PhIsDigitCharacter(PhStartupParameters.CommandObject->Buffer[i])) break; } if (i == processIdLength) { ULONG64 processId64; if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &processId64)) return STATUS_INVALID_PARAMETER; processId = (HANDLE)processId64; } else { PVOID processes; PSYSTEM_PROCESS_INFORMATION process; if (!NT_SUCCESS(status = PhEnumProcesses(&processes))) return status; if (!(process = PhFindProcessInformationByImageName(processes, &PhStartupParameters.CommandObject->sr))) { PhFree(processes); return STATUS_NOT_FOUND; } processId = process->UniqueProcessId; PhFree(processes); } if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE)) { if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_TERMINATE, processId))) { status = NtTerminateProcess(processHandle, STATUS_SUCCESS); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE)) { if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId))) { status = NtSuspendProcess(processHandle); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE)) { if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId))) { status = NtResumeProcess(processHandle); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"priority", TRUE)) { UCHAR priority; if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (PhEqualString2(PhStartupParameters.CommandValue, L"idle", TRUE)) priority = PROCESS_PRIORITY_CLASS_IDLE; else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE)) priority = PROCESS_PRIORITY_CLASS_NORMAL; else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE)) priority = PROCESS_PRIORITY_CLASS_HIGH; else if (PhEqualString2(PhStartupParameters.CommandValue, L"realtime", TRUE)) priority = PROCESS_PRIORITY_CLASS_REALTIME; else if (PhEqualString2(PhStartupParameters.CommandValue, L"abovenormal", TRUE)) priority = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL; else if (PhEqualString2(PhStartupParameters.CommandValue, L"belownormal", TRUE)) priority = PROCESS_PRIORITY_CLASS_BELOW_NORMAL; else return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId))) { PROCESS_PRIORITY_CLASS priorityClass; priorityClass.Foreground = FALSE; priorityClass.PriorityClass = priority; status = NtSetInformationProcess(processHandle, ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS)); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"iopriority", TRUE)) { ULONG ioPriority; if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (PhEqualString2(PhStartupParameters.CommandValue, L"verylow", TRUE)) ioPriority = 0; else if (PhEqualString2(PhStartupParameters.CommandValue, L"low", TRUE)) ioPriority = 1; else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE)) ioPriority = 2; else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE)) ioPriority = 3; else return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId))) { status = PhSetProcessIoPriority(processHandle, ioPriority); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"pagepriority", TRUE)) { ULONG64 pagePriority64; ULONG pagePriority; if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; PhStringToInteger64(&PhStartupParameters.CommandValue->sr, 10, &pagePriority64); pagePriority = (ULONG)pagePriority64; if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId))) { status = NtSetInformationProcess( processHandle, ProcessPagePriority, &pagePriority, sizeof(ULONG) ); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"injectdll", TRUE)) { if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic( &processHandle, ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, processId ))) { LARGE_INTEGER timeout; timeout.QuadPart = -5 * PH_TIMEOUT_SEC; status = PhInjectDllProcess( processHandle, PhStartupParameters.CommandValue->Buffer, &timeout ); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"unloaddll", TRUE)) { if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic( &processHandle, ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, processId ))) { PVOID baseAddress; if (NT_SUCCESS(status = PhpGetDllBaseRemote( processHandle, &PhStartupParameters.CommandValue->sr, &baseAddress ))) { LARGE_INTEGER timeout; timeout.QuadPart = -5 * PH_TIMEOUT_SEC; status = PhUnloadDllProcess( processHandle, baseAddress, &timeout ); } NtClose(processHandle); } } } else if (PhEqualString2(PhStartupParameters.CommandType, L"service", TRUE)) { SC_HANDLE serviceHandle; SERVICE_STATUS serviceStatus; if (!PhStartupParameters.CommandObject) return STATUS_INVALID_PARAMETER; if (PhEqualString2(PhStartupParameters.CommandAction, L"start", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_START ))) return PhGetLastWin32ErrorAsNtStatus(); if (!StartService(serviceHandle, 0, NULL)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"continue", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_PAUSE_CONTINUE ))) return PhGetLastWin32ErrorAsNtStatus(); if (!ControlService(serviceHandle, SERVICE_CONTROL_CONTINUE, &serviceStatus)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"pause", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_PAUSE_CONTINUE ))) return PhGetLastWin32ErrorAsNtStatus(); if (!ControlService(serviceHandle, SERVICE_CONTROL_PAUSE, &serviceStatus)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"stop", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_STOP ))) return PhGetLastWin32ErrorAsNtStatus(); if (!ControlService(serviceHandle, SERVICE_CONTROL_STOP, &serviceStatus)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"delete", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, DELETE ))) return PhGetLastWin32ErrorAsNtStatus(); if (!DeleteService(serviceHandle)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } } else if (PhEqualString2(PhStartupParameters.CommandType, L"thread", TRUE)) { ULONG64 threadId64; HANDLE threadId; HANDLE threadHandle; if (!PhStartupParameters.CommandObject) return STATUS_INVALID_PARAMETER; if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &threadId64)) return STATUS_INVALID_PARAMETER; threadId = (HANDLE)threadId64; if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE)) { if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_TERMINATE, threadId))) { status = NtTerminateThread(threadHandle, STATUS_SUCCESS); NtClose(threadHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE)) { if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId))) { status = NtSuspendThread(threadHandle, NULL); NtClose(threadHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE)) { if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId))) { status = NtResumeThread(threadHandle, NULL); NtClose(threadHandle); } } } return status; }
NTSTATUS NTAPI SmpSbCreateSession(IN PVOID Reserved, IN PSMP_SUBSYSTEM OtherSubsystem, IN PRTL_USER_PROCESS_INFORMATION ProcessInformation, IN ULONG MuSessionId, IN PCLIENT_ID DbgClientId) { NTSTATUS Status; PSMP_SUBSYSTEM KnownSubsys; SB_API_MSG SbApiMsg; ULONG SessionId; PSB_CREATE_SESSION_MSG CreateSessionMsg; /* Write out the create session message including its initial process */ CreateSessionMsg = &SbApiMsg.CreateSession; CreateSessionMsg->ProcessInfo = *ProcessInformation; CreateSessionMsg->MuSessionId = MuSessionId; if (DbgClientId) { CreateSessionMsg->ClientId = *DbgClientId; } else { CreateSessionMsg->ClientId.UniqueThread = NULL; CreateSessionMsg->ClientId.UniqueProcess = NULL; } /* Find a subsystem responsible for this session */ SmpGetProcessMuSessionId(ProcessInformation->ProcessHandle, &MuSessionId); if (!SmpCheckDuplicateMuSessionId(MuSessionId)) { NtClose(ProcessInformation->ProcessHandle); NtClose(ProcessInformation->ThreadHandle); DPRINT1("SMSS: CreateSession status=%x\n", STATUS_OBJECT_NAME_NOT_FOUND); return STATUS_OBJECT_NAME_NOT_FOUND; } /* Find the subsystem we have for this initial process */ KnownSubsys = SmpLocateKnownSubSysByType(MuSessionId, ProcessInformation-> ImageInformation.SubSystemType); if (KnownSubsys) { /* Duplicate the process handle into the message */ Status = NtDuplicateObject(NtCurrentProcess(), ProcessInformation->ProcessHandle, KnownSubsys->ProcessHandle, &CreateSessionMsg->ProcessInfo.ProcessHandle, PROCESS_ALL_ACCESS, 0, 0); if (NT_SUCCESS(Status)) { /* Duplicate the thread handle into the message */ Status = NtDuplicateObject(NtCurrentProcess(), ProcessInformation->ThreadHandle, KnownSubsys->ProcessHandle, &CreateSessionMsg->ProcessInfo.ThreadHandle, THREAD_ALL_ACCESS, 0, 0); if (!NT_SUCCESS(Status)) { /* Close everything on failure */ NtClose(ProcessInformation->ProcessHandle); NtClose(ProcessInformation->ThreadHandle); SmpDereferenceSubsystem(KnownSubsys); DbgPrint("SmpSbCreateSession: NtDuplicateObject (Thread) Failed %lx\n", Status); return Status; } /* Close the original handles as they are no longer needed */ NtClose(ProcessInformation->ProcessHandle); NtClose(ProcessInformation->ThreadHandle); /* Finally, allocate a new SMSS session ID for this session */ SessionId = SmpAllocateSessionId(KnownSubsys, OtherSubsystem); CreateSessionMsg->SessionId = SessionId; /* Fill out the LPC message header and send it to the client! */ SbApiMsg.ApiNumber = SbpCreateSession; SbApiMsg.h.u2.ZeroInit = 0; SbApiMsg.h.u1.s1.DataLength = sizeof(SB_CREATE_SESSION_MSG) + 8; SbApiMsg.h.u1.s1.TotalLength = sizeof(SbApiMsg); Status = NtRequestWaitReplyPort(KnownSubsys->SbApiPort, &SbApiMsg.h, &SbApiMsg.h); if (!NT_SUCCESS(Status)) { /* Bail out */ DPRINT1("SmpSbCreateSession: NtRequestWaitReply Failed %lx\n", Status); } else { /* If the API succeeded, get the result value from the LPC */ Status = SbApiMsg.ReturnValue; } /* Delete the session on any kind of failure */ if (!NT_SUCCESS(Status)) SmpDeleteSession(SessionId); } else { /* Close the handles on failure */ DPRINT1("SmpSbCreateSession: NtDuplicateObject (Process) Failed %lx\n", Status); NtClose(ProcessInformation->ProcessHandle); NtClose(ProcessInformation->ThreadHandle); } /* Dereference the subsystem and return the status of the LPC call */ SmpDereferenceSubsystem(KnownSubsys); return Status; } /* If we don't yet have a subsystem, only native images can be launched */ if (ProcessInformation->ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_NATIVE) { /* Fail */ DPRINT1("SMSS: %s SubSystem has not been started.\n", SmpSubSystemNames[ProcessInformation->ImageInformation.SubSystemType]); Status = STATUS_UNSUCCESSFUL; NtClose(ProcessInformation->ProcessHandle); NtClose(ProcessInformation->ThreadHandle); return Status; } #if 0 /* This code handles debug applications, but it seems vestigial... */ if ((*(ULONGLONG)&CreateSessionMsg.ClientId) && (SmpDbgSsLoaded)) { Process = RtlAllocateHeap(SmpHeap, SmBaseTag, sizeof(SMP_PROCESS)); if (!Process) { DPRINT1("Unable to initialize debugging for Native App %lx.%lx -- out of memory\n", ProcessInformation->ClientId.UniqueProcess, ProcessInformation->ClientId.UniqueThread); NtClose(ProcessInformation->ProcessHandle); NtClose(ProcessInformation->ThreadHandle); return STATUS_NO_MEMORY; } Process->DbgClientId = CreateSessionMsg->ClientId; Process->ClientId = ProcessInformation->ClientId; InsertHeadList(&NativeProcessList, &Process->Entry); DPRINT1("Native Debug App %lx.%lx\n", Process->ClientId.UniqueProcess, Process->ClientId.UniqueThread); Status = NtSetInformationProcess(ProcessInformation->ProcessHandle, 7, &SmpDebugPort, 4); ASSERT(NT_SUCCESS(Status)); } #endif /* This is a native application being started as the initial command */ DPRINT1("Subsystem active, starting thread\n"); NtClose(ProcessInformation->ProcessHandle); NtResumeThread(ProcessInformation->ThreadHandle, NULL); NtClose(ProcessInformation->ThreadHandle); return STATUS_SUCCESS; }
/*++ * @name CsrCreateProcess * @implemented NT4 * * The CsrCreateProcess routine creates a CSR Process object for an NT Process. * * @param hProcess * Handle to an existing NT Process to which to associate this * CSR Process. * * @param hThread * Handle to an existing NT Thread to which to create its * corresponding CSR Thread for this CSR Process. * * @param ClientId * Pointer to the Client ID structure of the NT Process to associate * with this CSR Process. * * @param NtSession * @param Flags * @param DebugCid * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise. * * @remarks None. * *--*/ NTSTATUS NTAPI CsrCreateProcess(IN HANDLE hProcess, IN HANDLE hThread, IN PCLIENT_ID ClientId, IN PCSR_NT_SESSION NtSession, IN ULONG Flags, IN PCLIENT_ID DebugCid) { PCSR_THREAD CurrentThread = CsrGetClientThread(); CLIENT_ID CurrentCid; PCSR_PROCESS CurrentProcess; PCSR_SERVER_DLL ServerDll; PVOID ProcessData; ULONG i; PCSR_PROCESS CsrProcess; NTSTATUS Status; PCSR_THREAD CsrThread; KERNEL_USER_TIMES KernelTimes; /* Get the current CID and lock Processes */ CurrentCid = CurrentThread->ClientId; CsrAcquireProcessLock(); /* Get the current CSR Thread */ CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid); if (!CurrentThread) { /* We've failed to locate the thread */ CsrReleaseProcessLock(); return STATUS_THREAD_IS_TERMINATING; } /* Allocate a new Process Object */ CsrProcess = CsrAllocateProcess(); if (!CsrProcess) { /* Couldn't allocate Process */ CsrReleaseProcessLock(); return STATUS_NO_MEMORY; } /* Inherit the Process Data */ CurrentProcess = CurrentThread->Process; ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX]; for (i = 0; i < CSR_SERVER_DLL_MAX; i++) { /* Get the current Server */ ServerDll = CsrLoadedServerDll[i]; /* Check if the DLL is Loaded and has Per Process Data */ if (ServerDll && ServerDll->SizeOfProcessData) { /* Set the pointer */ CsrProcess->ServerData[i] = ProcessData; /* Copy the Data */ RtlMoveMemory(ProcessData, CurrentProcess->ServerData[i], ServerDll->SizeOfProcessData); /* Update next data pointer */ ProcessData = (PVOID)((ULONG_PTR)ProcessData + ServerDll->SizeOfProcessData); } else { /* No data for this Server */ CsrProcess->ServerData[i] = NULL; } } /* Set the Exception Port for us */ Status = NtSetInformationProcess(hProcess, ProcessExceptionPort, &CsrApiPort, sizeof(CsrApiPort)); if (!NT_SUCCESS(Status)) { /* Failed */ CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); return STATUS_NO_MEMORY; } /* Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */ if (Flags & CsrProcessCreateNewGroup) { /* * We create the process group leader of a new process group, therefore * its process group ID and sequence number are its own ones. */ CsrProcess->ProcessGroupId = HandleToUlong(ClientId->UniqueProcess); CsrProcess->ProcessGroupSequence = CsrProcess->SequenceNumber; } else { /* Inherit the process group ID and sequence number from the current process */ CsrProcess->ProcessGroupId = CurrentProcess->ProcessGroupId; CsrProcess->ProcessGroupSequence = CurrentProcess->ProcessGroupSequence; } /* Check if this is a console process */ if (Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp; /* Mask out non-debug flags */ Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup | CsrProcessPriorityFlags); /* Check if every process will be debugged */ if (!(Flags) && (CurrentProcess->DebugFlags & CsrDebugProcessChildren)) { /* Pass it on to the current process */ CsrProcess->DebugFlags = CsrDebugProcessChildren; CsrProcess->DebugCid = CurrentProcess->DebugCid; } /* Check if Debugging was used on this process */ if ((Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren)) && (DebugCid)) { /* Save the debug flag used */ CsrProcess->DebugFlags = Flags; /* Save the CID */ CsrProcess->DebugCid = *DebugCid; } /* Check if Debugging is enabled */ if (CsrProcess->DebugFlags) { /* Set the Debug Port for us */ Status = NtSetInformationProcess(hProcess, ProcessDebugPort, &CsrApiPort, sizeof(CsrApiPort)); ASSERT(NT_SUCCESS(Status)); if (!NT_SUCCESS(Status)) { /* Failed */ CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); return STATUS_NO_MEMORY; } } /* Get the Thread Create Time */ Status = NtQueryInformationThread(hThread, ThreadTimes, &KernelTimes, sizeof(KernelTimes), NULL); if (!NT_SUCCESS(Status)) { /* Failed */ CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); return STATUS_NO_MEMORY; } /* Allocate a CSR Thread Structure */ CsrThread = CsrAllocateThread(CsrProcess); if (!CsrThread) { /* Failed */ CsrDeallocateProcess(CsrProcess); CsrReleaseProcessLock(); return STATUS_NO_MEMORY; } /* Save the data we have */ CsrThread->CreateTime = KernelTimes.CreateTime; CsrThread->ClientId = *ClientId; CsrThread->ThreadHandle = hThread; ProtectHandle(hThread); CsrThread->Flags = 0; /* Insert the Thread into the Process */ Status = CsrInsertThread(CsrProcess, CsrThread); if (!NT_SUCCESS(Status)) { /* Bail out */ CsrDeallocateProcess(CsrProcess); CsrDeallocateThread(CsrThread); CsrReleaseProcessLock(); return Status; } /* Reference the session */ CsrReferenceNtSession(NtSession); CsrProcess->NtSession = NtSession; /* Setup Process Data */ CsrProcess->ClientId = *ClientId; CsrProcess->ProcessHandle = hProcess; CsrProcess->ShutdownLevel = 0x280; /* Set the Priority to Background */ CsrSetBackgroundPriority(CsrProcess); /* Insert the Process */ CsrInsertProcess(CurrentProcess, CsrProcess); /* Release lock and return */ CsrReleaseProcessLock(); return Status; }
INT_PTR CALLBACK EtpWsWatchDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PWS_WATCH_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = (PWS_WATCH_CONTEXT)lParam; SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PWS_WATCH_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { HWND lvHandle; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); context->WindowHandle = hwndDlg; context->ListViewHandle = lvHandle = GetDlgItem(hwndDlg, IDC_LIST); PhSetListViewStyle(lvHandle, FALSE, TRUE); PhSetControlTheme(lvHandle, L"explorer"); PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 340, L"Instruction"); PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 80, L"Count"); PhSetExtendedListView(lvHandle); ExtendedListView_SetSort(lvHandle, 1, DescendingSortOrder); context->Hashtable = PhCreateSimpleHashtable(64); context->BufferSize = 0x2000; context->Buffer = PhAllocate(context->BufferSize); PhInitializeQueuedLock(&context->ResultListLock); context->SymbolProvider = PhCreateSymbolProvider(context->ProcessItem->ProcessId); PhLoadSymbolProviderOptions(context->SymbolProvider); if (!context->SymbolProvider || !context->SymbolProvider->IsRealHandle) { PhShowError(hwndDlg, L"Unable to open the process."); EndDialog(hwndDlg, IDCANCEL); break; } context->ProcessHandle = context->SymbolProvider->ProcessHandle; // Load symbols for both process and kernel modules. context->LoadingSymbolsForProcessId = context->ProcessItem->ProcessId; PhEnumGenericModules( NULL, context->ProcessHandle, 0, EnumGenericModulesCallback, context ); context->LoadingSymbolsForProcessId = SYSTEM_PROCESS_ID; PhEnumGenericModules( SYSTEM_PROCESS_ID, NULL, 0, EnumGenericModulesCallback, context ); context->Enabled = EtpUpdateWsWatch(hwndDlg, context); if (context->Enabled) { // WS Watch is already enabled for the process. Enable updating. EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE), FALSE); ShowWindow(GetDlgItem(hwndDlg, IDC_WSWATCHENABLED), SW_SHOW); SetTimer(hwndDlg, 1, 1000, NULL); } else { // WS Watch has not yet been enabled for the process. } } break; case WM_DESTROY: { context->Destroying = TRUE; PhDereferenceObject(context->Hashtable); if (context->Buffer) { PhFree(context->Buffer); context->Buffer = NULL; } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: EndDialog(hwndDlg, IDOK); break; case IDC_ENABLE: { NTSTATUS status; HANDLE processHandle; if (NT_SUCCESS(status = PhOpenProcess( &processHandle, PROCESS_SET_INFORMATION, context->ProcessItem->ProcessId ))) { status = NtSetInformationProcess( processHandle, ProcessWorkingSetWatchEx, NULL, 0 ); NtClose(processHandle); } if (NT_SUCCESS(status)) { EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE), FALSE); ShowWindow(GetDlgItem(hwndDlg, IDC_WSWATCHENABLED), SW_SHOW); SetTimer(hwndDlg, 1, 1000, NULL); } else { PhShowStatus(hwndDlg, L"Unable to enable WS watch", status, 0); } } break; } } break; case WM_NOTIFY: { PhHandleListViewNotifyForCopy(lParam, context->ListViewHandle); } break; case WM_TIMER: { switch (wParam) { case 1: { EtpUpdateWsWatch(hwndDlg, context); } break; } } break; } return FALSE; }
VOID NTAPI MenuItemCallback( _In_opt_ PVOID Parameter, _In_opt_ PVOID Context ) { PPH_PLUGIN_MENU_ITEM menuItem = Parameter; switch (menuItem->Id) { case CRITICAL_MENU_ITEM: { NTSTATUS status; PPH_PROCESS_ITEM processItem = menuItem->Context; HANDLE processHandle; ULONG breakOnTermination; if (NT_SUCCESS(status = PhOpenProcess(&processHandle, PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION, processItem->ProcessId))) { if (NT_SUCCESS(status = NtQueryInformationProcess(processHandle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG), NULL))) { if (!breakOnTermination && PhShowConfirmMessage( menuItem->OwnerWindow, L"enable", L"critical status on the process", L"If the process ends, the operating system will shut down immediately.", TRUE )) { breakOnTermination = TRUE; status = NtSetInformationProcess(processHandle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG)); } else if (breakOnTermination && PhShowConfirmMessage( menuItem->OwnerWindow, L"disable", L"critical status on the process", NULL, FALSE )) { breakOnTermination = FALSE; status = NtSetInformationProcess(processHandle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG)); } if (!NT_SUCCESS(status)) PhShowStatus(menuItem->OwnerWindow, L"Unable to set critical status", status, 0); } else { PhShowStatus(menuItem->OwnerWindow, L"Unable to query critical status", status, 0); } NtClose(processHandle); } else { PhShowStatus(menuItem->OwnerWindow, L"Unable to open the process", status, 0); } } break; } }
VOID ServiceStart ( DWORD dwArgc, LPTSTR *lpszArgv ) /*++ Routine Description: The code that starts everything, is really the main(). Arguments: None. Return Values: None. --*/ { DWORD dwWait; NTSTATUS Status = STATUS_SUCCESS; BOOLEAN EnableAlignmentFaults = TRUE; KPRIORITY BasePriority; /////////////////////////////////////////////////// // // Service initialization // // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // // Create the event object. The control handler function signals // this event when it receives the "stop" control code. // hServerStopEvent = CreateEvent( NULL, // no security attributes TRUE, // manual reset event FALSE, // not-signalled NULL); // no name if ( hServerStopEvent == NULL) goto Cleanup; // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // // Define a top-level exception handler for the entire process. // (VOID) SetErrorMode( SEM_FAILCRITICALERRORS ); (VOID) SetUnhandledExceptionFilter( &LLSTopLevelExceptionHandler ); // // Turn on alignment fault fixups. This is necessary because // several structures stored in the registry have qword aligned // fields. They are nicely aligned in our structures, but they // end up being forced out of alignment when being stored because // the registry api require data to be passed following a wierd // length header. // Status = NtSetInformationProcess( NtCurrentProcess(), ProcessEnableAlignmentFaultFixup, (PVOID) &EnableAlignmentFaults, sizeof(BOOLEAN) ); ASSERT(NT_SUCCESS(Status)); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // // Run the LLS in the foreground. // // Several processes which depend on the LLS (like the lanman server) // run in the foreground. If we don't run in the foreground, they'll // starve waiting for us. // BasePriority = FOREGROUND_BASE_PRIORITY; Status = NtSetInformationProcess( NtCurrentProcess(), ProcessBasePriority, &BasePriority, sizeof(BasePriority) ); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize the Registry values... RegistryInit(); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize the Registry values... ConfigInfoInit(); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize the Service Table LicenseListInit(); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize the Service Table MasterServiceListInit(); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize the Service Table LocalServiceListInit(); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize the Service Table ServiceListInit(); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize the Service Table MappingListInit(); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize the Per-Seat Table UserListInit(); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize the Service Table ServerListInit(); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize the Certificate Database CertDbInit(); // // Report the status to the service control manager - need a bit longer // to read in all the data files. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 15000)) // wait hint goto Cleanup; // Load data files LoadAll(); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize RPC Stuff... LLSRpcInit(); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize Replication... ReplicationInit(); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize scavenger thread... ScavengerInit(); // // Report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000)) // wait hint goto Cleanup; // Initialize RegistryMonitor thread... RegistryStartMonitor(); // // End of initialization // //////////////////////////////////////////////////////// // // Tell SCM we are up and running! // if (!ReportStatusToSCMgr( SERVICE_RUNNING, NO_ERROR, 0)) // wait hint goto Cleanup; //////////////////////////////////////////////////////// // // Service is now running, perform work until shutdown // dwWait = WaitForSingleObject(hServerStopEvent, INFINITE); Cleanup: if (hServerStopEvent) CloseHandle(hServerStopEvent); if (sshStatusHandle) ReportStatusToSCMgr( SERVICE_STOPPED, NO_ERROR, 0); } // ServiceStart
NTSTATUS _main(IN INT argc, IN PCHAR argv[], IN PCHAR envp[], IN ULONG DebugFlag) { NTSTATUS Status; KPRIORITY SetBasePriority; ULONG_PTR Parameters[4]; HANDLE Handles[2]; PVOID State; ULONG Flags; PROCESS_BASIC_INFORMATION ProcessInfo; UNICODE_STRING DbgString, InitialCommand; /* Make us critical */ RtlSetProcessIsCritical(TRUE, NULL, FALSE); RtlSetThreadIsCritical(TRUE, NULL, FALSE); /* Raise our priority */ SetBasePriority = 11; Status = NtSetInformationProcess(NtCurrentProcess(), ProcessBasePriority, (PVOID)&SetBasePriority, sizeof(SetBasePriority)); ASSERT(NT_SUCCESS(Status)); /* Save the debug flag if it was passed */ if (DebugFlag) SmpDebug = DebugFlag != 0; /* Build the hard error parameters */ Parameters[0] = (ULONG_PTR)&DbgString; Parameters[1] = Parameters[2] = Parameters[3] = 0; /* Enter SEH so we can terminate correctly if anything goes wrong */ _SEH2_TRY { /* Initialize SMSS */ Status = SmpInit(&InitialCommand, Handles); if (!NT_SUCCESS(Status)) { DPRINT1("SMSS: SmpInit return failure - Status == %x\n", Status); RtlInitUnicodeString(&DbgString, L"Session Manager Initialization"); Parameters[1] = Status; _SEH2_LEAVE; } /* Get the global flags */ Status = NtQuerySystemInformation(SystemFlagsInformation, &Flags, sizeof(Flags), NULL); ASSERT(NT_SUCCESS(Status)); /* Before executing the initial command check if the debug flag is on */ if (Flags & (FLG_DEBUG_INITIAL_COMMAND | FLG_DEBUG_INITIAL_COMMAND_EX)) { /* SMSS should launch ntsd with a few parameters at this point */ DPRINT1("Global Flags Set to SMSS Debugging: Not yet supported\n"); } /* Execute the initial command (Winlogon.exe) */ Status = SmpExecuteInitialCommand(0, &InitialCommand, &Handles[1], NULL); if (!NT_SUCCESS(Status)) { /* Fail and raise a hard error */ DPRINT1("SMSS: Execute Initial Command failed\n"); RtlInitUnicodeString(&DbgString, L"Session Manager ExecuteInitialCommand"); Parameters[1] = Status; _SEH2_LEAVE; } /* Check if we're already attached to a session */ Status = SmpAcquirePrivilege(SE_LOAD_DRIVER_PRIVILEGE, &State); if (AttachedSessionId != -1) { /* Detach from it, we should be in no session right now */ Status = NtSetSystemInformation(SystemSessionDetach, &AttachedSessionId, sizeof(AttachedSessionId)); ASSERT(NT_SUCCESS(Status)); AttachedSessionId = -1; } SmpReleasePrivilege(State); /* Wait on either CSRSS or Winlogon to die */ Status = NtWaitForMultipleObjects(RTL_NUMBER_OF(Handles), Handles, WaitAny, FALSE, NULL); if (Status == STATUS_WAIT_0) { /* CSRSS is dead, get exit code and prepare for the hard error */ RtlInitUnicodeString(&DbgString, L"Windows SubSystem"); Status = NtQueryInformationProcess(Handles[0], ProcessBasicInformation, &ProcessInfo, sizeof(ProcessInfo), NULL); DPRINT1("SMSS: Windows subsystem terminated when it wasn't supposed to.\n"); } else { /* The initial command is dead or we have another failure */ RtlInitUnicodeString(&DbgString, L"Windows Logon Process"); if (Status == STATUS_WAIT_1) { /* Winlogon.exe got terminated, get its exit code */ Status = NtQueryInformationProcess(Handles[1], ProcessBasicInformation, &ProcessInfo, sizeof(ProcessInfo), NULL); } else { /* Something else satisfied our wait, so set the wait status */ ProcessInfo.ExitStatus = Status; Status = STATUS_SUCCESS; } DPRINT1("SMSS: Initial command '%wZ' terminated when it wasn't supposed to.\n", &InitialCommand); } /* Check if NtQueryInformationProcess was successful */ if (NT_SUCCESS(Status)) { /* Then we must have a valid exit status in the structure, use it */ Parameters[1] = ProcessInfo.ExitStatus; } else { /* We really don't know what happened, so set a generic error */ Parameters[1] = STATUS_UNSUCCESSFUL; } } _SEH2_EXCEPT(SmpUnhandledExceptionFilter(_SEH2_GetExceptionInformation())) { /* The filter should never return here */ ASSERT(FALSE); } _SEH2_END; /* Something in the init loop failed, terminate SMSS */ return SmpTerminate(Parameters, 1, RTL_NUMBER_OF(Parameters)); }
VOID SuspendedProcessTest ( VOID ) { PERFINFO PerfInfo; STARTUPINFO si; PROCESS_INFORMATION pi[SPD_PROCESS_ITERATIONS]; BOOL b; int Index; CHAR Buffer[256]; KPRIORITY Base; GetModuleFileName(0,Buffer,256); RtlZeroMemory(&si,sizeof(si)); si.cb = sizeof(si); Base = 13; NtSetInformationProcess( NtCurrentProcess(), ProcessBasePriority, (PVOID) &Base, sizeof(Base) ); // SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS); StartBenchMark("Suspended Process Creation Benchmark)", SPD_PROCESS_ITERATIONS, &PerfInfo); for (Index = 0; Index < SPD_PROCESS_ITERATIONS; Index += 1) { b = CreateProcess( Buffer, "just exit", NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, &pi[Index] ); if ( !b ) { printf("failed %ld\n",Index); } } // // Print out performance statistics. // FinishBenchMark(&PerfInfo); // SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS); StartBenchMark("Process Startup/Exit Benchmark)", SPD_PROCESS_ITERATIONS, &PerfInfo); for (Index = 0; Index < SPD_PROCESS_ITERATIONS; Index += 1) { ResumeThread(pi[Index].hThread); CloseHandle(pi[Index].hThread); WaitForSingleObject(pi[Index].hProcess,-1); CloseHandle(pi[Index].hProcess); } FinishBenchMark(&PerfInfo); // // End of event1 context switch test. // return; }