static DWORD WINAPI KillComProcesses( LPVOID Parameter) { DWORD ret = 1; PLOGOFF_SHUTDOWN_DATA LSData = (PLOGOFF_SHUTDOWN_DATA)Parameter; TRACE("In KillComProcesses\n"); if (LSData->Session->UserToken != NULL && !ImpersonateLoggedOnUser(LSData->Session->UserToken)) { ERR("ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError()); return 0; } /* Attempt to kill remaining processes. No notifications needed. */ if (!ExitWindowsEx(EWX_CALLER_WINLOGON | EWX_NONOTIFY | EWX_FORCE | EWX_LOGOFF, 0)) { ERR("Unable to kill COM apps, error %lu\n", GetLastError()); ret = 0; } if (LSData->Session->UserToken) RevertToSelf(); return ret; }
void Backup() { HANDLE hSystemToken; //if (GetSystemToken(&hSystemToken)) { if (ImpersonateLoggedOnUser(hSystemToken)) { WINSTATIONUSERTOKEN WinStaUserToken = { 0 }; DWORD ccbInfo = NULL; WinStationQueryInformationW(SERVERNAME_CURRENT, LOGONID_CURRENT, WinStationUserToken, &WinStaUserToken, sizeof(WINSTATIONUSERTOKEN), &ccbInfo); HRESULT hr = GetLastError(); STARTUPINFOW StartupInfo = { 0 }; PROCESS_INFORMATION ProcessInfo = { 0 }; StartupInfo.lpDesktop = L"WinSta0\\Default"; wchar_t szCMDLine[] = L"cmd /c start cmd"; if (CreateProcessAsUserW(WinStaUserToken.UserToken, NULL, szCMDLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo)) { } RevertToSelf(); ReturnMessage(L"OK"); } CloseHandle(hSystemToken); } }
BOOL Cnet_demoApp::InitInstance() { // 如果一个运行在 Windows XP 上的应用程序清单指定要 // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式, //则需要 InitCommonControlsEx()。否则,将无法创建窗口。 INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // 将它设置为包括所有要在应用程序中使用的 // 公共控件类。 InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls); CWinApp::InitInstance(); AfxEnableControlContainer(); // 标准初始化 // 如果未使用这些功能并希望减小 // 最终可执行文件的大小,则应移除下列 // 不需要的特定初始化例程 // 更改用于存储设置的注册表项 // TODO: 应适当修改该字符串, // 例如修改为公司或组织名 SetRegistryKey(_T("应用程序向导生成的本地应用程序")); HANDLE hUser; if(LogonUser ("test",".","test",LOGON32_LOGON_NEW_CREDENTIALS,LOGON32_PROVIDER_DEFAULT,&hUser)){ TRACE("授权1成功"); } if ( 0 == ImpersonateLoggedOnUser(hUser)){ TRACE("授权2不成功"); } //CKaoqing dlg1; CAMainDlg dlg1; Cnet_demoDlg dlg2; INT_PTR nResponse; if (1 || IDOK == AfxMessageBox(_T("选择"),MB_OKCANCEL )){ m_pMainWnd = &dlg1; nResponse = dlg1.DoModal(); } else{ m_pMainWnd = &dlg2; nResponse = dlg2.DoModal(); } if (nResponse == IDOK) { // TODO: 在此放置处理何时用 // “确定”来关闭对话框的代码 } else if (nResponse == IDCANCEL) { // TODO: 在此放置处理何时用 // “取消”来关闭对话框的代码 } // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序, // 而不是启动应用程序的消息泵。 return FALSE; }
BOOL CreateUserEnvironment( IN PWLSESSION Session) { HKEY hKeyCurrentUser; LONG lError; TRACE("WL: CreateUserEnvironment called\n"); /* Impersonate the new user */ ImpersonateLoggedOnUser(Session->UserToken); /* Open the new users HKCU key */ lError = RegOpenCurrentUser(KEY_CREATE_SUB_KEY, &hKeyCurrentUser); if (lError == ERROR_SUCCESS) { BuildVolatileEnvironment(Session, hKeyCurrentUser); RegCloseKey(hKeyCurrentUser); } /* Revert the impersonation */ RevertToSelf(); TRACE("WL: CreateUserEnvironment done\n"); return TRUE; }
bool SecurityHelper::CreateProcessAsUserOnDesktop(HANDLE hToken, wchar_t* programImage, wchar_t* desktop, void* env) { // impersonate the user to ensure that they are allowed // to execute the program in the first place if (!ImpersonateLoggedOnUser(hToken)) { LCF1(L"ImpersonateLoggedOnUser failed: %d", GetLastError()); return false; } STARTUPINFO si = { sizeof si, 0, desktop }; PROCESS_INFORMATION pi; if (!CreateProcessAsUser(hToken, programImage, programImage, 0, 0, FALSE, CREATE_UNICODE_ENVIRONMENT, env, 0, &si, &pi)) { RevertToSelf(); LCF2(L"CreateProcessAsUser failed for image %s with error code %d", programImage, GetLastError()); return false; } CloseHandle(pi.hProcess); CloseHandle(pi.hThread); RevertToSelf(); LDB1(L"Successfully launched %s", programImage); return true; }
int is_writable(bool localsystem, const char *directory) { HANDLE hFile; HANDLE hToken = NULL; if(localsystem) { // Doesn't work... fixme. if(SuidGetImpersonationToken("SYSTEM",NULL,LOGON32_LOGON_INTERACTIVE,&hToken)) { return 2; } if(!ImpersonateLoggedOnUser(hToken)) { CloseHandle(hToken); return 2; } } hFile=CreateFile(directory,GENERIC_WRITE,0,NULL,0,FILE_FLAG_BACKUP_SEMANTICS,NULL); if(hToken) { RevertToSelf(); CloseHandle(hToken); } if(!hFile) return 0; CloseHandle(hFile); return 1; }
gboolean ves_icall_System_Security_Principal_WindowsImpersonationContext_SetCurrentToken (gpointer token) { MONO_ARCH_SAVE_REGS; /* Posix version implemented in /mono/mono/io-layer/security.c */ return (ImpersonateLoggedOnUser (token) != 0); }
AUTHADMIN_API BOOL CUGP(char * userin,char *password,char *machine,char *groupin,int locdom) { DWORD dwLogonType; DWORD dwLogonProvider; HANDLE hToken; bool returnvalue=false; dwLogonType = LOGON32_LOGON_INTERACTIVE; dwLogonProvider = LOGON32_PROVIDER_DEFAULT; byte *buf = 0; byte *buf2 = 0; char domain[MAXLEN * sizeof(wchar_t)]; DWORD rcdomain = NetGetDCName( 0, 0, &buf ); NetApiBufferFree( buf ); printf("Logonuser: % s %s \n", userin, "."); if (LogonUser(userin, ".", password, dwLogonType, dwLogonProvider, &hToken)) if (ImpersonateLoggedOnUser(hToken)) { returnvalue=IsAdmin(); RevertToSelf(); CloseHandle(hToken); } if (returnvalue==true) return returnvalue; if (!rcdomain) { DWORD result=NetWkstaGetInfo( 0 , 100 , &buf2 ) ; if (!result) { wcstombs( domain, ((WKSTA_INFO_100_NT *) buf2)->wki100_langroup, MAXLEN ); NetApiBufferFree( buf2 ); printf("Logonuser: % s %s \n", userin, domain); if (LogonUser(userin, domain, password, dwLogonType, dwLogonProvider, &hToken)) if (ImpersonateLoggedOnUser(hToken)) { returnvalue=IsAdmin(); RevertToSelf(); CloseHandle(hToken); } } } return returnvalue; }
void Impersonator::impersonateAsLoggedUser() { WTS::queryConsoleUserToken(&m_token); if ((!DuplicateToken(m_token, SecurityImpersonation, &m_dupToken)) || (!ImpersonateLoggedOnUser(m_dupToken))) { throw SystemException(); } }
void CUser::Impersonate() { CTrace::CEnter CEnter(CTrace::Layer::KERNEL, L"User::Impersonate()"); BOOL bRet; bRet = ImpersonateLoggedOnUser(GetHandle()); if (bRet == 0) { throw CCodineException(CError::GetErrorMessage(GetLastError()), __FILE__, __LINE__); } }
HANDLE GetLoggedOnUserToken( OUT PWCHAR userName, IN DWORD cchUserName // at least UNLEN WCHARs ) { DWORD consoleSessionId; HANDLE userToken, duplicateToken; DWORD nameSize = UNLEN; consoleSessionId = WTSGetActiveConsoleSessionId(); if (0xFFFFFFFF == consoleSessionId) { LogWarning("no active console session"); return NULL; } if (!WTSQueryUserToken(consoleSessionId, &userToken)) { LogDebug("no user is logged on"); return NULL; } // create a primary token (needed for logon) if (!DuplicateTokenEx( userToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &duplicateToken)) { perror("DuplicateTokenEx"); CloseHandle(userToken); return NULL; } CloseHandle(userToken); if (!ImpersonateLoggedOnUser(duplicateToken)) { perror("ImpersonateLoggedOnUser"); CloseHandle(duplicateToken); return NULL; } if (!GetUserName(userName, &cchUserName)) { perror("GetUserName"); userName[0] = 0; } RevertToSelf(); return duplicateToken; }
int win_switch_user(HANDLE user_token) { if (user_token) { if (!ImpersonateLoggedOnUser(user_token)) { ERR(GetLastError(), "Could not switch error context"); return 0; } } else RevertToSelf(); return 1; }
void unmap_drive() { if (server_user&&drive_maped) { logfile("unmap\r\n"); ImpersonateLoggedOnUser(server_user); int ec=WNetCancelConnection2(maped_drive,CONNECT_UPDATE_PROFILE,true); if (NO_ERROR!=ec) logfile("WNetCancelConnection2 failed %i\r\n",ec); RevertToSelf(); drive_maped=false; } }
/** * @brief * check whether to allow access for users. * * @param[in] rhost - remote hosts * @param[in] superuser - val to indicate whether superuser * @param[in] ruser - remote user * @param[in] luser - local user * * @return int * @retval 0 if access is allowed * @retval -1 if access is denied * @retval -2 if user does not exist * @retval -3 problem reading user's .rhosts file. * * @par Note: * Checks if (ruser,rhost) can access account * luser@LOCALHOST. The hosts.equiv or user's .rhosts is consulted. * */ int ruserok(const char *rhost, int superuser, const char *ruser, const char *luser) { char hosts_equiv[MAXPATHLEN+1]; char rhosts[MAXPATHLEN+1]; struct stat sbuf; int rc = 1; struct passwd *pw; int user_impersonate = 0; char logb[LOG_BUF_SIZE] = {'\0' } ; /* see if local user exists! */ if ((pw = getpwnam((char *)luser)) == NULL) { sprintf(logb,"user %s does not exist!", luser); log_err(-1, "ruserok", logb); return (-2); } /* Let's construct the hosts.equiv file */ sprintf(hosts_equiv, "%s\\system32\\drivers\\etc\\hosts.equiv", get_saved_env("SYSTEMROOT")); if (stat(hosts_equiv, &sbuf) != 0) { sprintf(hosts_equiv, "%s\\hosts.equiv", get_saved_env("SYSTEMROOT")); } /* check hosts.equiv file if luser is not superuser */ if( !superuser && \ chk_file_sec(hosts_equiv, 0, 0, WRITES_MASK, 0) == 0 && \ match_hosts_equiv_entry(hosts_equiv, rhost, ruser, luser) ) return (0); /* check luser's .rhosts file */ /* Let's construct the $HOME/.rhosts file */ /* have to read .rhosts as user */ if (pw->pw_userlogin != INVALID_HANDLE_VALUE) { ImpersonateLoggedOnUser(pw->pw_userlogin); user_impersonate =1; } strcpy(rhosts, getRhostsFile(pw->pw_name, pw->pw_userlogin)); rc = match_rhosts_entry(rhosts, rhost, ruser); if (user_impersonate) RevertToSelf(); if (rc == 1) /* ok */ return (0); else if (rc < 0) /* some error occurred */ return (-3); else /* absolutely no match */ return (-1); }
/* @brief * Impersonate a user, a wrapper to ImpersonateLoggedOnUser() API. * if impersonation fails, sets the errno * * @param[in] hlogintoken : user login * * @return BOOL * @retval whether impersonation succeded, return value of ImpersonateLoggedOnUser() API */ BOOL impersonate_user(HANDLE hlogintoken) { is_user_impersonated = FALSE; if (hlogintoken == NULL || hlogintoken == INVALID_HANDLE_VALUE) return FALSE; is_user_impersonated = ImpersonateLoggedOnUser(hlogintoken); if (is_user_impersonated == FALSE) errno = GetLastError(); return is_user_impersonated; }
MonoBoolean ves_icall_System_Security_Principal_WindowsImpersonationContext_SetCurrentToken (gpointer token, MonoError *error) { #ifdef HOST_WIN32 return (ImpersonateLoggedOnUser (token) != 0); #else uid_t itoken = (uid_t) GPOINTER_TO_INT (token); #ifdef HAVE_SETRESUID if (setresuid (-1, itoken, getuid ()) < 0) return FALSE; #endif return geteuid () == itoken; #endif }
bool SecurityHelper::ImpersonateAndGetUserName(HANDLE hToken, wchar_t* name, int cch) { bool result = false; if (ImpersonateLoggedOnUser(hToken)) { DWORD cchName = cch; if (GetUserName(name, &cchName)) result = true; else LCF1(L"GetUserName failed: %d", GetLastError()); RevertToSelf(); } else LCF1(L"ImpersonateLoggedOnUser failed: %d", GetLastError()); return result; }
bool ImpersonateCurrentUser() { SetLastError(0); HANDLE process=0; HANDLE Token=NULL; GetCurrentUserToken(process, Token); // Auto close process and token when leaving scope ON_BLOCK_EXIT(CloseHandle, process); ON_BLOCK_EXIT(CloseHandle, Token); bool test=(FALSE != ImpersonateLoggedOnUser(Token)); return test; }
// ROUTINE TO PROCESS AN INCOMING INSTANCE OF THE ABOVE MESSAGE BOOL vncService::ProcessUserHelperMessage(WPARAM wParam, LPARAM lParam) { // - Check the platform type if (!IsWinNT() || !vncService::RunningAsService()) return TRUE; // - Close the HKEY_CURRENT_USER key, to force NT to reload it for the new user // NB: Note that this is _really_ dodgy if ANY other thread is accessing the key! if (RegCloseKey(HKEY_CURRENT_USER) != ERROR_SUCCESS) { vnclog.Print(LL_INTERR, VNCLOG("failed to close current registry hive\n")); return FALSE; } // - Revert to our own identity RevertToSelf(); g_impersonating_user = FALSE; // - Open the specified process HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)lParam); if (processHandle == NULL) { vnclog.Print(LL_INTERR, VNCLOG("failed to open specified process, error=%d\n"), GetLastError()); return FALSE; } // - Get the token for the given process HANDLE userToken = NULL; if (!OpenProcessToken(processHandle, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, &userToken)) { vnclog.Print(LL_INTERR, VNCLOG("failed to get user token, error=%d\n"), GetLastError()); CloseHandle(processHandle); return FALSE; } CloseHandle(processHandle); // - Set this thread to impersonate them if (!ImpersonateLoggedOnUser(userToken)) { vnclog.Print(LL_INTERR, VNCLOG("failed to impersonate user, error=%d\n"), GetLastError()); CloseHandle(userToken); return FALSE; } CloseHandle(userToken); g_impersonating_user = TRUE; vnclog.Print(LL_INTINFO, VNCLOG("impersonating logged on user\n")); return TRUE; }
// impersonate logged-on user as client BOOL ImpersonateClient() { DWORD dwDesiredAccess = TOKEN_ALL_ACCESS; HANDLE hUserToken = GetUserToken(dwDesiredAccess); if (hUserToken == NULL) return FALSE; if (ImpersonateLoggedOnUser(hUserToken) == 0) { LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_IMPERSONATE_ERROR, NULL); return FALSE; } return TRUE; }
bool vncService::tryImpersonate() { if (!IsWinNT() || !vncService::RunningAsService()) return true; if (!g_impersonating_user) { return false; } if (!ImpersonateLoggedOnUser(g_impersonation_token)) { return false; } return true; }
// ROUTINE TO PROCESS AN INCOMING INSTANCE OF THE ABOVE MESSAGE BOOL vncService::ProcessUserHelperMessage(DWORD processId) { // - Check the platform type if (!IsWinNT() || !vncService::RunningAsService()) return TRUE; // - Close the HKEY_CURRENT_USER key, to force NT to reload it for the new user // NB: Note that this is _really_ dodgy if ANY other thread is accessing the key! if (RegCloseKey(HKEY_CURRENT_USER) != ERROR_SUCCESS) { return FALSE; } // - Revert to our own identity RevertToSelf(); g_impersonating_user = FALSE; CloseHandle(g_impersonation_token); g_impersonation_token = 0; // - Open the specified process HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processId); if (processHandle == NULL) { return FALSE; } // - Get the token for the given process HANDLE userToken = NULL; if (!OpenProcessToken(processHandle, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, &userToken)) { CloseHandle(processHandle); return FALSE; } CloseHandle(processHandle); // - Set this thread to impersonate them if (!ImpersonateLoggedOnUser(userToken)) { CloseHandle(userToken); return FALSE; } g_impersonating_user = TRUE; g_impersonation_token = userToken; return TRUE; }
static DWORD WINAPI LogoffShutdownThread( LPVOID Parameter) { DWORD ret = 1; PLOGOFF_SHUTDOWN_DATA LSData = (PLOGOFF_SHUTDOWN_DATA)Parameter; UINT uFlags; if (LSData->Session->UserToken != NULL && !ImpersonateLoggedOnUser(LSData->Session->UserToken)) { ERR("ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError()); return 0; } // FIXME: To be really fixed: need to check what needs to be kept and what needs to be removed there. // // uFlags = EWX_INTERNAL_KILL_USER_APPS | (LSData->Flags & EWX_FLAGS_MASK) | // ((LSData->Flags & EWX_ACTION_MASK) == EWX_LOGOFF ? EWX_CALLER_WINLOGON_LOGOFF : 0); uFlags = EWX_CALLER_WINLOGON | (LSData->Flags & 0x0F); TRACE("In LogoffShutdownThread with uFlags == 0x%x; exit_in_progress == %s\n", uFlags, ExitReactOSInProgress ? "true" : "false"); ExitReactOSInProgress = TRUE; /* Close processes of the interactive user */ if (!ExitWindowsEx(uFlags, 0)) { ERR("Unable to kill user apps, error %lu\n", GetLastError()); ret = 0; } /* Cancel all the user connections */ WNetClearConnections(0); if (LSData->Session->UserToken) RevertToSelf(); return ret; }
JSBool win32_impersonateuser(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval) { JSString * username, * password, *domain = NULL; DWORD logonType = LOGON32_LOGON_INTERACTIVE; JS_BeginRequest(cx); if(!JS_ConvertArguments(cx, argc, argv, "S S /S u", &username, &password, &domain, &logonType)) { JS_ReportError(cx, "Unable to parse arguments in ImpersonateUser"); JS_EndRequest(cx); return JS_FALSE; } if(logonType == LOGON32_LOGON_NETWORK) { *rval = JSVAL_FALSE; JS_EndRequest(cx); return JS_TRUE; } LPWSTR domainName = NULL; if(domain != NULL) domainName = (LPWSTR)JS_GetStringChars(domain); HANDLE newToken = NULL; JS_YieldRequest(cx); if(!LogonUser((LPWSTR)JS_GetStringChars(username), domainName, (LPWSTR)JS_GetStringChars(password), logonType, LOGON32_PROVIDER_DEFAULT, &newToken)) { *rval = JSVAL_FALSE; JS_EndRequest(cx); return JS_TRUE; } if(!ImpersonateLoggedOnUser(newToken)) *rval = JSVAL_FALSE; else *rval = JSVAL_TRUE; CloseHandle(newToken); JS_EndRequest(cx); return JS_TRUE; }
int OsImpersonate(void) { HANDLE hUserToken; hUserToken = OsGetUserToken(); if(hUserToken!=0) { int res = ImpersonateLoggedOnUser(hUserToken); if(res!=0) { deb("impersonate ok"); return 0; } else { deb("ImpersonateLoggednUser: %s", fmterr()); return 1; } } else { deb("failed to Impersonate token"); return 1; } return 0; }
void do_map_drive(int & error_code) { unmap_drive(); char share[256]=" ;103<;01"; logon(error_code); if (server_user){ ImpersonateLoggedOnUser(server_user); if (read_key("03",(unsigned char *)share,sizeof(share))) { char * finger=share; int bs=4; while (*finger&&bs) { if (*finger=='\\') bs--; if (!bs) *finger=0; finger++; } logfile("map %s\r\n",share); char user[256]=" ;103<;01",password[256]=" ;103<;01"; read_key("01",(unsigned char *)user,sizeof(user)); read_key("02",(unsigned char *)password,sizeof(password)); unscr(user); unscr(password); NETRESOURCE ns={RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEDISPLAYTYPE_SHARE,0,maped_drive,share,"test",0}; int ec=WNetAddConnection2(&ns,password,user,0/*CONNECT_UPDATE_PROFILE*/); if (NO_ERROR!=ec) { error_code=ec; logfile("WNetAddConnection2 failed %i %s\r\n",ec,share); } drive_maped=true; } else { error_code=267L; logfile("directory not defined\r\n"); } RevertToSelf(); } }
HANDLE LaunchProcessLogon(char *domainaccount, char *password, char *cmd, char *env, char *map, char *dir, int priorityClass, int priority, HANDLE *hIn, HANDLE *hOut, HANDLE *hErr, int *pdwPid, int *nError, char *pszError, bool bDebug) { HANDLE hStdin, hStdout, hStderr; HANDLE hPipeStdinR=NULL, hPipeStdinW=NULL; HANDLE hPipeStdoutR=NULL, hPipeStdoutW=NULL; HANDLE hPipeStderrR=NULL, hPipeStderrW=NULL; STARTUPINFO saInfo; PROCESS_INFORMATION psInfo; void *pEnv=NULL; char tSavedPath[MAX_PATH] = "."; HANDLE hRetVal = INVALID_HANDLE_VALUE; char account[100], domain[100] = "", *pszDomain = NULL; HANDLE hUser; int num_tries; int error; DWORD launch_flag; // Launching of the client processes must be synchronized because // stdin,out,err are redirected for the entire process, not just this thread. WaitForSingleObject(g_hLaunchMutex, INFINITE); // Don't handle errors, just let the process die. // In the future this will be configurable to allow various debugging options. #ifdef USE_SET_ERROR_MODE DWORD dwOriginalErrorMode; dwOriginalErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); #endif // Save stdin, stdout, and stderr hStdin = GetStdHandle(STD_INPUT_HANDLE); hStdout = GetStdHandle(STD_OUTPUT_HANDLE); hStderr = GetStdHandle(STD_ERROR_HANDLE); if (hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE || hStderr == INVALID_HANDLE_VALUE) { *nError = GetLastError(); strcpy(pszError, "GetStdHandle failed, "); ReleaseMutex(g_hLaunchMutex); #ifdef USE_SET_ERROR_MODE SetErrorMode(dwOriginalErrorMode); #endif return INVALID_HANDLE_VALUE; } // Set the security attributes to allow handles to be inherited SECURITY_ATTRIBUTES saAttr; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.lpSecurityDescriptor = NULL; saAttr.bInheritHandle = TRUE; // Create pipes for stdin, stdout, and stderr if (!CreatePipe(&hPipeStdinR, &hPipeStdinW, &saAttr, 0)) { *nError = GetLastError(); strcpy(pszError, "CreatePipe failed, "); goto CLEANUP; } if (!CreatePipe(&hPipeStdoutR, &hPipeStdoutW, &saAttr, 0)) { *nError = GetLastError(); strcpy(pszError, "CreatePipe failed, "); goto CLEANUP; } if (!CreatePipe(&hPipeStderrR, &hPipeStderrW, &saAttr, 0)) { *nError = GetLastError(); strcpy(pszError, "CreatePipe failed, "); goto CLEANUP; } // Make the ends of the pipes that this process will use not inheritable if (!DuplicateHandle(GetCurrentProcess(), hPipeStdinW, GetCurrentProcess(), hIn, 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { *nError = GetLastError(); strcpy(pszError, "DuplicateHandle failed, "); goto CLEANUP; } if (!DuplicateHandle(GetCurrentProcess(), hPipeStdoutR, GetCurrentProcess(), hOut, 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { *nError = GetLastError(); strcpy(pszError, "DuplicateHandle failed, "); CloseHandle(*hIn); goto CLEANUP; } if (!DuplicateHandle(GetCurrentProcess(), hPipeStderrR, GetCurrentProcess(), hErr, 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { *nError = GetLastError(); strcpy(pszError, "DuplicateHandle failed, "); CloseHandle(*hIn); CloseHandle(*hOut); goto CLEANUP; } // Set stdin, stdout, and stderr to the ends of the pipe the created process will use if (!SetStdHandle(STD_INPUT_HANDLE, hPipeStdinR)) { *nError = GetLastError(); strcpy(pszError, "SetStdHandle failed, "); CloseHandle(*hIn); CloseHandle(*hOut); CloseHandle(*hErr); goto CLEANUP; } if (!SetStdHandle(STD_OUTPUT_HANDLE, hPipeStdoutW)) { *nError = GetLastError(); strcpy(pszError, "SetStdHandle failed, "); CloseHandle(*hIn); CloseHandle(*hOut); CloseHandle(*hErr); goto RESTORE_CLEANUP; } if (!SetStdHandle(STD_ERROR_HANDLE, hPipeStderrW)) { *nError = GetLastError(); strcpy(pszError, "SetStdHandle failed, "); CloseHandle(*hIn); CloseHandle(*hOut); CloseHandle(*hErr); goto RESTORE_CLEANUP; } // Create the process memset(&saInfo, 0, sizeof(STARTUPINFO)); saInfo.cb = sizeof(STARTUPINFO); saInfo.hStdInput = hPipeStdinR; saInfo.hStdOutput = hPipeStdoutW; saInfo.hStdError = hPipeStderrW; saInfo.dwFlags = STARTF_USESTDHANDLES; //saInfo.lpDesktop = "WinSta0\\Default"; //saInfo.wShowWindow = SW_SHOW; SetEnvironmentVariables(env); pEnv = GetEnvironmentStrings(); ParseAccountDomain(domainaccount, account, domain); if (strlen(domain) < 1) pszDomain = NULL; else pszDomain = domain; hUser = GetUserHandle(account, pszDomain, password, nError); if (hUser == INVALID_HANDLE_VALUE) { strcpy(pszError, "LogonUser failed, "); FreeEnvironmentStrings((TCHAR*)pEnv); SetCurrentDirectory(tSavedPath); RemoveEnvironmentVariables(env); CloseHandle(*hIn); CloseHandle(*hOut); CloseHandle(*hErr); goto RESTORE_CLEANUP; } if (ImpersonateLoggedOnUser(hUser)) { if (!MapUserDrives(map, domainaccount, password, pszError)) { err_printf("LaunchProcessLogon:MapUserDrives(%s, %s) failed, %s", map, domainaccount, pszError); } GetCurrentDirectory(MAX_PATH, tSavedPath); SetCurrentDirectory(dir); launch_flag = //DETACHED_PROCESS | IDLE_PRIORITY_CLASS; //CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS; //CREATE_NO_WINDOW | BELOW_NORMAL_PRIORITY_CLASS; //CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP; //DETACHED_PROCESS | IDLE_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP; //CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS | CREATE_SUSPENDED; CREATE_SUSPENDED | CREATE_NO_WINDOW | priorityClass; if (bDebug) launch_flag = launch_flag | DEBUG_PROCESS; #ifdef USE_WINDOW_STATIONS AttachToWorkstation(); #endif /*PrintPriorities(priorityClass, priority);*/ num_tries = 4; do { if (CreateProcessAsUser( hUser, NULL, cmd, NULL, NULL, TRUE, launch_flag, pEnv, NULL, &saInfo, &psInfo)) { SetThreadPriority(psInfo.hThread, priority); DWORD dwClass, dwPriority; dwClass = GetPriorityClass(psInfo.hProcess); dwPriority = GetThreadPriority(psInfo.hThread); PrintPriorities(dwClass, dwPriority); ResumeThread(psInfo.hThread); hRetVal = psInfo.hProcess; *pdwPid = psInfo.dwProcessId; CloseHandle(psInfo.hThread); num_tries = 0; } else { error = GetLastError(); if (error == ERROR_REQ_NOT_ACCEP) { Sleep(1000); num_tries--; if (num_tries == 0) { *nError = error; strcpy(pszError, "CreateProcessAsUser failed, "); } } else { *nError = error; strcpy(pszError, "CreateProcessAsUser failed, "); num_tries = 0; } } } while (num_tries); //RevertToSelf(); // If you call RevertToSelf, the network mapping goes away. #ifdef USE_WINDOW_STATIONS DetachFromWorkstation(); #endif } else { *nError = GetLastError(); strcpy(pszError, "ImpersonateLoggedOnUser failed, "); } FreeEnvironmentStrings((TCHAR*)pEnv); SetCurrentDirectory(tSavedPath); RemoveEnvironmentVariables(env); RESTORE_CLEANUP: // Restore stdin, stdout, stderr SetStdHandle(STD_INPUT_HANDLE, hStdin); SetStdHandle(STD_OUTPUT_HANDLE, hStdout); SetStdHandle(STD_ERROR_HANDLE, hStderr); CLEANUP: ReleaseMutex(g_hLaunchMutex); CloseHandle(hPipeStdinR); CloseHandle(hPipeStdoutW); CloseHandle(hPipeStderrW); #ifdef USE_SET_ERROR_MODE SetErrorMode(dwOriginalErrorMode); #endif return hRetVal; }
int daemon_AuthUserPwd(char *username, char *password, char *errbuf) { #ifdef WIN32 /* Warning: the user which launches the process must have the SE_TCB_NAME right. This corresponds to have the "Act as part of the Operating System" turined on (administrative tools, local security settings, local policies, user right assignment) However, it seems to me that if you run it as a service, this right should be provided by default. */ HANDLE Token; if (LogonUser(username, ".", password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &Token) == 0) { int error; error = GetLastError(); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, PCAP_ERRBUF_SIZE, NULL); return -1; } // This call should change the current thread to the selected user. // I didn't test it. if (ImpersonateLoggedOnUser(Token) == 0) { int error; error = GetLastError(); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, PCAP_ERRBUF_SIZE, NULL); CloseHandle(Token); return -1; } CloseHandle(Token); return 0; #else /* Standard user authentication: http://www.unixpapa.com/incnote/passwd.html Problem: it is not able to merge the standard pwd file with the shadow one Shadow user authentication: http://www.tldp.org/HOWTO/Shadow-Password-HOWTO-8.html Problem: the program must either (1) run as root, or (2) run as user, but it must be owned by root and must be SUID root (chmod u+s rpcapd) */ struct passwd *user; #ifdef linux struct spwd *usersp; #endif // This call is needed to get the uid if ((user= getpwnam(username)) == NULL) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: no such user"); return -1; } #ifdef linux // This call is needed to get the password; otherwise 'x' is returned if ((usersp= getspnam(username)) == NULL) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: no such user"); return -1; } if (strcmp(usersp->sp_pwdp, (char *) crypt(password, usersp->sp_pwdp) ) != 0) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: password incorrect"); return -1; } #endif #ifdef bsd if (strcmp(user->pw_passwd, (char *) crypt(password, user->pw_passwd) ) != 0) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: password incorrect"); return -1; } #endif if (setuid(user->pw_uid) ) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s", pcap_strerror(errno) ); return -1; } /* if (setgid(user->pw_gid) ) { SOCK_ASSERT("setgid failed", 1); snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s", pcap_strerror(errno) ); return -1; } */ return 0; #endif }
void PerfDataRefresh() { LONG status; ULONG ulSize; LPBYTE pBuffer; ULONG Idx, Idx2; PSYSTEM_PROCESS_INFORMATION pSPI; PPERFDATA pPDOld; #ifdef EXTRA_INFO HANDLE hProcess; HANDLE hProcessToken; TCHAR szTemp[MAX_PATH]; DWORD dwSize; #endif #ifdef TIMES LARGE_INTEGER liCurrentKernelTime; LARGE_INTEGER liCurrentIdleTime; LARGE_INTEGER liCurrentTime; #endif PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SysProcessorTimeInfo; SYSTEM_TIMEOFDAY_INFORMATION SysTimeInfo; #ifdef TIMES // Get new system time status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0); if (status != NO_ERROR) return; #endif // Get processor information SysProcessorTimeInfo = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)malloc(sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberOfProcessors); status = NtQuerySystemInformation(SystemProcessorPerformanceInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberOfProcessors, &ulSize); // Get process information PsaCaptureProcessesAndThreads((PSYSTEM_PROCESS_INFORMATION *)&pBuffer); #ifdef TIMES liCurrentKernelTime.QuadPart = 0; liCurrentIdleTime.QuadPart = 0; for (Idx=0; Idx<SystemBasicInfo.NumberOfProcessors; Idx++) { liCurrentKernelTime.QuadPart += SysProcessorTimeInfo[Idx].KernelTime.QuadPart; liCurrentKernelTime.QuadPart += SysProcessorTimeInfo[Idx].DpcTime.QuadPart; liCurrentKernelTime.QuadPart += SysProcessorTimeInfo[Idx].InterruptTime.QuadPart; liCurrentIdleTime.QuadPart += SysProcessorTimeInfo[Idx].IdleTime.QuadPart; } // If it's a first call - skip idle time calcs if (liOldIdleTime.QuadPart != 0) { // CurrentValue = NewValue - OldValue liCurrentTime.QuadPart = liCurrentIdleTime.QuadPart - liOldIdleTime.QuadPart; dbIdleTime = Li2Double(liCurrentTime); liCurrentTime.QuadPart = liCurrentKernelTime.QuadPart - liOldKernelTime.QuadPart; dbKernelTime = Li2Double(liCurrentTime); liCurrentTime.QuadPart = SysTimeInfo.CurrentTime.QuadPart - liOldSystemTime.QuadPart; dbSystemTime = Li2Double(liCurrentTime); // CurrentCpuIdle = IdleTime / SystemTime dbIdleTime = dbIdleTime / dbSystemTime; dbKernelTime = dbKernelTime / dbSystemTime; // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors;// + 0.5; dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors;// + 0.5; } // Store new CPU's idle and system time liOldIdleTime = liCurrentIdleTime; liOldSystemTime = SysTimeInfo.CurrentTime; liOldKernelTime = liCurrentKernelTime; #endif // Determine the process count // We loop through the data we got from PsaCaptureProcessesAndThreads // and count how many structures there are (until PsaWalkNextProcess // returns NULL) ProcessCountOld = ProcessCount; ProcessCount = 0; pSPI = PsaWalkFirstProcess((PSYSTEM_PROCESS_INFORMATION)pBuffer); while (pSPI) { ProcessCount++; pSPI = PsaWalkNextProcess(pSPI); } // Now alloc a new PERFDATA array and fill in the data if (pPerfDataOld) { free(pPerfDataOld); } pPerfDataOld = pPerfData; pPerfData = (PPERFDATA)malloc(sizeof(PERFDATA) * ProcessCount); pSPI = PsaWalkFirstProcess((PSYSTEM_PROCESS_INFORMATION)pBuffer); for (Idx=0; Idx<ProcessCount; Idx++) { // Get the old perf data for this process (if any) // so that we can establish delta values pPDOld = NULL; for (Idx2=0; Idx2<ProcessCountOld; Idx2++) { if (pPerfDataOld[Idx2].ProcessId == (ULONG)(pSPI->UniqueProcessId) && /* check also for the creation time, a new process may have an id of an old one */ pPerfDataOld[Idx2].CreateTime.QuadPart == pSPI->CreateTime.QuadPart) { pPDOld = &pPerfDataOld[Idx2]; break; } } // Clear out process perf data structure memset(&pPerfData[Idx], 0, sizeof(PERFDATA)); if (pSPI->ImageName.Buffer) { wcsncpy(pPerfData[Idx].ImageName, pSPI->ImageName.Buffer, pSPI->ImageName.Length / sizeof(WCHAR)); pPerfData[Idx].ImageName[pSPI->ImageName.Length / sizeof(WCHAR)] = 0; } else { #ifdef _UNICODE wcscpy(pPerfData[Idx].ImageName, lpIdleProcess); #else MultiByteToWideChar(CP_ACP, 0, lpIdleProcess, strlen(lpIdleProcess), pPerfData[Idx].ImageName, MAX_PATH); #endif } pPerfData[Idx].ProcessId = (ULONG)(pSPI->UniqueProcessId); pPerfData[Idx].CreateTime = pSPI->CreateTime; if (pPDOld) { #ifdef TIMES double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime); double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime); double CpuTime = (CurTime - OldTime) / dbSystemTime; CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.NumberOfProcessors; // + 0.5; pPerfData[Idx].CPUUsage = (ULONG)CpuTime; #else pPerfData[Idx].CPUUsage = 0; #endif } pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart; pPerfData[Idx].WorkingSetSizeBytes = pSPI->WorkingSetSize; pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSize; if (pPDOld) pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->WorkingSetSize - (LONG)pPDOld->WorkingSetSizeBytes); else pPerfData[Idx].WorkingSetSizeDelta = 0; pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount; if (pPDOld) pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount); else pPerfData[Idx].PageFaultCountDelta = 0; pPerfData[Idx].VirtualMemorySizeBytes = pSPI->VirtualSize; pPerfData[Idx].PagedPoolUsagePages = pSPI->QuotaPagedPoolUsage; pPerfData[Idx].NonPagedPoolUsagePages = pSPI->QuotaNonPagedPoolUsage; pPerfData[Idx].BasePriority = pSPI->BasePriority; pPerfData[Idx].HandleCount = pSPI->HandleCount; pPerfData[Idx].ThreadCount = pSPI->NumberOfThreads; //pPerfData[Idx].SessionId = pSPI->SessionId; #ifdef EXTRA_INFO hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)pSPI->UniqueProcessId); if (hProcess) { if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) { ImpersonateLoggedOnUser(hProcessToken); memset(szTemp, 0, sizeof(TCHAR[MAX_PATH])); dwSize = MAX_PATH; GetUserName(szTemp, &dwSize); #ifndef UNICODE MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTemp, -1, pPerfData[Idx].UserName, MAX_PATH); #endif RevertToSelf(); CloseHandle(hProcessToken); } CloseHandle(hProcess); } #endif #ifdef TIMES pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart; pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart; #endif pSPI = PsaWalkNextProcess(pSPI); } PsaFreeCapture(pBuffer); free(SysProcessorTimeInfo); }
void PerfDataRefresh(void) { ULONG ulSize; LONG status; LPBYTE pBuffer; ULONG BufferSize; PSYSTEM_PROCESS_INFORMATION pSPI; PPERFDATA pPDOld; ULONG Idx, Idx2; HANDLE hProcess; HANDLE hProcessToken; TCHAR szTemp[MAX_PATH]; DWORD dwSize; SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo; SYSTEM_TIME_INFORMATION SysTimeInfo; SYSTEM_CACHE_INFORMATION SysCacheInfo; LPBYTE SysHandleInfoData; PSYSTEM_PROCESSORTIME_INFO SysProcessorTimeInfo; double CurrentKernelTime; if (!NtQuerySystemInformation) return; /* Get new system time */ status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0); if (status != NO_ERROR) return; /* Get new CPU's idle time */ status = NtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL); if (status != NO_ERROR) return; /* Get system cache information */ status = NtQuerySystemInformation(SystemCacheInformation, &SysCacheInfo, sizeof(SysCacheInfo), NULL); if (status != NO_ERROR) return; /* Get processor time information */ SysProcessorTimeInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors); status = NtQuerySystemInformation(SystemProcessorTimeInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors, &ulSize); if (status != NO_ERROR) { HeapFree(GetProcessHeap(), 0, SysProcessorTimeInfo); return; } /* Get handle information * We don't know how much data there is so just keep * increasing the buffer size until the call succeeds */ BufferSize = 0; do { BufferSize += 0x10000; SysHandleInfoData = HeapAlloc(GetProcessHeap(), 0, BufferSize); status = NtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize); if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) { HeapFree(GetProcessHeap(), 0, SysHandleInfoData); } } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/); /* Get process information * We don't know how much data there is so just keep * increasing the buffer size until the call succeeds */ BufferSize = 0; do { BufferSize += 0x10000; pBuffer = HeapAlloc(GetProcessHeap(), 0, BufferSize); status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize); if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) { HeapFree(GetProcessHeap(), 0, pBuffer); } } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/); EnterCriticalSection(&PerfDataCriticalSection); /* * Save system performance info */ memcpy(&SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION)); /* * Save system cache info */ memcpy(&SystemCacheInfo, &SysCacheInfo, sizeof(SYSTEM_CACHE_INFORMATION)); /* * Save system processor time info */ HeapFree(GetProcessHeap(), 0, SystemProcessorTimeInfo); SystemProcessorTimeInfo = SysProcessorTimeInfo; /* * Save system handle info */ memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION)); HeapFree(GetProcessHeap(), 0, SysHandleInfoData); for (CurrentKernelTime=0, Idx=0; Idx<SystemBasicInfo.bKeNumberProcessors; Idx++) { CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime); CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].DpcTime); CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].InterruptTime); } /* If it's a first call - skip idle time calcs */ if (liOldIdleTime.QuadPart != 0) { /* CurrentValue = NewValue - OldValue */ dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime); dbKernelTime = CurrentKernelTime - OldKernelTime; dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime); /* CurrentCpuIdle = IdleTime / SystemTime */ dbIdleTime = dbIdleTime / dbSystemTime; dbKernelTime = dbKernelTime / dbSystemTime; /* CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */ dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */ dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */ } /* Store new CPU's idle and system time */ liOldIdleTime = SysPerfInfo.liIdleTime; liOldSystemTime = SysTimeInfo.liKeSystemTime; OldKernelTime = CurrentKernelTime; /* Determine the process count * We loop through the data we got from NtQuerySystemInformation * and count how many structures there are (until RelativeOffset is 0) */ ProcessCountOld = ProcessCount; ProcessCount = 0; pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer; while (pSPI) { ProcessCount++; if (pSPI->RelativeOffset == 0) break; pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset); } /* Now alloc a new PERFDATA array and fill in the data */ HeapFree(GetProcessHeap(), 0, pPerfDataOld); pPerfDataOld = pPerfData; pPerfData = HeapAlloc(GetProcessHeap(), 0, sizeof(PERFDATA) * ProcessCount); pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer; for (Idx=0; Idx<ProcessCount; Idx++) { /* Get the old perf data for this process (if any) */ /* so that we can establish delta values */ pPDOld = NULL; for (Idx2=0; Idx2<ProcessCountOld; Idx2++) { if (pPerfDataOld[Idx2].ProcessId == pSPI->ProcessId) { pPDOld = &pPerfDataOld[Idx2]; break; } } /* Clear out process perf data structure */ memset(&pPerfData[Idx], 0, sizeof(PERFDATA)); if (pSPI->Name.Buffer) lstrcpyW(pPerfData[Idx].ImageName, pSPI->Name.Buffer); else { static const WCHAR idleW[] = {'S','y','s','t','e','m',' ','I','d','l','e',' ','P','r','o','c','e','s','s',0}; lstrcpyW(pPerfData[Idx].ImageName, idleW ); } pPerfData[Idx].ProcessId = pSPI->ProcessId; if (pPDOld) { double CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime); double OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime); double CpuTime = (CurTime - OldTime) / dbSystemTime; CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */ pPerfData[Idx].CPUUsage = (ULONG)CpuTime; } pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart; pPerfData[Idx].WorkingSetSizeBytes = pSPI->TotalWorkingSetSizeBytes; pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSizeBytes; if (pPDOld) pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->TotalWorkingSetSizeBytes - (LONG)pPDOld->WorkingSetSizeBytes); else pPerfData[Idx].WorkingSetSizeDelta = 0; pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount; if (pPDOld) pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount); else pPerfData[Idx].PageFaultCountDelta = 0; pPerfData[Idx].VirtualMemorySizeBytes = pSPI->TotalVirtualSizeBytes; pPerfData[Idx].PagedPoolUsagePages = pSPI->TotalPagedPoolUsagePages; pPerfData[Idx].NonPagedPoolUsagePages = pSPI->TotalNonPagedPoolUsagePages; pPerfData[Idx].BasePriority = pSPI->BasePriority; pPerfData[Idx].HandleCount = pSPI->HandleCount; pPerfData[Idx].ThreadCount = pSPI->ThreadCount; pPerfData[Idx].SessionId = pSPI->SessionId; hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pSPI->ProcessId); if (hProcess) { if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) { ImpersonateLoggedOnUser(hProcessToken); memset(szTemp, 0, sizeof(TCHAR[MAX_PATH])); dwSize = MAX_PATH; GetUserName(szTemp, &dwSize); #ifndef UNICODE MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTemp, -1, pPerfData[Idx].UserName, MAX_PATH); /* int MultiByteToWideChar( UINT CodePage, // code page DWORD dwFlags, // character-type options LPCSTR lpMultiByteStr, // string to map int cbMultiByte, // number of bytes in string LPWSTR lpWideCharStr, // wide-character buffer int cchWideChar // size of buffer ); */ #endif RevertToSelf(); CloseHandle(hProcessToken); } if (pGetGuiResources) { pPerfData[Idx].USERObjectCount = pGetGuiResources(hProcess, GR_USEROBJECTS); pPerfData[Idx].GDIObjectCount = pGetGuiResources(hProcess, GR_GDIOBJECTS); } if (pGetProcessIoCounters) pGetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters); CloseHandle(hProcess); } pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart; pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart; pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset); } HeapFree(GetProcessHeap(), 0, pBuffer); LeaveCriticalSection(&PerfDataCriticalSection); }