I have two mdi applications, both of which retrieve their data from the same database.
The two applications need to be able to send messages to each other to keep in synch.
The messages being passed back and forth only contain a string telling the recieving application which piece of data in the database it should be looking at (a job number, and some additional related info).
Both applications have a message handler, instantiated when each program starts up.
When a message is sent from the VB6 app to the c# app it sees the message, and acts appropriately, but when I send the same type of message from the c# app to the VB6 app, it seems to see the message event, but when unpacking it, only sees part of the data, and then ignores the message.
I'm thinking I may be formatting something wrong on the c# end.
Here is the method that sends the message:
namespace InterProcessMessaging
{
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
public IntPtr dwData;//a pointer to a number use this to identify your message
public IntPtr lpData;//a pointer to the address of the data
public IntPtr cbData;//a pointer to the number of bytes to be transferred
}
public class clsMessaging : System.Windows.Forms.NativeWindow, IDisposable
{
//API function to send async. message to target application
[DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr SendMessageA(IntPtr hwnd, Int32 wMsg, Int32 wParam, COPYDATASTRUCT lParam);
public void SendMessageToVB6(string sendMsg, string WindowsAppTitle)
{
try
{
IntPtr hwndTarget = FindWindow(null, WindowsAppTitle);
IntPtr pDWData = Marshal.AllocHGlobal(sizeof(Int32));//a pointer to a number used this to identify your message
Marshal.StructureToPtr(3, pDWData, true);//place the value 3 at this location
IntPtr pLPData = Marshal.StringToHGlobalAnsi(sendMsg.Trim());//a pointer to the address of the data
IntPtr pCBData = Marshal.AllocHGlobal(sizeof(Int32));//a pointer to the number of bytes to be transferred
Marshal.StructureToPtr(sendMsg.Trim().Length+1, pCBData, true);//place the size of the string at this location
COPYDATASTRUCT cds;//a structure containing the three pointers above
cds.dwData = pDWData;//a pointer to a number used this to identify your message (3)
cds.lpData = pLPData;//a pointer to the address of the data
cds.cbData = pCBData;//a pointer to the number of bytes to be transferred
if (!System.IntPtr.Zero.Equals(hwndTarget))
{
SendMessageA(hwndTarget, 74, 0, cds);
}
}
catch (Exception ex)
{
Debug.Print(ex.InnerException.ToString());
}
}
}
}
I would recommend to look into Named Pipes. In .NET you can use System.IO.Pipes for this purpose. In VB6 you can easily implement it with Win32API. Named Pipes is better way to make IPC than windows messaging. Also IPC via SendMessage has limitations on Vista and Win7.
You got that pretty wrong. Only COPYDATASTRUCT.lpData is a pointer. dwData indicates the message number. You pick your own, use 0 if you have only one. cbData is the size of the pointed-to data.
More problems, you are leaking the memory. The amount of memory you allocate doesn't match the size you pass. The string conversion is lossy and might not produce as many bytes as string.Length(). FindWindow is notoriously unreliable. Use a socket or a named pipe for this so you don't have to guess a name, WCF is best.
COPYDATASTRUCT cds;
cds.dwData = (IntPtr)3;
cds.lpData = Marshal.StringToHGlobalUni(sendMsg);
cds.cbData = 2 * (sendMsg.Length + 1);
SendMessageA(hwndTarget, 74, 0, cds);
Marshal.FreeHGlobal(cds.lpData);
This works:
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public UInt32 cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
IntPtr result;
byte[] sarr = System.Text.Encoding.Default.GetBytes(sendMsg);
int len = sarr.Length;
COPYDATASTRUCT cds;
cds.dwData = (IntPtr)3;
cds.lpData = sendMsg;
cds.cbData = (UInt32)len + 1;
result = SendMessage(hwndTarget, WM_COPYDATA, 0, ref cds);
Credit for this solution goes to Jim Kemp...who is not yet a member.
Thanks Jim!
I based the solution off of the example I found here:
http://boycook.wordpress.com/2008/07/29/c-win32-messaging-with-sendmessage-and-wm_copydata/
Related
I have an error with reading the memory address of the game, where:
my code is this
public partial class MainWindow: Window
{
[DllImport ("kernel32.dll")]
public static extern IntPtr OpenProcess (int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport ("kernel32.dll")]
public static extern bool ReadProcessMemory (int hProcess, int lpBaseAddress, byte [] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
const int PROCESS_WM_READ = 0x0010;
public MainWindow ()
{
arguments dir = new arguments ();
Process process = Process.GetProcessesByName (dir.proccessname) [0];
IntPtr processHandle = OpenProcess (PROCESS_WM_READ, false, process.Id);
int bytesRead = 0;
byte [] buffer = new byte [4];
ReadProcessMemory ((int) processHandle, dir.heal_Act, buffer, buffer.Length, ref bytesRead);
}
however, nothing reading appears:
in cheat engine read me the values
Read address with Cheat Engine
Where in the image appears the reading of the memory address and finally the value contained with 4 bytes in size
Read address with Cheat Engine
In addition, I do not know how the summation of the address is as shown in box 2 to obtain the contained value.
they could help me to propose the reading with the indicated address, since zero appears.
You need to run your process as administrator and you should compile this for the same architecture as the target process. If you're targetting x86, compile as x86.
Keep in mind your ReadProcessMemory define only takes 4 byte addresses as arguments, you will want to use IntPtr for the addresses so when you someday switch to x64 the args will be large enough for 64 bit pointers.
If these things don't solve your problem then you're offsets or addresses are wrong. In which case the best thing to do is to use the Visual Studio Debugger and compare what you see against what you see in Cheat Engine.
Also in your PROCESS_WM_READ you have a 'W' instead of a 'V'.
I have a WPF application that needs to interface with another application.
This application has about 20 custom Windows Messages (WM_USER+50...WM_USER+70).
Summary of what I'm trying to accomplish:
WPF Application -> SendMessage -> ThirdParty application
The problem I have is that all of the Messages are CUSTOM messages. Therefore I have to implement my own data marshaling.
See http://msdn.microsoft.com/en-us/library/windows/desktop/ms644950(v=vs.85).aspx
It seems that the process I need to go through is:
Grab the process and open it for all access.
User32.GetWindowThreadProcessId(windowHandle, out pId);
// Open the process with all access
someprocess = OpenProcess((0x1F0FFF), false, (int)pId);
Allocate a buffer in the process:
IntPtr buffer = VirtualAllocEx( hProcess, IntPtr.Zero, 1024, 0x1000, 0x04 );
Fill up some sort of struct that will be written to the buffer created in #2?
Copy #3 to the remote buffer is #2? WriteProcessMemory??
Send the custom message ( SendMessage(windowhandle, customMsg, 0, buffer from #2?)
Read the struct back in from the remote process buffer into a local buffer
Marshal this data to a managed type. (This is a C# .Net application)
I could really use some insight. I haven't had much luck thus far. I think the part that I'm most stuck on is what type of struct to send to the WriteProcessMemory?
WM_COPYDATA is definitely the easiest way to do this. WM_COPYDATA lets you send two distinct items of data to another process - a DWORD value, and an arbitrarily-sized chunk of data. So for your implementation you would probably do something like this:
COPYDATASTRUCT cds;
cds.dwData = WM_USER + 50; // the "message" you want to send
cds.cbData = sizeof(MyDataForMessage50); // the size of the chunk of data
cds.lpData = lpMessage50Data; // a pointer to the chunk of data
SendMessage(hwndTarget, WM_COPYDATA, reinterpret_cast<WPARAM>(hwndSender),
reinterpret_cast<LPARAM>(&cds));
Note that hwndTarget is the target window in the other process, and hwndSender is a window in the sending process. The target window receives the same parameters and so can use wParam to learn who sent the message, and can therefore send a reply if needed.
In the WndProc at the receiving end:
if (uMsg == WM_COPYDATA)
{
HWND hwndSender = reinterpret_cast<HWND>(wParam);
LPCOPYDATASTRUCT pcds = reinterpret_cast<LPCOPYDATASTRUCT>(lParam);
DWORD dwCustomMsg = pcds->dwData;
LPVOID pCustomData = pcds->lpData;
DWORD dwCustomDataSize = pcds->cbData;
// do something with the custom message
// return TRUE to indicate message received
return TRUE;
}
Also note the important note in the docs for WM_COPYDATA:
The receiving application should consider the data read-only. The
lParam parameter is valid only during the processing of the message.
The receiving application should not free the memory referenced by
lParam. If the receiving application must access the data after
SendMessage returns, it must copy the data into a local buffer
Sample code for Sending message:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
public const int WM_COPYDATA = 0x4A;
public const UInt32 WM_COMMAND = 0x0111;
public const UInt32 IDM_MENU_SECUREDISCONNECT = 305;
public const UInt32 PROCESS_QUERY_LIMITED_INFORMATION = 0x1000;
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpData;
}
[DllImport("User32.dll", EntryPoint = "SendMessage", SetLastError = true)]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
private const string MARKER = "MARKER\n";
static void Main(string[] args)
{
IntPtr destWnd = (IntPtr)int.Parse(args[0]);
string packedargs = DAZZLE_MARKER + String.Join("\n", args[1]);
/
byte[] sarr = System.Text.Encoding.Unicode.GetBytes(packedargs);
int len = sarr.Length;
COPYDATASTRUCT CopyDataStruct;
CopyDataStruct.dwData = (IntPtr)100;
CopyDataStruct.cbData = (len + 1) * 2;
CopyDataStruct.lpData = packedargs;
int result = SendMessage(destWnd, WM_COPYDATA, 0, ref CopyDataStruct);
}
}
}
I have an application that will form a packet and send the packet data to an external program to send. I have everything working, but my only method I know that doesn't require the window to be the foremost is PostMessage. However, it seems to always lose 0-2 characters at the beginning of the message. Is there a way I can make a check to prevent the loss? I've tried looping GetLastError() and re-sending it if it's 0, but it doesn't help any. Here's the code I've gotten so far:
public void SendPacket(string packet)
{
//Get window name
IntPtr hWnd = Window.FindWindow(null, "???????????");
//Get the first edit box handle
IntPtr edithWnd = Window.FindWindowEx(hWnd, IntPtr.Zero, "TEdit", "");
//Get the handle for the send button
IntPtr buttonhWnd = Window.FindWindowEx(hWnd, IntPtr.Zero, "TButton", "SEND");
//Iterate twice to get the edit box I need
edithWnd = Window.FindWindowEx(hWnd, edithWnd, "TEdit", "");
edithWnd = Window.FindWindowEx(hWnd, edithWnd, "TEdit", "");
foreach (Char c in packet)
{
SendCheck(c, edithWnd);
}
//Press button
TextSend.PostMessageA(buttonhWnd, 0x00F5, 0, 0);
//Clear the edit box
TextSend.SendMessage(edithWnd, 0x000C, IntPtr.Zero, "");
}
public void SendCheck(char c, IntPtr handle)
{
//Send the character
TextSend.PostMessageA(handle, 0x102, c, 1);
//If error code is 0 (failure), resend that character
if (TextSend.GetLastError() == 0)
SendCheck(c, handle);
return;
}
And here are the definitions in TextSend class:
[DllImport("Kernel32.dll")]
public static extern int GetLastError();
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
public static extern bool SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, string s);
The fact that you're finding a TEdit and a TButton makes me think that the target application was written in Delphi. If so, depending on the version of Delphi it may or may not be a Unicode application. You're calling PostMessageA instead of PostMessageW which means it's sending a single-byte Ansi char instead of a 16-bit Unicode char from the c# application.
Do you have source to the target application? Stuffing data in an edit box and clicking a button seems a bit fragile. If you can modify the target application there are certainly other options available than to send one character at a time.
I posted this question a few days ago, and I have some follow up doubts about marshaling an IntPtr to a struct.
The thing goes like this:
As stated in the question I am referencing, I make calls to asynchronous methods on a native Dll. These methods communicate their completion with Windows Messages. I receive the Windows Message correctly now and, within it, an lParam property (of type IntPrt).
According to the documentation I am following, this lParam points to the struct that has the results of the execution of the method. As a particular example, one of the structures I am trying to fill is defined as follows:
Original C signature:
typedef struct _wfs_result {
ULONG RequestID;
USHORT hService;
TIMESTAMP tsTimestamp; /*Win32 SYSTEMTIME structure according to documentation*/
LONG hResult;
union {
DWORD dwCommandCode;
DWORD dwEventID;
} u;
LPVOID lpBuffer;
} WFSRESULT, *LPWFSRESULT;
My C# definition:
[StructLayout(LayoutKind.Sequential), Serializable]
public struct Timestamp
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
[StructLayout(LayoutKind.Explicit), Serializable]
public struct WFSResult
{
[FieldOffset(0), MarshalAs(UnmanagedType.U4)]
public uint RequestID;
[FieldOffset(4), MarshalAs(UnmanagedType.U2)]
public ushort hService;
[FieldOffset(6), MarshalAs(UnmanagedType.Struct, SizeConst = 16)]
public Timestamp tsTimestamp;
[FieldOffset(22), MarshalAs(UnmanagedType.U4)]
public int hResult;
[FieldOffset(26), MarshalAs(UnmanagedType.U4)]
public UInt32 dwCommandCode;
[FieldOffset(26), MarshalAs(UnmanagedType.U4)]
public UInt32 dwEventID;
[FieldOffset(30), MarshalAs(UnmanagedType.U4)]
public Int32 lpBuffer;
}
Now the fun part: the native Dll I am calling belongs to an independent process, FWMAIN32.EXE, which is running in the same machine (single instance). I believe the Window Message that I receive, which is application specific (above WM_USER), returns an LParam that is not really pointing to the struct I am expecting, and that the struct resides somewhere in the memory space of the FWMAIN32.EXE process.
Initially, I tried to just Marshal.PtrToStructure (with little hope actually) and the struct got filled with garbage data. I also tried with GetLParam with same outcome. Finally, I tried to go across process boundaries with the ReadProcessMemory API, as explained in these posts:
C# p/invoke, Reading data from an Owner Drawn List Box
http://www.codeproject.com/KB/trace/minememoryreader.aspx
I get the exception code 299 (ERROR_PARTIAL_COPY: Only part of a ReadProcessMemory or WriteProcessMemory request was completed.)
And additionally the byte[] I get from using ReadProcessMemory is: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
My code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace XFSInteropMidleware
{
public class CrossBoundaryManager
{
[DllImport("kernel32")]
static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
[DllImport("kernel32")]
static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] lpBuffer, UInt32 dwSize, out IntPtr lpNumberOfBytesRead);
[DllImport("kernel32")]
static extern Int32 CloseHandle(IntPtr hObject);
[DllImport("kernel32")]
static extern int GetLastError();
private const string nativeProcessName = "FWMAIN32";
private IntPtr hProcess = IntPtr.Zero;
const uint PROCESS_ALL_ACCESS = (uint)(0x000F0000L | 0x00100000L | 0xFFF);
static int dwSize = 34; //The size of the struct I want to fill
byte[] lpBuffer = new byte[dwSize];
public void OpenProcess()
{
Process[] ProcessesByName = Process.GetProcessesByName(nativeProcessName);
hProcess = CrossBoundaryManager.OpenProcess(CrossBoundaryManager.PROCESS_ALL_ACCESS, 1, (uint)ProcessesByName[0].Id);
}
public byte[] ReadMemory(IntPtr lParam, ref int lastError)
{
try
{
IntPtr ptrBytesReaded;
OpenProcess();
Int32 result = CrossBoundaryManager.ReadProcessMemory(hProcess, lParam, lpBuffer, (uint)lpBuffer.Length, out ptrBytesReaded);
return lpBuffer;
}
finally
{
int processLastError = GetLastError();
if (processLastError != 0)
{
lastError = processLastError;
}
if (hProcess != IntPtr.Zero)
CloseHandle(hProcess);
}
}
public void CloseProcessHandle()
{
int iRetValue;
iRetValue = CrossBoundaryManager.CloseHandle(hProcess);
if (iRetValue == 0)
throw new Exception("CloseHandle failed");
}
}
}
And I use it like this:
protected override void WndProc(ref Message m)
{
StringBuilder sb = new StringBuilder();
switch (m.Msg)
{
case OPEN_SESSION_COMPLETE:
GCHandle openCompleteResultGCH = GCHandle.Alloc(m.LParam); //So the GC does not eat the pointer before I can use it
CrossBoundaryManager manager = new CrossBoundaryManager();
int lastError = 0;
byte[] result = manager.ReadMemory(m.LParam, ref lastError);
if (lastError != 0)
{
txtState.Text = "Last error: " + lastError.ToString();
}
StringBuilder byteResult = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
byteResult.Append(result[i].ToString() + " ");
}
sb.AppendLine("Memory Read Result: " + byteResult.ToString());
sb.AppendLine("Request ID: " + BitConverter.ToInt32(result, 0).ToString());
txtResult.Text += sb.ToString();
manager.CloseProcessHandle();
break;
}
base.WndProc(ref m);
}
Is it correct to go across process boundaries in this case?
Is it correct to use lParam as the base address for ReadProcessMemory?
Is the CLR turning lParam to something I cannot use?
Why I am getting the 299 exception?
I correctly get the process ID of FWMAIN32.EXE, but how can I be sure the lParam is pointing inside its memory space?
Should I consider the use of "unsafe"? Could anyone recommend that approach?
Are there any other ways to custom marshal the struct?
Too many questions on a single post, I know, but I think they all point to resolving this issue. Thank you all for your help in advance, and sorry I had to make it so long.
I guess I have to take this one myself. So, as stated in the comments above, removing the
GCHandle openCompleteResultGCH = GCHandle.Alloc(m.LParam);
line did the trick. I understood that when a pointer in manage context is pointing to a struct in unmanaged context, the GC would collect it as the pointer really had nothing in its address. It is in fact the other way around. When, in managed context, we hold an object or struct that is being pointed from an unmanaged context, the GC could collect it because no pointer in the managed context is pointing to it, thus the need to pin it in order to keep the GC at distance.
So, in the end, there was no need go across process boundaries in this case. I removed the call to the Kernell32 methods, as the CLR handles the marshalling quiet well and Marshal.PtrToStructure was all I needed.
Credit goes to Jim and David who pointed me in the right direction.
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.