Tom
Tom

Reputation: 21

Using PInvoke registry functions, how do I get the data from handle pointers?

Say i am using RegQueryValueEx:

http://msdn.microsoft.com/en-us/library/ms724911(v=VS.85).aspx

I can get the pointer handle to lpType, but its just an integer, how do i actually get the data lpType is pointing to?

Upvotes: 1

Views: 679

Answers (3)

Scott Solmer
Scott Solmer

Reputation: 3897

logicnp is correct.

m0s has the right idea, but I would argue about the clarity of that MSDN link. lpType should actually be of type unsigned integer. I decided to make an enum for my own sanity:

    /// <summary>Specify the data type to retrieve from the registry</summary>
    /// <remarks> https://msdn.microsoft.com/en-us/library/windows/desktop/ms724884%28v=vs.85%29.aspx </remarks>
    public enum RegDataType
    {
        /// <summary>[0] No defined value type.</summary>
        REG_NONE,

        /// <summary>[1] Null-terminated string. 
        /// It will be a Unicode or ANSI string, depending on whether you use the Unicode or ANSI functions.</summary>
        REG_SZ,

        /// <summary>[2] Null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%"). 
        /// It will be a Unicode or ANSI string, depending on whether you use the Unicode or ANSI functions.</summary>
        REG_EXPAND_SZ,

        /// <summary>[3] Binary data in any form.</summary>
        REG_BINARY,

        /// <summary>[4] 32-bit number.</summary>
        REG_DWORD,

       /* /// <summary> [4] 32-bit number in little-Endean format. This is equivalent to REG_DWORD.
          /// In little-Endean format, a multi-byte value is stored in memory from the lowest byte (the "little end") to the highest byte. 
          //// For example, the value 0x12345678 is stored as (0x78 0x56 0x34 0x12) in little-Endean format.</summary>
       */ //REG_DWORD_LITTLE_ENDIAN 4

        /// <summary>[5] 32-bit number in big-Endean format.
        /// In big-Endean format, a multi-byte value is stored in memory from the highest byte (the "big end") to the lowest byte.
        /// For example, the value 0x12345678 is stored as (0x12 0x34 0x56 0x78) in big-Endean format.</summary>
        REG_DWORD_BIG_ENDIAN,

        /// <summary>[6]Unicode symbolic link.</summary>
        REG_LINK,

        /// <summary>[7] Array of null-terminated strings that are terminated by two null characters.</summary>
        REG_MULTI_SZ,

        /// <summary>[8]Device-driver resource list.</summary>
        REG_RESOURCE_LIST,

        /// <summary>[9] </summary>
        REG_FULL_RESOURCE_DESCRIPTOR,

        /// <summary>[10] </summary>
        REG_RESOURCE_REQUIREMENTS_LIST,

        /// <summary>[11] 64-bit number.</summary>
        REG_QWORD

      /*  /// <summary>[11] A 64-bit number in little-Endean format. This is equivalent to REG_QWORD.</summary>
      */  //REG_QWORD_LITTLE_ENDIAN 11 
    }

Once you have that, you can switch by data type, marshal the pointer to the result and convert depending on the type. Since you can't marshal directly to an unsigned type, you'll want to take that into account as well. Don't forget the error handling either.

Snippet:

switch ((Enums.RegDataType)type)
    {
         case Enums.RegDataType.REG_SZ:
            return Marshal.PtrToStringAnsi(pResult);

         case Enums.RegDataType.REG_DWORD:
              int DWORDCouldBeNegative = Marshal.ReadInt32(pResult);
              uint DWORDCastBackToUInt = (uint)DWORDCouldBeNegative;
              return DWORDCastBackToUInt.ToString();

         case Enums.RegDataType.REG_QWORD:
              Int64 QWORDCouldBeNegative = Marshal.ReadInt64(pResult);
              UInt64 QWORDCastBackToUInt = (UInt64)QWORDCouldBeNegative;
              return QWORDCastBackToUInt.ToString();

         case Enums.RegDataType.REG_BINARY:   ...

Upvotes: -1

logicnp
logicnp

Reputation: 5836

'lpType' does not point to the actual data, the actual data is returned in the 'lpData' parameter.

Upvotes: 1

m0s
m0s

Reputation: 4280

As it clearly tells says on MSDN it is just an integer... its just an enum from 0 to 7 where 0 is REG_NONE ... 7 is REG_MULTI_SZ. Check out here for more detail Look under key types.

Upvotes: 1

Related Questions