I was playing with a project from codeproject which basically monitors the printing activity on the computer. However it does not work correctly for 64 bit configuration. The below portion of the code was the issue. This code is called whenever printing is done.
PRINTER_NOTIFY_INFO info = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO));
int pData = (int)pNotifyInfo + Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO));
PRINTER_NOTIFY_INFO_DATA[] data = new PRINTER_NOTIFY_INFO_DATA[info.Count];
for (uint i = 0; i < info.Count; i++)
{
data[i] = (PRINTER_NOTIFY_INFO_DATA)Marshal.PtrToStructure((IntPtr)pData, typeof(PRINTER_NOTIFY_INFO_DATA));
pData += Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO_DATA));
}
Debugging shows that the data[i].field value is always 0. In 32 bit however it works correctly. I think the PRINTER_NOTIFY_INFO_DATA is not defined correctly. Presently I am using the following code. Can anybody fix this to work correctly in 64 bit as well?
[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_NOTIFY_INFO
{
public uint Version;
public uint Flags;
public uint Count;
}
[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_NOTIFY_INFO_DATA_DATA
{
public uint cbBuf;
public IntPtr pBuf;
}
[StructLayout(LayoutKind.Explicit)]
public struct PRINTER_NOTIFY_INFO_DATA_UNION
{
[FieldOffset(0)]
private uint adwData0;
[FieldOffset(4)]
private uint adwData1;
[FieldOffset(0)]
public PRINTER_NOTIFY_INFO_DATA_DATA Data;
public uint[] adwData
{
get
{
return new uint[] { this.adwData0, this.adwData1 };
}
}
}
// Structure borrowed from http://lifeandtimesofadeveloper.blogspot.com/2007/10/unmanaged-structures-padding-and-c-part_18.html.
[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_NOTIFY_INFO_DATA
{
public ushort Type;
public ushort Field;
public uint Reserved;
public uint Id;
public PRINTER_NOTIFY_INFO_DATA_UNION NotifyData;
}
I was testing print using the MS XPS driver. The Code project article is Here
It doesn't work correctly for 64-bit configuration because of Data Alignment.
So I suggest you to change PRINTER_NOTIFY_INFO as follows:
[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_NOTIFY_INFO
{
public uint Version;
public uint Flags;
public uint Count;
public PRINTER_NOTIFY_INFO_DATA_UNION aData;
}
And then use Marshal.OffsetOf
instead of Marshal.SizeOf:
PRINTER_NOTIFY_INFO info = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO));
long pData = (long)pNotifyInfo + (long)Marshal.OffsetOf(typeof(PRINTER_NOTIFY_INFO), "aData");
PRINTER_NOTIFY_INFO_DATA[] data = new PRINTER_NOTIFY_INFO_DATA[info.Count];
for (uint i = 0; i < info.Count; i++)
{
data[i] = (PRINTER_NOTIFY_INFO_DATA)Marshal.PtrToStructure((IntPtr)pData, typeof(PRINTER_NOTIFY_INFO_DATA));
pData += (long)Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO_DATA));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With