Esempio n. 1
0
        /// <summary>
        /// Retrieve the UserName through PInvoke
        /// </summary>
        /// <param name="process"></param>
        /// <returns></returns>
        private static string RetrieveProcessUserName(Process process)
        {
            string userName = null;

#if UNIX
            userName = Platform.NonWindowsGetUserFromPid(process.Id);
#else
            IntPtr tokenUserInfo       = IntPtr.Zero;
            IntPtr processTokenHandler = IntPtr.Zero;

            const uint TOKEN_QUERY = 0x0008;

            try
            {
                do
                {
                    int error;
                    if (!Win32Native.OpenProcessToken(ClrFacade.GetSafeProcessHandle(process), TOKEN_QUERY, out processTokenHandler))
                    {
                        break;
                    }

                    // Set the default length to be 256, so it will be sufficient for most cases
                    int tokenInfoLength = 256;
                    tokenUserInfo = Marshal.AllocHGlobal(tokenInfoLength);
                    if (!Win32Native.GetTokenInformation(processTokenHandler, Win32Native.TOKEN_INFORMATION_CLASS.TokenUser, tokenUserInfo, tokenInfoLength, out tokenInfoLength))
                    {
                        error = Marshal.GetLastWin32Error();
                        if (error == Win32Native.ERROR_INSUFFICIENT_BUFFER)
                        {
                            Marshal.FreeHGlobal(tokenUserInfo);
                            tokenUserInfo = Marshal.AllocHGlobal(tokenInfoLength);

                            if (!Win32Native.GetTokenInformation(processTokenHandler, Win32Native.TOKEN_INFORMATION_CLASS.TokenUser, tokenUserInfo, tokenInfoLength, out tokenInfoLength))
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    var tokenUser = ClrFacade.PtrToStructure <Win32Native.TOKEN_USER>(tokenUserInfo);

                    // Set the default length to be 256, so it will be sufficient for most cases
                    int userNameLength = 256, domainNameLength = 256;
                    var userNameStr   = new StringBuilder(userNameLength);
                    var domainNameStr = new StringBuilder(domainNameLength);
                    Win32Native.SID_NAME_USE accountType;

                    if (!Win32Native.LookupAccountSid(null, tokenUser.User.Sid, userNameStr, ref userNameLength, domainNameStr, ref domainNameLength, out accountType))
                    {
                        error = Marshal.GetLastWin32Error();
                        if (error == Win32Native.ERROR_INSUFFICIENT_BUFFER)
                        {
                            userNameStr.EnsureCapacity(userNameLength);
                            domainNameStr.EnsureCapacity(domainNameLength);

                            if (!Win32Native.LookupAccountSid(null, tokenUser.User.Sid, userNameStr, ref userNameLength, domainNameStr, ref domainNameLength, out accountType))
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    userName = domainNameStr + "\\" + userNameStr;
                } while (false);
            }
            catch (NotSupportedException)
            {
                // The Process not started yet, or it's a process from a remote machine
            }
            catch (InvalidOperationException)
            {
                // The Process has exited, Process.Handle will raise this exception
            }
            catch (Win32Exception)
            {
                // We might get an AccessDenied error
            }
            catch (Exception)
            {
                // I don't expect to get other exceptions,
            }
            finally
            {
                if (tokenUserInfo != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(tokenUserInfo);
                }

                if (processTokenHandler != IntPtr.Zero)
                {
                    Win32Native.CloseHandle(processTokenHandler);
                }
            }
#endif
            return(userName);
        }