Marshal.SecureStringToGlobalAllocUnicode メソッド
アセンブリ: mscorlib (mscorlib.dll 内)

Dim s As SecureString Dim returnValue As IntPtr returnValue = Marshal.SecureStringToGlobalAllocUnicode(s)
戻り値
s パラメータのコピー先となったアンマネージ メモリ内のアドレス。null SecureString が提供された場合は 0。


SecureStringToGlobalAllocUnicode メソッドは、カスタム マーシャリングを実行する場合、またはマネージ コードとアンマネージ コードを混在させる場合に役立ちます。このメソッドは文字列で必要とされるアンマネージ メモリを割り当てるため、必ず ZeroFreeGlobalAllocUnicode メソッドを呼び出してメモリを解放してください。
![]() |
---|
このメソッドは SecurityAction.LinkDemand を使用して、信頼関係のないコードからの呼び出しを防ぎます。SecurityPermissionAttribute.UnmanagedCode アクセス許可は、直前の呼び出し元にのみ要求されます。信頼性が一部しか確認されていないコードから呼び出すことができるコードの場合、ユーザー入力を検証せずに Marshal クラスに渡すことは避けてください。LinkDemand メンバの使用に関する重要な制約事項については、「Demand と LinkDemand」を参照してください。 |

アンマネージ LogonUser 関数で SecureStringToGlobalAllocUnicode メソッドを使用して、SecureString クラスで偽装を実行する方法を次のコード例に示します。この例では、次に ZeroFreeGlobalAllocUnicode メソッドを使用して、アンマネージ文字列参照を消去し解放します。
Imports System Imports System.Diagnostics Imports System.Runtime.InteropServices Imports System.Security Imports System.Security.Principal Imports System.Text Module ImpersonationExample ' PInvoke into the Win32 API to provide access to the ' LogonUser and CloseHandle functions. <DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> Function LogonUser(ByVal username As String, ByVal domain As String, ByVal password As IntPtr, ByVal logonType As Integer, ByVal logonProvider As Integer, ByRef token As IntPtr) As Boolean End Function <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> Function CloseHandle(ByVal handle As IntPtr) As Boolean End Function ' Define the required LogonUser enumerations. Const LOGON32_PROVIDER_DEFAULT As Integer = 0 Const LOGON32_LOGON_INTERACTIVE As Integer = 2 Sub Main(ByVal args() As String) Try ' Display the current user before impersonation. Console.WriteLine("Before impersonation: " + WindowsIdentity.GetCurrent().Name) ' Ask the user for a network domain. Console.Write("Please enter your domain:") Dim domain As String = Console.ReadLine() ' Ask the user for a user name. Console.Write("Please enter your user name:") Dim username As String = Console.ReadLine() ' Ask the user for a password. Console.Write("Please enter your password:") Dim passWord As SecureString = GetPassword() ' Impersonate the account provided by the user. Dim userContext As WindowsImpersonationContext = ImpersonateUser(passWord, username, domain) ' Display the current user after impersonation. Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name) Catch e As Exception Console.WriteLine(e.Message) End Try Console.ReadLine() End Sub Function GetPassword() As SecureString Dim password As New SecureString() ' get the first character of the password Dim nextKey As ConsoleKeyInfo = Console.ReadKey(True) While nextKey.Key <> ConsoleKey.Enter If nextKey.Key = ConsoleKey.BackSpace Then If password.Length > 0 Then password.RemoveAt(password.Length - 1) ' erase the last * as well Console.Write(nextKey.KeyChar) Console.Write(" ") Console.Write(nextKey.KeyChar) End If Else password.AppendChar(nextKey.KeyChar) Console.Write("*") End If nextKey = Console.ReadKey(True) End While Console.WriteLine() ' lock the password down password.MakeReadOnly() Return password End Function Function ImpersonateUser(ByVal password As SecureString, ByVal userName As String, ByVal domainName As String) As WindowsImpersonationContext Dim tokenHandle As IntPtr = IntPtr.Zero Dim passwordPtr As IntPtr = IntPtr.Zero Dim returnValue As Boolean = False Try ' Marshal the SecureString to unmanaged memory. passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password) ' Call LogonUser, passing the unmanaged (and decrypted) copy of ' the SecureString password. returnValue = LogonUser(userName, domainName, passwordPtr, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, tokenHandle) Finally ' Zero-out and free the unmanaged string reference. Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr) ' Close the token handle. CloseHandle(tokenHandle) End Try ' Get the Last win32 Error and throw an exception. If Not returnValue AndAlso tokenHandle = IntPtr.Zero Then Dim [error] As Integer = Marshal.GetLastWin32Error() Throw New System.ComponentModel.Win32Exception([error]) End If ' The token that is passed to the following constructor must ' be a primary token in order to use it for impersonation. Dim newId As New WindowsIdentity(tokenHandle) Return newId.Impersonate() End Function End Module
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Security; using System.Security.Principal; using System.Text; namespace SecureStringImpersonationExample { class ImpersonationExample { // PInvoke into the Win32 API to provide access to the // LogonUser and CloseHandle functions. [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] internal static extern bool LogonUser(String username, String domain, IntPtr password, int logonType, int logonProvider, ref IntPtr token); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public extern static bool CloseHandle(IntPtr handle); // Define the required LogonUser enumerations. const int LOGON32_PROVIDER_DEFAULT = 0; const int LOGON32_LOGON_INTERACTIVE = 2; static void Main(string[] args) { try { // Display the current user before impersonation. Console.WriteLine("Before impersonation: " + WindowsIdentity.GetCurrent().Name); // Ask the user for a network domain. Console.Write("Please enter your domain:"); string domain = Console.ReadLine(); // Ask the user for a user name. Console.Write("Please enter your user name:"); string username = Console.ReadLine(); // Ask the user for a password. Console.Write("Please enter your password:"); SecureString passWord = GetPassword(); // Impersonate the account provided by the user. WindowsImpersonationContext userContext = ImpersonateUser(passWord, username, domain); // Display the current user after impersonation. Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name); } catch (Exception e) { Console.WriteLine(e.Message); } Console.ReadLine(); } public static SecureString GetPassword() { SecureString password = new SecureString(); // get the first character of the password ConsoleKeyInfo nextKey = Console.ReadKey(true); while (nextKey.Key != ConsoleKey.Enter) { if (nextKey.Key == ConsoleKey.Backspace) { if (password.Length > 0) { password.RemoveAt(password.Length - 1); // erase the last * as well Console.Write(nextKey.KeyChar); Console.Write(" "); Console.Write(nextKey.KeyChar); } } else { password.AppendChar(nextKey.KeyChar); Console.Write("*"); } nextKey = Console.ReadKey(true); } Console.WriteLine(); // lock the password down password.MakeReadOnly(); return password; } public static WindowsImpersonationContext ImpersonateUser(SecureString password, string userName, string domainName) { IntPtr tokenHandle = IntPtr.Zero; IntPtr passwordPtr = IntPtr.Zero; bool returnValue = false; try { // Marshal the SecureString to unmanaged memory. passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password); // Call LogonUser, passing the unmanaged (and decrypted) copy of // the SecureString password. returnValue = LogonUser(userName, domainName, passwordPtr, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle); } finally { // Zero-out and free the unmanaged string reference. Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr); // Close the token handle. CloseHandle(tokenHandle); } // Get the Last win32 Error and throw an exception. if (!returnValue && tokenHandle == IntPtr.Zero) { int error = Marshal.GetLastWin32Error(); throw new System.ComponentModel.Win32Exception(error); } // The token that is passed to the following constructor must // be a primary token in order to use it for impersonation. WindowsIdentity newId = new WindowsIdentity(tokenHandle); return newId.Impersonate(); } } }

- SecurityPermission (アンマネージ コードを呼び出すために必要なアクセス許可)。 UnmanagedCode (関連する列挙体)。LinkDemand (セキュリティ アクション)。

Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
開発プラットフォームの中には、.NET Framework によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。


- Marshal.SecureStringToGlobalAllocUnicode メソッドのページへのリンク