source: branches/eraser6/CodeReview/Eraser.Util/AdvApi.cs @ 1543

Revision 1543, 5.7 KB checked in by lowjoel, 5 years ago (diff)

Moved all the NativeMethods? declarations to the NativeMethods? folder with filenames equal to the DLL the functions import from. Addresses #284: Eraser.Util rewrite

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 * Copyright 2009 The Eraser Project
4 * Original Author: Joel Low <lowjoel@users.sourceforge.net>
5 * Modified By:
6 *
7 * This file is part of Eraser.
8 *
9 * Eraser is free software: you can redistribute it and/or modify it under the
10 * terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later
12 * version.
13 *
14 * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 *
18 * A copy of the GNU General Public License can be found at
19 * <http://www.gnu.org/licenses/>.
20 */
21
22using System;
23using System.Collections.Generic;
24using System.Text;
25using System.ComponentModel;
26using System.Security.Principal;
27using System.Runtime.InteropServices;
28
29namespace Eraser.Util
30{
31    public static class AdvApi
32    {
33        /// <summary>
34        /// Checks whether the current process is running with administrative
35        /// privileges.
36        /// </summary>
37        /// <returns>True if the user is an administrator. This only returns
38        /// true under Vista when UAC is enabled and the process is elevated.</returns>
39        public static bool IsAdministrator()
40        {
41            WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
42            return principal.IsInRole(WindowsBuiltInRole.Administrator);
43        }
44
45        /// <summary>
46        /// Checks whether the current process is running with administrative privileges.
47        /// </summary>
48        /// <returns>Returns true if UAC is enabled under Vista. Will return false
49        /// under pre-Vista OSes</returns>
50        public static bool UacEnabled()
51        {
52            //Check whether we're on Vista
53            if (Environment.OSVersion.Platform != PlatformID.Win32NT ||
54                Environment.OSVersion.Version < new Version(6, 0))
55            {
56                //UAC doesn't exist on these platforms.
57                return false;
58            }
59
60            //Get the process token.
61            SafeTokenHandle hToken = new SafeTokenHandle();
62            bool result = NativeMethods.OpenProcessToken(NativeMethods.GetCurrentProcess(),
63                NativeMethods.TOKEN_QUERY, out hToken);
64            if (!result || hToken.IsInvalid)
65                throw KernelApi.GetExceptionForWin32Error(Marshal.GetLastWin32Error());
66
67            IntPtr pElevationType = Marshal.AllocHGlobal(Marshal.SizeOf(
68                typeof(NativeMethods.TOKEN_ELEVATION_TYPE)));
69            try
70            {
71                //Get the token information for our current process.
72                uint returnSize = 0;
73                result = NativeMethods.GetTokenInformation(hToken,
74                    NativeMethods.TOKEN_INFORMATION_CLASS.TokenElevationType,
75                    pElevationType, sizeof(NativeMethods.TOKEN_ELEVATION_TYPE),
76                    out returnSize);
77
78                //Check the return code
79                if (!result)
80                    throw KernelApi.GetExceptionForWin32Error(Marshal.GetLastWin32Error());
81
82                NativeMethods.TOKEN_ELEVATION_TYPE elevationType =
83                    (NativeMethods.TOKEN_ELEVATION_TYPE)Marshal.PtrToStructure(
84                        pElevationType, typeof(NativeMethods.TOKEN_ELEVATION_TYPE));
85                return elevationType != NativeMethods.TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault;
86            }
87            finally
88            {
89                Marshal.FreeHGlobal(pElevationType);
90            }
91        }
92    }
93
94    public sealed class CryptApi : IDisposable
95    {
96        /// <summary>
97        /// Constructor.
98        /// </summary>
99        private CryptApi()
100        {
101            /* Intel i8xx (82802 Firmware Hub Device) hardware random number generator */
102            const string IntelDefaultProvider = "Intel Hardware Cryptographic Service Provider";
103
104            handle = new SafeCryptHandle();
105            if (NativeMethods.CryptAcquireContext(out handle, string.Empty,
106                IntelDefaultProvider, NativeMethods.PROV_INTEL_SEC, 0))
107            {
108                return;
109            }
110            else if (NativeMethods.CryptAcquireContext(out handle, string.Empty,
111                string.Empty, NativeMethods.PROV_RSA_FULL, 0))
112            {
113                return;
114            }
115            else if (Marshal.GetLastWin32Error() == NativeMethods.NTE_BAD_KEYSET)
116            {
117                //Default keyset doesn't exist, attempt to create a new one
118                if (NativeMethods.CryptAcquireContext(out handle, string.Empty, string.Empty,
119                    NativeMethods.PROV_RSA_FULL, NativeMethods.CRYPT_NEWKEYSET))
120                {
121                    return;
122                }
123            }
124
125            throw new NotSupportedException("Unable to acquire a cryptographic service provider.");
126        }
127
128        #region IDisposable Members
129        ~CryptApi()
130        {
131            Dispose(false);
132        }
133
134        public void Dispose(bool disposing)
135        {
136            if (disposing)
137                handle.Close();
138        }
139
140        public void Dispose()
141        {
142            Dispose(true);
143            GC.SuppressFinalize(this);
144        }
145        #endregion
146
147        /// <summary>
148        /// The GenRandom function fills a buffer with cryptographically random bytes.
149        /// </summary>
150        /// <param name="buffer">Buffer to receive the returned data. This buffer
151        /// must be at least dwLen bytes in length.
152        ///
153        /// Optionally, the application can fill this buffer with data to use as
154        /// an auxiliary random seed.</param>
155        public static bool CryptGenRandom(byte[] buffer)
156        {
157            return NativeMethods.CryptGenRandom(instance.handle, (uint)buffer.Length, buffer);
158        }
159
160        /// <summary>
161        /// The HCRYPTPROV handle.
162        /// </summary>
163        private SafeCryptHandle handle;
164
165        /// <summary>
166        /// The global CryptAPI instance.
167        /// </summary>
168        private static CryptApi instance = new CryptApi();
169    }
170
171    internal class SafeCryptHandle : SafeHandle
172    {
173        public SafeCryptHandle()
174            : base(IntPtr.Zero, true)
175        {
176        }
177
178        public override bool IsInvalid
179        {
180            get { return handle == IntPtr.Zero; }
181        }
182
183        protected override bool ReleaseHandle()
184        {
185            NativeMethods.CryptReleaseContext(handle, 0u);
186            handle = IntPtr.Zero;
187            return true;
188        }
189    }
190
191    internal class SafeTokenHandle : SafeHandle
192    {
193        public SafeTokenHandle()
194            : base(IntPtr.Zero, true)
195        {
196        }
197
198        public override bool IsInvalid
199        {
200            get { return handle == IntPtr.Zero; }
201        }
202
203        protected override bool ReleaseHandle()
204        {
205            NativeMethods.CloseHandle(handle);
206            handle = IntPtr.Zero;
207            return true;
208        }
209    }
210}
Note: See TracBrowser for help on using the repository browser.