How is the securestring ordered into unmanaged code?

What caused this question: I am trying to change the account under which the windows service is running. I decided to use win32 api instead of WMI and started looking for ChangeServiceConfig.

I thought I could just use the SecureString type in the unmanaged method signature and it would work fine. Hmm, not really. This got me thinking, does anyone know what type of native (win32) SecureString class is sorted as (default) unmanaged code?

+2


source to share


4 answers


I didn't get an answer to the question in the title, so I still don't know that SecureString is configured for unmanaged code.

I did however get my code working using suggestions in some of the other answers. I have provided the code below.

internal static class NativeService
{
    ...
    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool ChangeServiceConfig(IntPtr hService, uint nServiceType, uint nStartType, uint nErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, [In] char[] lpDependencies, string lpServiceStartName, IntPtr lpPassword, string lpDisplayName);
    ...
    public const uint SERVICE_NO_CHANGE = 0xffffffff;
}

internal class ClassThatConfiguresService
{
    ...
    public void ConfigureStartupAccount(IntPtr service, string userName, SecureString password)
    {
        passwordPointer = Marshal.SecureStringToGlobalAllocUnicode(password);
        try
        {
            if(!NativeService.ChangeServiceConfig(service, NativeService.SERVICE_NO_CHANGE, NativeService.SERVICE_NO_CHANGE, NativeService.SERVICE_NO_CHANGE, null, null, IntPtr.Zero, null, userName, passwordPointer, null))
                throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        finally
        {
            Marshal.ZeroFreeGlobalAllocUnicode(passwordPointer);
        }
    }
    ...
}

      



Instead of Marshal.SecureStringToBSTR I used Marshal.SecureStringToGlobalAllocUnicode because that's what the unmanaged function expects, but other than that it works.

Hope someone finds this helpful. Cap.

+5


source


It looks like you can use the helper functions in the namespace InteropServices

to help you do this:

Note that SecureString has no members that check, compare, or convert the SecureString value. The absence of such elements helps to protect the value of an instance from accidental or malicious attack. Use the appropriate System.Runtime.InteropServices .. :: members. A class marshal, such as the SecureStringToBSTR method, to manipulate the value of a SecureString object.



You can use SecureStringToBSTR to convert the string to BSTR

and then pass it to the appropriate function for use.

+4


source


+2


source


SecureString is non-blittable . So - there is no win32 1: 1 type.

Keep in mind that I am not a COM expert at all.

0


source







All Articles