ERROR_MORE_DATA --- PVOID和C#---非托管类型

时间:2010-04-12 18:26:40

标签: c# dll registry unmanaged

如何从以下DLL获取值? offreg.dll。

在我的下面代码中,我已经成功打开了hive,密钥,现在我正在尝试获取密钥的值,并且我一直遇到ERROR_MORE_DATA(234)错误。

这是C ++ .dll:

DWORD
ORAPI
ORGetValue (
    __in ORHKEY     Handle,
    __in_opt PCWSTR lpSubKey,
    __in_opt PCWSTR lpValue,
    __out_opt PDWORD pdwType,
    __out_bcount_opt(*pcbData) PVOID pvData,
    __inout_opt PDWORD pcbData
    );

这是我的C#代码:

        [DllImport("offreg.dll", CharSet = CharSet.Auto, EntryPoint = "ORGetValue", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
        public static extern uint ORGetValue(IntPtr Handle, string lpSubKey, string lpValue, out uint pdwType, out StringBuilder pvData, out uint pcbData);

            IntPtr myHive;            
            IntPtr myKey;
            StringBuilder myValue = new StringBuilder("", 256);
            uint pdwtype;
            uint pcbdata;

 uint ret3 = ORGetValue(myKey, "", "DefaultUserName", out pdwtype, out myValue, out pcbdata);

所以问题似乎是围绕 PVOID pvData 我似乎无法获得正确的类型或缓冲区大小。总是出现234错误。

注意:运行此命令时pcbdata = 28 ...所以256应该绰绰有余。

非常感谢任何帮助。

如上所示,我已经尝试过字符串构建器...字符串... IntPtr ...等等都没有能够处理出PVData ...

谢谢。

1 个答案:

答案 0 :(得分:1)

你需要在传入之前将pcbData初始化为缓冲区的大小。记住C不知道你传递的缓冲区有多大,进入的pcbData值告诉函数pvData有多大。在你的情况下,你传入零,告诉OrGetValue你pvData是一个0字节缓冲区,所以它响应告诉你它需要一个更大的缓冲区。

因此,在您的PInvoke定义中,pcbData应该是一个ref参数并且具有非零值:

[DllImport("offreg.dll", CharSet = CharSet.Auto, EntryPoint = "ORGetValue", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public static extern uint ORGetValue(IntPtr Handle, string lpSubKey, string lpValue, out uint pdwType, out StringBuilder pvData, ref uint pcbData);

IntPtr myHive;            
IntPtr myKey;
StringBuilder myValue = new StringBuilder("", 256);
uint pdwtype;
uint pcbdata = myValue.Capacity();

uint ret3 = ORGetValue(myKey, "", "DefaultUserName", out pdwtype, out myValue, ref pcbdata);