ERROR_MORE_DATA --- PVOID и C # --- неуправляемые типы - PullRequest
1 голос
/ 12 апреля 2010

Как я могу получить значение из следующей библиотеки DLL? offreg.dll.

В приведенном ниже коде я успешно открыл улей, ключ, и теперь я пытаюсь получить значение ключа и продолжаю сталкиваться с ошибкой 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 должно быть более чем достаточно.

Любая помощь будет принята с благодарностью.

Как показано выше, я пробовал построитель строк ... string ... IntPtr ... и т. Д. Ни один из которых не смог обработать PVData ...

Спасибо.

1 Ответ

1 голос
/ 07 февраля 2011

Вам нужно инициализировать 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);
...