Archive

Posts Tagged ‘OpenProcessToken’

Changing scheduling priority of a process at runtime

March 4, 2009 3 comments

I had a requirement sometime back to make my process have a higher priority at runtime, so went hunting around for an API which does this and found one with an intuitive name, “SetPriorityClass”. So what is process priority? Process priority is the value which determines priority of a process when it’s being scheduled. If there are two processes having normal priority and above normal priority respectively, then the one with above normal priority is given preference. Internally it’s more complicated than what I explained.

We normally set priority through task manager…

Changing process priority through task manager

Changing process priority through task manager

These are the priority classes defined in windows (From MSDN)…

  1. IDLE_PRIORITY_CLASS – Process whose threads run only when the system is idle. The threads of the process are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle-priority class is inherited by child processes.
  2. BELOW_NORMAL_PRIORITY_CLASS – Process that has priority above IDLE_PRIORITY_CLASS but below NORMAL_PRIORITY_CLASS.
  3. NORMAL_PRIORITY_CLASS – Process with no special scheduling needs.
  4. ABOVE_NORMAL_PRIORITY_CLASS – Process that has priority above NORMAL_PRIORITY_CLASS but below HIGH_PRIORITY_CLASS.
  5. HIGH_PRIORITY_CLASS – Process that performs time-critical tasks that must be executed immediately. The threads of the process preempt the threads of normal or idle priority class processes. An example is the Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class application can use nearly all available CPU time.
  6. REALTIME_PRIORITY_CLASS –Process that has the highest possible priority. The threads of the process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.

So these are the six priorities supported in windows and here is a small function which changes priority of current process to above normal class.

void ChangeProcessPriority()
{
   HANDLE hProcess = GetCurrentProcess();
   SetPriorityClass( hProcess , ABOVE_NORMAL_PRIORITY_CLASS );
}

Note that for above code to work; the handle given to SetPriorityClass must have PROCESS_SET_INFORMATION right. Use OpenProcessToken function to get a process token and then use AdjustTokenPrivileges function to set new privileges. A demo for changing process priority is given here -> http://nibuthomas.com/2007/06/28/function-for-enabling-privileges-for-your-application/

To retrieve current priority of a process call GetPriorityClass(). Also for this function to work handle given must have PROCESS_QUERY_INFORMATION privilege set.

DWORD GetProcessPriority()
{
   HANDLE hProcess = GetCurrentProcess();
   return GetPriorityClass( hProcess );
}
Advertisements

How to get name of owner of a process?

January 8, 2008 6 comments

Here is a function that extracts the name of the owner of a process…

bool ExtractProcessOwner( HANDLE hProcess_i,
                          CString& csOwner_o )
{
   // Get process token
   HANDLE hProcessToken = NULL;
   if ( !::OpenProcessToken( hProcess_i, TOKEN_READ, &hProcessToken ) || !hProcessToken )
   {
      return false;
   }

   // First get size needed, TokenUser indicates we want user information from given token
   DWORD dwProcessTokenInfoAllocSize = 0;
   ::GetTokenInformation(hProcessToken, TokenUser, NULL, 0, &dwProcessTokenInfoAllocSize);

   // Call should have failed due to zero-length buffer.
   if( ::GetLastError() == ERROR_INSUFFICIENT_BUFFER )
   {
      // Allocate buffer for user information in the token.
      PTOKEN_USER pUserToken = reinterpret_cast<ptoken_user>( new BYTE[dwProcessTokenInfoAllocSize] );
      if (pUserToken != NULL)
      {
         // Now get user information in the allocated buffer
         if (::GetTokenInformation( hProcessToken, TokenUser, pUserToken, dwProcessTokenInfoAllocSize, &dwProcessTokenInfoAllocSize ))
         {
            // Some vars that we may need
            SID_NAME_USE   snuSIDNameUse;
            TCHAR          szUser[MAX_PATH] = { 0 };
            DWORD          dwUserNameLength = MAX_PATH;
            TCHAR          szDomain[MAX_PATH] = { 0 };
            DWORD          dwDomainNameLength = MAX_PATH;

            // Retrieve user name and domain name based on user's SID.
            if ( ::LookupAccountSid( NULL,
                                     pUserToken->User.Sid,
                                     szUser,
                                     &dwUserNameLength,
                                     szDomain,
                                     &dwDomainNameLength,
                                     &snuSIDNameUse ))
            {
               // Prepare user name string
               csOwner_o = _T("\\\\");
               csOwner_o += szDomain;
               csOwner_o += _T("\\");
               csOwner_o += szUser;

               // We are done!
               CloseHandle( hProcessToken );
               delete [] pUserToken;

               // We succeeded
               return true;
            }//End if
         }// End if

         delete [] pUserToken;
      }// End if
   }// End if

   CloseHandle( hProcessToken );

   // Oops trouble
   return false;
}// End GetProcessOwner

The key to this implementation is the function GetTokenInformation and the token information class TokenUser. Take a look in MSDN for this function. Take note of the information classes available. GetTokenInformation returns the users security identifier(SID) using which we called the function LookupAccountSid which returns the corresponding users name.

You may also need the SeDebugPrivilege set to execute this function successfully.

Function for enabling privileges for your application!

June 28, 2007 4 comments

Here is the code that does this…

// Set up access
void SetUpAccess()
{
    HANDLE hProcToken = 0;
    if( !OpenProcessToken( GetCurrentProcess(),
                           TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
                           &hProcToken ))
    {
        return;
    }  

    // List of privileges, all of them, he he 😀
    LPCTSTR lpctszPrivileges[] = { SE_CREATE_TOKEN_NAME,
                                   SE_ASSIGNPRIMARYTOKEN_NAME,
                                   SE_LOCK_MEMORY_NAME,
                                   SE_INCREASE_QUOTA_NAME,
                                   SE_UNSOLICITED_INPUT_NAME,
                                   SE_MACHINE_ACCOUNT_NAME,
                                   SE_TCB_NAME,
                                   SE_SECURITY_NAME,
                                   SE_TAKE_OWNERSHIP_NAME,
                                   SE_LOAD_DRIVER_NAME,
                                   SE_SYSTEM_PROFILE_NAME,
                                   SE_SYSTEMTIME_NAME,
                                   SE_PROF_SINGLE_PROCESS_NAME,
                                   SE_INC_BASE_PRIORITY_NAME,
                                   SE_CREATE_PAGEFILE_NAME,
                                   SE_CREATE_PERMANENT_NAME,
                                   SE_BACKUP_NAME,
                                   SE_RESTORE_NAME,
                                   SE_SHUTDOWN_NAME,
                                   SE_DEBUG_NAME,
                                   SE_AUDIT_NAME,
                                   SE_SYSTEM_ENVIRONMENT_NAME,
                                   SE_CHANGE_NOTIFY_NAME,
                                   SE_REMOTE_SHUTDOWN_NAME,
                                   SE_UNDOCK_NAME,
                                   SE_SYNC_AGENT_NAME,         
                                   SE_ENABLE_DELEGATION_NAME,  
                                   SE_MANAGE_VOLUME_NAME,
                                   0 // The end
                                 }; 

    // Token privileges structure
    TOKEN_PRIVILEGES tkpPriv = { 0 };    

    // Loop through and enable privileges
    for( int nIndex = 0; lpctszPrivileges[nIndex]; ++nIndex )
    {
        // Clear previous
        ::ZeroMemory( &tkpPriv, sizeof( tkpPriv ));    

        // Look up value for privilege
        LookupPrivilegeValue( NULL,
                              lpctszPrivileges[nIndex],
                              &tkpPriv.Privileges[0].Luid );    

        // Count of privilege
        tkpPriv.PrivilegeCount = 1;    

        // Set up "enable" attribute for privilege
        tkpPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;    

        // Set up privilege
        AdjustTokenPrivileges( hProcToken, FALSE, &tkpPriv, 0, 0, 0 );
    }// End for   

    // Close handle
    CloseHandle( hProcToken );
}// End SetUpAccess
%d bloggers like this: