@@ -172,13 +172,24 @@ public NtToken DuplicateToken(TokenType type, SecurityImpersonationLevel level,
172172 }
173173
174174 /// <summary>
175- /// Duplicate the token as a primary token
175+ /// Duplicate the token as the same token type.
176176 /// </summary>
177- /// <returns>The new token</returns>
177+ /// <returns>The new token. </returns>
178178 /// <exception cref="NtException">Thrown on error</exception>
179179 public NtToken DuplicateToken ( )
180180 {
181- return DuplicateToken ( TokenType . Primary , SecurityImpersonationLevel . Anonymous , TokenAccessRights . MaximumAllowed ) ;
181+ return DuplicateToken ( true ) . Result ;
182+ }
183+
184+ /// <summary>
185+ /// Duplicate the token as the same token type.
186+ /// </summary>
187+ /// <param name="throw_on_error">True to throw on error.</param>
188+ /// <returns>The new token.</returns>
189+ /// <exception cref="NtException">Thrown on error</exception>
190+ public NtResult < NtToken > DuplicateToken ( bool throw_on_error )
191+ {
192+ return DuplicateToken ( TokenType , ImpersonationLevel , TokenAccessRights . MaximumAllowed , throw_on_error ) ;
182193 }
183194
184195 /// <summary>
@@ -887,6 +898,21 @@ public UserGroup[] QueryGroups(QueryGroupType group_type)
887898 return QueryGroups ( group_type , true ) . Result ;
888899 }
889900
901+ /// <summary>
902+ /// Get the user from the token.
903+ /// </summary>
904+ /// <param name="throw_on_error">True to throw on error.</param>
905+ /// <returns>The user group information.</returns>
906+ public NtResult < UserGroup > GetUser ( bool throw_on_error )
907+ {
908+ using ( var user = QueryBuffer ( TokenInformationClass . TokenUser , new TokenUser ( ) , throw_on_error ) )
909+ {
910+ if ( ! user . IsSuccess )
911+ return user . Cast < UserGroup > ( ) ;
912+ return user . Result . Result . User . ToUserGroup ( ) . CreateResult ( ) ;
913+ }
914+ }
915+
890916 /// <summary>
891917 /// Method to query information for this object type.
892918 /// </summary>
@@ -1854,15 +1880,27 @@ public static NtToken OpenProcessToken(NtProcess process, bool duplicate)
18541880 /// <exception cref="NtException">Thrown if cannot open token</exception>
18551881 public static NtToken OpenProcessToken ( NtProcess process , bool duplicate , TokenAccessRights desired_access )
18561882 {
1857- var ret = OpenProcessToken ( process , desired_access , true ) . Result ;
1858- if ( duplicate )
1883+ return OpenProcessToken ( process , duplicate , desired_access , true ) . Result ;
1884+ }
1885+
1886+ /// <summary>
1887+ /// Open the process token of another process
1888+ /// </summary>
1889+ /// <param name="process">The process to open the token for</param>
1890+ /// <param name="duplicate">True to duplicate the token before returning</param>
1891+ /// <param name="desired_access">The desired access for the token</param>
1892+ /// <param name="throw_on_error">True to throw on error.</param>
1893+ /// <returns>The opened token</returns>
1894+ /// <exception cref="NtException">Thrown if cannot open token</exception>
1895+ public static NtResult < NtToken > OpenProcessToken ( NtProcess process , bool duplicate , TokenAccessRights desired_access , bool throw_on_error )
1896+ {
1897+ var ret = OpenProcessToken ( process , desired_access , throw_on_error ) ;
1898+ if ( ! ret . IsSuccess || ! duplicate )
1899+ return ret ;
1900+ using ( ret )
18591901 {
1860- using ( ret )
1861- {
1862- return ret . DuplicateToken ( ) ;
1863- }
1902+ return ret . Result . DuplicateToken ( throw_on_error ) ;
18641903 }
1865- return ret ;
18661904 }
18671905
18681906 /// <summary>
@@ -1937,6 +1975,25 @@ public static NtToken OpenProcessToken(int pid, bool duplicate, TokenAccessRight
19371975 }
19381976 }
19391977
1978+ /// <summary>
1979+ /// Open the process token of another process
1980+ /// </summary>
1981+ /// <param name="pid">The id of the process to open the token for</param>
1982+ /// <param name="duplicate">True to duplicate the token before returning</param>
1983+ /// <param name="desired_access">The desired access for the token</param>
1984+ /// <param name="throw_on_error">True to throw on error.</param>
1985+ /// <returns>The opened token</returns>
1986+ /// <exception cref="NtException">Thrown if cannot open token</exception>
1987+ public static NtResult < NtToken > OpenProcessToken ( int pid , bool duplicate , TokenAccessRights desired_access , bool throw_on_error )
1988+ {
1989+ using ( var process = NtProcess . Open ( pid , ProcessAccessRights . QueryLimitedInformation , throw_on_error ) )
1990+ {
1991+ if ( ! process . IsSuccess )
1992+ return process . Cast < NtToken > ( ) ;
1993+ return OpenProcessToken ( process . Result , duplicate , desired_access , throw_on_error ) ;
1994+ }
1995+ }
1996+
19401997 /// <summary>
19411998 /// Open the process token of another process
19421999 /// </summary>
@@ -1968,24 +2025,37 @@ public static NtResult<NtToken> OpenThreadToken(NtThread thread, bool open_as_se
19682025 /// </summary>
19692026 /// <param name="thread">The thread to open the token for</param>
19702027 /// <param name="open_as_self">Open the token as the current identify rather than the impersonated one</param>
1971- /// <param name="duplicate">True to duplicate the token before returning</param>
2028+ /// <param name="duplicate">True to duplicate the token before returning. </param>
19722029 /// <param name="desired_access">The desired access for the token</param>
2030+ /// <param name="throw_on_error">True to throw on error.</param>
19732031 /// <returns>The opened token, if no token return null</returns>
19742032 /// <exception cref="NtException">Thrown if cannot open token</exception>
1975- public static NtToken OpenThreadToken ( NtThread thread , bool open_as_self , bool duplicate , TokenAccessRights desired_access )
2033+ public static NtResult < NtToken > OpenThreadToken ( NtThread thread , bool open_as_self ,
2034+ bool duplicate , TokenAccessRights desired_access , bool throw_on_error )
19762035 {
19772036 var result = OpenThreadToken ( thread , open_as_self , desired_access , false ) ;
19782037 if ( result . Status == NtStatus . STATUS_NO_TOKEN )
1979- return null ;
1980- NtToken ret = result . GetResultOrThrow ( ) ;
1981- if ( duplicate )
2038+ return new NtResult < NtToken > ( ) ;
2039+ if ( ! duplicate )
2040+ return result ;
2041+ using ( result )
19822042 {
1983- using ( ret )
1984- {
1985- return ret . DuplicateToken ( ) ;
1986- }
2043+ return result . Result . DuplicateToken ( throw_on_error ) ;
19872044 }
1988- return ret ;
2045+ }
2046+
2047+ /// <summary>
2048+ /// Open the thread token
2049+ /// </summary>
2050+ /// <param name="thread">The thread to open the token for</param>
2051+ /// <param name="open_as_self">Open the token as the current identify rather than the impersonated one</param>
2052+ /// <param name="duplicate">True to duplicate the token before returning</param>
2053+ /// <param name="desired_access">The desired access for the token</param>
2054+ /// <returns>The opened token, if no token return null</returns>
2055+ /// <exception cref="NtException">Thrown if cannot open token</exception>
2056+ public static NtToken OpenThreadToken ( NtThread thread , bool open_as_self , bool duplicate , TokenAccessRights desired_access )
2057+ {
2058+ return OpenThreadToken ( thread , open_as_self , duplicate , desired_access , true ) . Result ;
19892059 }
19902060
19912061 /// <summary>
@@ -2050,6 +2120,27 @@ public static NtToken OpenThreadToken()
20502120 return OpenThreadToken ( false ) ;
20512121 }
20522122
2123+ /// <summary>
2124+ /// Open the effective token, thread if available or process
2125+ /// </summary>
2126+ /// <param name="thread">The thread to open the token for</param>
2127+ /// <param name="duplicate">True to duplicate the token before returning</param>
2128+ /// <param name="throw_on_error">True to throw on error.</param>
2129+ /// <returns>The opened token</returns>
2130+ /// <exception cref="NtException">Thrown if cannot open token</exception>
2131+ public static NtResult < NtToken > OpenEffectiveToken ( NtThread thread , bool duplicate , bool throw_on_error )
2132+ {
2133+ var token = OpenThreadToken ( thread , true , duplicate , TokenAccessRights . MaximumAllowed , throw_on_error ) ;
2134+ if ( ! token . IsSuccess || token . Result != null )
2135+ return token ;
2136+
2137+ var pid = thread . GetProcessId ( throw_on_error ) ;
2138+ if ( ! pid . IsSuccess )
2139+ return pid . Cast < NtToken > ( ) ;
2140+
2141+ return OpenProcessToken ( pid . Result , duplicate , TokenAccessRights . MaximumAllowed , throw_on_error ) ;
2142+ }
2143+
20532144 /// <summary>
20542145 /// Open the effective token, thread if available or process
20552146 /// </summary>
@@ -2078,7 +2169,18 @@ public static NtToken OpenEffectiveToken(NtThread thread, bool duplicate)
20782169 /// <exception cref="NtException">Thrown if cannot open token</exception>
20792170 public static NtToken OpenEffectiveToken ( )
20802171 {
2081- return OpenEffectiveToken ( NtThread . Current , false ) ;
2172+ return OpenEffectiveToken ( true ) . Result ;
2173+ }
2174+
2175+ /// <summary>
2176+ /// Open the current effective token, thread if available or process
2177+ /// </summary>
2178+ /// <param name="throw_on_error">True to throw on error.</param>
2179+ /// <returns>The opened token</returns>
2180+ /// <exception cref="NtException">Thrown if cannot open token</exception>
2181+ public static NtResult < NtToken > OpenEffectiveToken ( bool throw_on_error )
2182+ {
2183+ return OpenEffectiveToken ( NtThread . Current , false , throw_on_error ) ;
20822184 }
20832185
20842186 /// <summary>
@@ -2227,6 +2329,23 @@ public static ThreadImpersonationContext Impersonate(int pid, SecurityImpersonat
22272329 }
22282330 }
22292331
2332+ /// <summary>
2333+ /// Get the current user.
2334+ /// </summary>
2335+ /// <param name="throw_on_error">True to throw on error.</param>
2336+ /// <returns>The current user.</returns>
2337+ public static NtResult < UserGroup > GetCurrentUser ( bool throw_on_error )
2338+ {
2339+ using ( var token = OpenEffectiveToken ( throw_on_error ) )
2340+ {
2341+ if ( ! token . IsSuccess )
2342+ {
2343+ return token . Cast < UserGroup > ( ) ;
2344+ }
2345+ return token . Result . GetUser ( throw_on_error ) ;
2346+ }
2347+ }
2348+
22302349 #endregion
22312350
22322351 #region Static Properties
0 commit comments