csharp: extern DllImport with forced default argument - c#

I have the following function defined in a dll. The important part is the first mkrt argument, this argument have to be IntPtr.Zero and should not be part of the public api.
update the mkrt is just a pointer to my internal runtime, this is thread-local-storage struct used to provide per-thread attributes. the IntPtr.Zero just indicate to resolve the mkrt internally and not use the mkrt direct.
[DllImport(MkSetupC.DLL, CallingConvention=MkSetupC.CC, CharSet=MkSetupC.CS, EntryPoint = "MkBufferCreate1024_RT")]
internal static extern IntPtr MkBufferCreate1024 (IntPtr mkrt, Int32 size);
I have not found anything to set this IntPtr.Zero direct into the declaration.
not working:
[DllImport(MkSetupC.DLL, CallingConvention=MkSetupC.CC, CharSet=MkSetupC.CS, EntryPoint = "MkBufferCreate1024_RT")]
internal static extern IntPtr MkBufferCreate1024 (IntPtr mkrt = IntPtr.Zero, Int32 size);
Error: Optional parameter cannot precede required parameters
[DllImport(MkSetupC.DLL, CallingConvention=MkSetupC.CC, CharSet=MkSetupC.CS, EntryPoint = "MkBufferCreate1024_RT")]
internal static extern IntPtr MkBufferCreate1024 (IntPtr.Zero, Int32 size);
Error: Unexpected symbol `,', expecting identifier
An other possibility is to create an wrapper like a ... → __VA_ARGS__ wrapper in C
[DllImport(MkSetupC.DLL, CallingConvention=MkSetupC.CC, CharSet=MkSetupC.CS, EntryPoint = "MkBufferCreate1024_RT")]
private static extern IntPtr MkBufferCreate1024_RT (IntPtr mkrt, Int32 size);
What is the replacement for __VA_ARGS__ in C# ?
internal static IntPtr MkBufferCreate1024(...) {
MkBufferCreate1024_RT(IntPtr.Zero, __VA_ARGS__);
}

Related

Using ObRegisterCallbacks With C#

So I am trying to use C# and the ObRegisterCallbacks function to get notified about any calls to OpenProcess.
This is the code I have so far:
internal static class Win32SelfProtection
{
[DllImport("NtosKrnl.exe", SetLastError = true, PreserveSig = false)]
private static extern uint ObRegisterCallbacks(IntPtr callbackRegistration, out IntPtr registrationHandle);
[DllImport("NtosKrnl.exe", SetLastError = true, PreserveSig = false)]
private static extern void ObUnRegisterCallbacks(IntPtr registrationHandle);
[DllImport("kernel32.dll")]
internal static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect);
private const uint OB_OPERATION_HANDLE_CREATE = 0x00000001;
private const uint OB_OPERATION_HANDLE_DUPLICATE = 0x00000002;
private const uint PAGE_READWRITE = 0x04;
[StructLayout(LayoutKind.Sequential)]
internal struct OB_CALLBACK_REGISTRATION
{
internal ushort Version;
internal ushort OperationRegistrationCount; // 1
internal IntPtr Altitude;
internal IntPtr RegistrationContext; // NULL, probably
internal IntPtr OperationRegistration; // OB_OPERATION_REGISTRATION*
}
[StructLayout(LayoutKind.Sequential)]
internal struct OB_OPERATION_REGISTRATION
{
internal IntPtr ObjectType; // PsProcessType
internal uint Operations; // OB_OPERATION_HANDLE_CREATE
internal IntPtr PreOperation; // POB_PRE_OPERATION_CALLBACK
internal IntPtr PostOperation; // POB_POST_OPERATION_CALLBACK
}
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct UNICODE_STRING
{
internal ushort Length;
internal ushort MaximumLength;
internal IntPtr Buffer;
}
internal static unsafe void Protect()
{
PobPreOperationCallback preOperationCallback = PreOperationCallback;
IntPtr pPreOperationCallback = Marshal.GetFunctionPointerForDelegate(preOperationCallback);
PobPostOperationCallback postOperationCallback = PostOperationCallback;
IntPtr pPostOperationCallback = Marshal.GetFunctionPointerForDelegate(postOperationCallback);
OB_OPERATION_REGISTRATION operationRegistration = new OB_OPERATION_REGISTRATION
{
ObjectType = IntPtr.Zero, // I have no idea ... <-- Need pointer to PsProcessType
Operations = OB_OPERATION_HANDLE_CREATE,
PreOperation = pPreOperationCallback,
PostOperation = pPostOperationCallback
};
IntPtr pOperationRegistration = Marshal.AllocHGlobal(sizeof(OB_OPERATION_REGISTRATION));
Marshal.StructureToPtr(operationRegistration, pOperationRegistration, false);
const ushort buffersize = sizeof(ushort) * 64;
IntPtr buffer = Marshal.AllocHGlobal(buffersize);
// No idea what kind of string I should put in here :C just zero it for now ...
Marshal.Copy(new byte[buffersize], 0, buffer, buffersize);
UNICODE_STRING unicodeString = new UNICODE_STRING
{
Length = buffersize,
MaximumLength = buffersize,
Buffer = buffer
};
IntPtr pUnicodeString = Marshal.AllocHGlobal(sizeof(UNICODE_STRING));
Marshal.StructureToPtr(unicodeString, pUnicodeString, false);
OB_CALLBACK_REGISTRATION callbackRegistration = new OB_CALLBACK_REGISTRATION
{
Version = 0x0100,
OperationRegistrationCount = 1,
Altitude = pUnicodeString,
RegistrationContext = IntPtr.Zero,
OperationRegistration = pOperationRegistration
};
IntPtr pCallbackRegistration = Marshal.AllocHGlobal(sizeof(OB_CALLBACK_REGISTRATION));
Marshal.StructureToPtr(callbackRegistration, pCallbackRegistration, false);
uint status = ObRegisterCallbacks(pCallbackRegistration, out IntPtr hRegistration); // FAILS WITH: AccessViolationException
// yeah, yeah I'll remember to call Marshal.FreeHGlobal() later ... :D
}
public delegate uint PobPreOperationCallback(IntPtr registrationContext, IntPtr operationInformation);
// dummy method for now
internal static uint PreOperationCallback(IntPtr registrationContext, IntPtr operationInformation)
{
Console.WriteLine("PreOperationCallback!");
return 0x0;
}
public delegate void PobPostOperationCallback(IntPtr registrationContext, IntPtr operationInformation);
// dummy method for now
internal static void PostOperationCallback(IntPtr registrationContext, IntPtr operationInformation)
{
Console.WriteLine("PostOperationCallback!");
}
}
The ObRegisterCallbacks function takes an OB_CALLBACK_REGISTRATION struct (docs here) as parameter that itself consists of an array of OB_OPERATION_REGISTRATION structs (docs here).
This is where I'm stuck:
The OB_OPERATION_REGISTRATION's first member, "ObjectType", is documented as follows
ObjectType
A pointer to the object type that triggers the callback routine. Specify one of the following values:
PsProcessType for process handle operations
PsThreadType for thread handle operations
ExDesktopObjectType for desktop handle operations. This value is supported in Windows 10 and not in the earlier versions of the operating system.
After a few hour of searching I still have no clue how I'm supposed to specify PsProcessType and initialize my struct with it. PsProcessType seems to be defined in process.c in line 20.
However it literally just says
POBJECT_TYPE PsProcessType = NULL;
which isn't especially helpful, since when setting the ObjectType field to IntPtr.Zero when initializing the OB_OPERATION_REGISTRATION struct a System.AccessViolationException is triggered when calling ObRegisterCallbacks. (There's also a UNICODE_STRING in the OB_OPERATION_REGISTRATION struct called Altitude that has to be set to some value (but currently isn't lol :D), but that string is initialized and allocated, so it shouldn't be responsible for the access violation... right?)
This is my first time diving this deep into Windows kernel stuff, so it would be nice if someone could help me out with this or point me to some hidden resources I didn't manage to dig up :)
There's an article that uses ObRegisterCallbacks for similar things (in C++ though), however they don't really specify where they're getting PsProcessType from, or how it's defined. So there has to be documentation somewhere out there, if they can successfully use that "ObjectType" field, right?
PsProcessType is exported at ntoskrnl.exe and is the same as ObRegisterCallbacks, the difference between them is that one is an exported global variable and the other is an exported function.
In C, these global variables are declared in wdm.h:
extern POBJECT_TYPE *CmKeyObjectType;
extern POBJECT_TYPE *IoFileObjectType;
extern POBJECT_TYPE *ExEventObjectType;
extern POBJECT_TYPE *ExSemaphoreObjectType;
extern POBJECT_TYPE *TmTransactionManagerObjectType;
extern POBJECT_TYPE *TmResourceManagerObjectType;
extern POBJECT_TYPE *TmEnlistmentObjectType;
extern POBJECT_TYPE *TmTransactionObjectType;
extern POBJECT_TYPE *PsProcessType;
extern POBJECT_TYPE *PsThreadType;
extern POBJECT_TYPE *PsJobType;
extern POBJECT_TYPE *SeTokenObjectType;
#if (NTDDI_VERSION >= NTDDI_THRESHOLD)
extern POBJECT_TYPE *ExDesktopObjectType;
#endif
So you can just use these variables without having to do anything else.
But I'm not good at C#, and I'm not even sure if C# modules can be loaded into the kernel.
The most recommended approach is to use C/C++ for kernel programming, and I've never heard of anyone doing this with C#.

get string value from registry using p/invoke (Silverlight)

I am trying to find the COM port assigned to a USB device, through the registry using Silverlight, and have tried the following:
dynamic WshShell = AutomationFactory.CreateObject("WScript.Shell");
string strRegKeyUSB = #"HKLM\HARDWARE\DEVICEMAP\SERIALCOMM\\Device\USB_COM";
string strCOMValue = WshShell.RegRead(strRegKeyUSB);
This approach usually works 100%, but all Value names under the DEVICEMAP Key is "\Device\XXX"
This causes the the "Path" to not be found, as the "\\" between SERIALCOMM and Device is not seen as valid (Throws Error: "Cannot find File Specified")
This, as far as I can see, only really leaves me with one option - P/Invoke, in Silverlight 5
I am using P/Invoke already for a SerialWrapper Class, to Open, Read, Write the COM Ports, and would like to include only the minimal needed to only read this one Key Value from the Registry - I have tried following some examples I have found, but not being strong in Interop, P/Invoke, etc. I am struggling to find only the portions I need.
If someone could please just give me a basic example, to only accomplish this (I do NOT need to write to the registry, or read QWORDS, or anything else - Only read this string value from only this specific key)
I have tried following the following post (Marshal.PtrToStructure in Silverlight) and it's answer, in relation to this (http://www.pinvoke.net/default.aspx/winspool.enumports), but have not been able to get this working, Most likely form a lack of REALLY understanding ;-)
Here's a simple desktop application that reads a REG_SZ value. It's crude and simple. It will read the value that you want. You may have to adapt it to Silverlight. I cannot help you there!
I hope this is useful:
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
namespace ConsoleApplication1
{
internal static class NativeMethods
{
public const int ERROR_SUCCESS = 0;
public const uint HKEY_LOCAL_MACHINE = 0x80000002;
public const int KEY_READ = 0x20019;
[DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
public static extern int RegOpenKeyEx(
UIntPtr hKey,
string subKey,
int ulOptions,
int samDesired,
out UIntPtr hkResult
);
[DllImport("advapi32.dll")]
public static extern int RegCloseKey(
UIntPtr hKey
);
[DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
public static extern int RegQueryValueEx(
UIntPtr hKey,
string lpValueName,
int lpReserved,
IntPtr type,
IntPtr lpData,
ref int lpcbData
);
}
internal static class RegistryWrapper
{
private static void checkErrorCode(int errorCode)
{
if (errorCode != NativeMethods.ERROR_SUCCESS)
throw new Win32Exception(errorCode);
}
public static string ReadRegString(UIntPtr rootKey, string subKey, string name)
{
UIntPtr hkey;
checkErrorCode(NativeMethods.RegOpenKeyEx(rootKey, subKey, 0, NativeMethods.KEY_READ, out hkey));
try
{
int cbData = 0;
checkErrorCode(NativeMethods.RegQueryValueEx(hkey, name, 0, IntPtr.Zero, IntPtr.Zero, ref cbData));
IntPtr ptr = Marshal.AllocHGlobal(cbData);
try
{
checkErrorCode(NativeMethods.RegQueryValueEx(hkey, name, 0, IntPtr.Zero, ptr, ref cbData));
return Marshal.PtrToStringUni(ptr, cbData / sizeof(char)).TrimEnd('\0');
}
finally
{
Marshal.FreeHGlobal(ptr);
}
}
finally
{
checkErrorCode(NativeMethods.RegCloseKey(hkey));
}
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(RegistryWrapper.ReadRegString((UIntPtr)NativeMethods.HKEY_LOCAL_MACHINE, #"HARDWARE\DEVICEMAP\SERIALCOMM", #"\Device\Serial0"));
}
}
}
Update
It seems that AllocHGlobal and FreeHGlobal are not available on Silverlight. You can p/invoke to LocalAlloc and LocalFree instead. Or you could use CoTaskMemAlloc and CoTaskMemFree. Here's what the former looks like:
[DllImport("kernel32.dll", SetLastError=true)]
static extern IntPtr LocalAlloc(uint uFlags, UIntPtr uBytes);
[DllImport("kernel32.dll", SetLastError=true)]
static extern IntPtr LocalFree(IntPtr hMem);
Define LMEM_FIXED like this:
const uint LMEM_FIXED = 0x0000;
Then replace the call to AllocHGlobal with this:
IntPtr ptr = LocalAlloc(LMEM_FIXED, cbData);
And replace the call to FreeHGlobal with this:
LocalFree(ptr);
A BIG thank you to #Dave Heffernan,
I got this to work FINALLY...
I Added the following code within the RegistryWrapper class in Dave's Answer:
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr LocalAlloc(uint uFlags, int size);
internal static IntPtr AllocHGlobal(int size)
{
uint LPTR = (uint)0x0040;
IntPtr hGlobal = LocalAlloc(LPTR, size);
if (hGlobal == IntPtr.Zero)
{
throw new OutOfMemoryException("Unmanaged memory was not allocated.");
}
return hGlobal;
}
This works around the limitation of Marshal.AllocHGlobal not being available in Silverlight.
I then also just changed the reference to Marshal.AllocHGlobal to the local AllocHGlobal method above.

How to import void ** C++ API into C#?

In c++ API Declaration is
BOOL DCAMAPI dcam_attachbuffer ( HDCAM h, void** top, _DWORD size );
arguments :
void** top--- is the array of pointer to buffer
_DWORD size-- is size of top parameter in bytes
In c#, this is how I import the dll file:
[DllImport("dcamapi.dll", EntryPoint = "dcam_attachbuffer",
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi, BestFitMapping = false,
ThrowOnUnmappableChar = true)]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
public static extern bool dcam_attachbuffer(IntPtr handleCamera,
[MarshalAsAttribute(UnmanagedType.LPArray)]ref Int32[] buf,
[MarshalAsAttribute(UnmanagedType.U4)] Int32 bufsize);
My question is do I convert the type from c++ into c# correctly? and How do I declare void**in c#? please help me.
It is depending on what function dcam_attachbuffer do.
If it's taking buffer, define method
[DllImport("dcamapi.dll", EntryPoint = "dcam_attachbuffer"]
public static extern bool dcam_attachbuffer(
IntPtr handleCamera,
IntPtr ptrsBuf,
Int32 bufSize);
and pass pointer derived earlier.
If function is getting pointer of pointers, define method
[DllImport("dcamapi.dll", EntryPoint = "dcam_attachbuffer"]
public static extern bool dcam_attachbuffer(
IntPtr handleCamera,
ref IntPtr ptrsBuf,
Int32 bufSize);
and use
System.Runtime.InteropServices.Marshal.Copy(
IntPtr source,
IntPtr[] destination,
int startIndex,
int length
)
to copy pointers in IntPtr[]
You can declare pointers directly in C# in unsafe blocks.
There's also IntPtr.
Or you can write some C++/CLI to glue the two together.
The argument is IntPtr[] (no ref). With the unnecessary attributes removed:
[DllImport("dcamapi.dll")]
public static extern bool dcam_attachbuffer(IntPtr handleCamera,
IntPtr[] buf, int bufsize);
Correctly initializing the array could be a challenge as well, it is quite unclear from the question what is required.

A Problem in Pinvoke

I have the following function in C++ native dll, and I want to use it in a C# app.
DWORD __cdecl Foo(
LPCTSTR Input,
TCHAR** Output,
DWORD Options,
ErroneousWord** List = NULL,
LPDWORD Count = 0
);
Using Pinvoke
[DllImport("dllName", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 Foo(string InputWord, out string Output, UInt32 Options, out object List,out UInt32 Count);
Calling code:
string output;
object dummyError = null;
uint dummyCount = 0;
uint x = 0;
Foo(Text, out output, x | y,out dummyError,out dummyCount);
I got the following exception
Attempted to read or write protected
memory. This is often an indication
that other memory is corrupt
P.S:
ErroneousWord is struct and I do not need its output, so I marshal it as object
That error more than likely means that you have a marshaling problem.
You don't show us what the ErroneousWord type is, but I assume it's some kind of class defined in your C++ code. My guess is that it's not being marshaled correctly to a .NET object.
Considering that it's a pointer (or a pointer to a pointer), try changing that parameter to an IntPtr type to represent a pointer, instead. It shouldn't matter, since you're simply passing NULL for the argument anyway, easily represented using the static IntPtr.Zero field.
You probably also want to marshal Output the exact same way. If you change the parameter to an IntPtr type, you'll receive a pointer to a TCHAR*, which you can then pass to the other unmanaged functions however you see fit (e.g., to free it).
Try the following code:
[
DllImport("dllName",
CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl)
]
public static extern UInt32 Foo(
string InputWord,
out IntPtr Output, // change to IntPtr
UInt32 Options,
out IntPtr List, // change to IntPtr
out UInt32 Count);
IntPtr output;
IntPtr dummyError = IntPtr.Zero;
uint dummyCount = 0;
uint x = 0;
Foo(Text, out output, x | y, out dummyError, out dummyCount);
You might also need to use the Marshal.AllocHGlobal method to allocate unmanaged memory from your process that is accessible to the C++ code. Make sure that if you do so, you also call the corresponding Marshal.FreeHGlobal method to release the memory.
Given Cody's answer and the comments, you will have to do it this way:
[DllImport("dllName", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
extern static UInt32 Foo(string InputWord, out IntPtr Output, UInt32 Options, out IntPtr List, out UInt32 Count);
Now to get the string value in Output marshalled over to managed memory you will do:
string outputValue = Marshal.PtrToStringAnsi(Output);
You must know if TCHAR is Ansi or Unicode and use the appropriate marshal.
Remember to hang onto the Output IntPtr so you can pass that to the native Free method.
Thanks Cody for your answer but I want to make a seperate one, first Output is created by Foo from the native side, and I call FreeFoo to free the allocated memory by Foo.
The following is the code
[DllImport("dllname", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 Correct(string InputWord, out IntPtr Output, UInt32 Options, out object List,out UInt32 Count);
[DllImport("dllname", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public static extern void FreeFoo(IntPtr Output);
}
To use it:
public string FooWrapper(string Text)
{
IntPtr output;
object dummyError = null;
uint dummyCount = 0;
uint x = 0;
Foo(Text, out output, x,out dummyError,out dummyCount);
string str = Marshal.PtrToStringUni(output);
FreeFoo(output);
return str;
}
Whatever the ErroneousWord type is, you can't marshal an array as a single out object. If it is at all possible to marshal as an object...

C++ function calling from C# application. Attempted to read or write protected memory

The problem below is ralated to my previous question
Converting static link library to dynamic dll
My first step was to develop a dll, that was done. (Thanks John Knoeller prakash. Your input was very helpful)
Now when i call the function in the dll from my c# application i get the error
"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Here is the C++ definition
extern "C" DEMO2_API void Decompress(char* inp_buff, unsigned short*
inp_len, char* buffer_decomp,unsigned *output_len,unsigned short* errorCode);
My C# Converstion p/Involke
private static extern void Decompress(
byte[] inp_buff,
ref ushort inp_len,
byte[] buffer_decomp,
ref int output_len,
ref ushort errorCode
);
And I am calling it as below
byte[] dst = new byte[2048];
int outlen = 2048;
ushort errorCode = 0;
Decompress(src, (ushort )src.Length, dst, ref outlen,ref errorCode);
return dst;
What is wrong?
I see a signature mismatch on the inp_len parameter. In the C++ definition you use a pointer to a short unsigned int, while in the C# method you use a ushort.
for pointers you must use IntPtr .net type
#necrostaz
It is not necessary that we use IntPtr for pointers.
Look below all of these four declarations are valid and currently i am using it.
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, String lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, StringBuilder lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, String lParam);
question is still open
In addition to the missing "ref" on the inp_len declaration that Maurits pointed out, you need to make sure that your pointer sizes match.
If you're running on a 32-bit operating system you should be OK, but if your code runs on 64-bit too, then you need to ensure that either:
You mark your .net entry assembly as x86 (not Any CPU)
or
You supply a 32-bit and 64-bit build of the C++ dll and install the correct one for the interop to call.
I have had the same problem two years ago. In my case the reason for the access violation was that the memory was allocated outside the DLL. As a solution I added two functions for memory allocation and deallocation to the DLL.
Another solution could be a change of the .net security settings. Some keywords are "Code Access Security Police Tool" (caspol.exe) and ".NET Framework Configuration Tool" (mscorcfg.msc). In VS there is also a security tab in the project property dialog. I'm not an expert in .net security so someone else should know more details.
The following code runs without any problems. It's very similar to yours:
C++:
extern "C" __declspec(dllexport) void TestFunction(char* inp_buff,
unsigned short* inp_len,
char* buffer_decomp,
unsigned *output_len,
unsigned short* errorCode)
{
//copy input buffer to output buffer
int size = min(*inp_len,*output_len);
for(int i=0; i<size; i++)
buffer_decomp[i] = inp_buff[i];
errorCode = 0;
}
C#:
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("TEST.DLL")]
public static extern void TestFunction(byte[] inp_buff,
ref ushort inp_len,
byte[] out_buff,
ref int out_len,
ref ushort errorCode);
static void Main(string[] args)
{
//prepare input buffer
byte[] inp_buff = new byte[20];
inp_buff[0] = (byte)'T';
inp_buff[1] = (byte)'E';
inp_buff[2] = (byte)'S';
inp_buff[3] = (byte)'T';
ushort inp_len = (ushort)inp_buff.Length;
//prepare output buffer
byte[] out_buff = new byte[20];
int out_len = out_buff.Length;
ushort errorCode = 0;
TestFunction(inp_buff, ref inp_len, out_buff, ref out_len, ref errorCode);
//see if copying was successful
for(int i=0; i<out_len; i++)
Console.Out.Write(out_buff[i]);
}
}
Try it out. I have taken a look at the open parts of the library you are using. Here is a direct excerpt of the function lzo_decomp:
in = lzo_malloc(IN_LEN);
out = lzo_malloc(OUT_LEN);
wrkmem = lzo_malloc(LZO1Z_999_MEM_COMPRESS);
if (in == NULL || out == NULL || wrkmem == NULL)
{
printf("out of memory\n");
}
in_len = IN_LEN;
lzo_memset(in,0,in_len );
lzo_memset ( out, 0, OUT_LEN );
memcpy ( out, &input_buffer, inp_buff_len);
lzo_free(wrkmem);
lzo_free(out);
lzo_free(in);
r = lzo1z_decompress(out,*inp_len,in,&out_len,NULL );
For serenity: "in" and "out" are not the function arguments for the input and output buffers but temporary pointers. What can you see (beside from bad formatted code)? The only two buffers lzo1z_decompress is called with are "in" and "out". And these two buffers are freed before the call. I'm not surprised that there is an access violation. I only can underline nobugz's advice: Contact the author.
The 4th parameter need to be passed using out mode instead of ref. That solved the problem.

Categories

Resources