Example #1
0
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;
}
Example #2
0
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);
	}
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #6
0
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;
}
Example #7
0
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);
}
Example #8
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;
	
}
Example #9
0
void Impersonator::impersonateAsLoggedUser()
{
  WTS::queryConsoleUserToken(&m_token);

  if ((!DuplicateToken(m_token, SecurityImpersonation, &m_dupToken)) || 
      (!ImpersonateLoggedOnUser(m_dupToken))) {
    throw SystemException();
  }
}
Example #10
0
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__);
   }
}
Example #11
0
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;
}
Example #12
0
File: win.c Project: 0xe/win-sshd
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;
}
Example #13
0
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;
  }
}
Example #14
0
/**
 * @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);
}
Example #15
0
/* @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;
}
Example #16
0
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;
}
Example #18
0
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;
}
Example #19
0
// 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;
}
Example #20
0
// 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;
}
Example #21
0
bool vncService::tryImpersonate()
{
	if (!IsWinNT() || !vncService::RunningAsService())
		return true;

	if (!g_impersonating_user) {

		return false;
	}
	if (!ImpersonateLoggedOnUser(g_impersonation_token)) {

		return false;
	}

	return true;
}
Example #22
0
// 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;
}
Example #23
0
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;
}
Example #24
0
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;
}
Example #25
0
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;
}
Example #26
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();
    }   
}
Example #27
0
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;
}
Example #28
0
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

}
Example #29
0
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);
}
Example #30
0
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);
}