tags:

views:

48

answers:

2

Hi All, I want to get the user name who has launched the given application. For Example if Outlook or IE is launched I need to get the Name of the user who has launched it. This should be generic across all Windows OS . But the solution given below is failing in Windows 2003 user ,in both ADMIN and Standard User.

A: 

You need GetUserName Function from WinApi.

Sergius
That will only return the user name of the current process of the application. The OP asked for a different process. Unless he does inject a remote thread (which is not a good idea at all and may even sometimes not work) and passes the information back that won't work.
Vinzenz
Sorry, misunderstood the question.
Sergius
+2  A: 

I found this page which gives a function to recover a process owner's name.

Here is the code (not my code and I couldn't test it):

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

Hope it helps.

ereOn
This is exactly how it works, you were faster than me ;-) I was just about to write it here too :-)
Vinzenz
But the solution given above is failing in Windows 2003 server,in both ADMIN and Standard User. Subbu
subbu
@subbu: Could you be more explicit about the failure ?
ereOn
when try to get the user name in Windows 2003 server ::GetTokenInformation(hProcessToken, TokenUser, NULL, 0, // Call should have failed due to zero-length buffer. if( ::GetLastError() == ERROR_INSUFFICIENT_BUFFER )GetlastError() gives access denied
subbu
@subbu Does your process run with administrative privileges ?
ereOn
it depends on the user who is launching it. If user is Admin my application will run as Admin. If he is a STD user this will be a Std
subbu
And the issue is raised on both cases ?
ereOn
yes in both cases issue is raised
subbu