Decoding IntPtr to MultiString

I need to extract environment strings from a call CreateEnvironmentBlock( out IntPtr lpEnvironment, IntPtr hToken, bool bInherit )

to put them into a dictionary based on the variable name and its value.

When this function returns, it lpEnvironment

gets a pointer to a new environment block. The environment block is an array of nullable Unicode strings. The list ends with two zeros ( \0\0

).

I can't use it easily Marshal.Copy

as I don't know the block length. I'm wondering if there is an easy way to move around it, or figure out what to copy to something that I can then convert more easily. One thought was to convey out IntPtr lpEnvironment

how out char [] lpEnvironment

.

Any suggestions?

+3


source to share


1 answer


You don't know the full length for Marshal.Copy()

, however you know the length of the first line if you do Marshal.PtrToString()

. With this knowledge, you can move on to the next line and so on until you read a blank line, which indicates that only the \0

end of a multi-line line was present at that address .

Note that the following code assumes that Unicode is available and uses it.



[DllImport("userenv.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool CreateEnvironmentBlock(ref IntPtr lpEnvironment,IntPtr hToken,bool bInherit);

static IEnumerable<string> ExtractMultiString(IntPtr ptr)
{
    while (true)
    {
        string str = Marshal.PtrToStringUni(ptr);
        if (str.Length == 0)
            break;
        yield return str;
        ptr = new IntPtr(ptr.ToInt64() + (str.Length + 1 /* char \0 */) * sizeof(char));
    }
}

      

+2


source







All Articles