diff --git a/src/NTwain/Data/TWAINH_EXTRAS.cs b/src/NTwain/Data/TWAINH_EXTRAS.cs index 0cc6041..e3c675a 100644 --- a/src/NTwain/Data/TWAINH_EXTRAS.cs +++ b/src/NTwain/Data/TWAINH_EXTRAS.cs @@ -1040,8 +1040,9 @@ public unsafe TValue ReadNonPointerData() where TValue : struct /// /// /// If item is an array specify which string to read + /// Pass a value if you know how long it should be. /// - public unsafe string? ReadHandleString(IMemoryManager memMgr, int index = 0) + public unsafe string? ReadHandleString(IMemoryManager memMgr, int index = 0, int lengthHint = -1) { if (index < 0 || index >= NumItems || !IsDataAPointer) return default; @@ -1053,7 +1054,7 @@ public unsafe TValue ReadNonPointerData() where TValue : struct if (NumItems == 1) { // if 1, item is already the pointer to the string - value = LockAndReadNullTerminatedString(memMgr, itemAsPtr); + value = LockAndReadNullTerminatedString(memMgr, itemAsPtr, lengthHint); } else { @@ -1062,17 +1063,17 @@ public unsafe TValue ReadNonPointerData() where TValue : struct lockPtr += (IntPtr.Size * index); // is this even correct? I hope it is var subItemPtr = Marshal.PtrToStructure(lockPtr); - value = LockAndReadNullTerminatedString(memMgr, subItemPtr); + value = LockAndReadNullTerminatedString(memMgr, subItemPtr, lengthHint); memMgr.Unlock(itemAsPtr); } return value; } - private string? LockAndReadNullTerminatedString(IMemoryManager memMgr, IntPtr data) + private string? LockAndReadNullTerminatedString(IMemoryManager memMgr, IntPtr data, int lengthHint = -1) { var lockPtr = memMgr.Lock(data); // yolo as ansi, should work in most cases - var value = Marshal.PtrToStringAnsi(lockPtr); + var value = lengthHint > 0 ? Marshal.PtrToStringAnsi(lockPtr, lengthHint) : Marshal.PtrToStringAnsi(lockPtr); memMgr.Unlock(data); return value; } diff --git a/src/NTwain/Data/ValueReader.cs b/src/NTwain/Data/ValueReader.cs index 1ab5c42..4e2dda9 100644 --- a/src/NTwain/Data/ValueReader.cs +++ b/src/NTwain/Data/ValueReader.cs @@ -439,6 +439,9 @@ public static TValue ReadTWTYData(this IntPtr intptr, TWTY type, int ite default: throw new NotSupportedException($"Unsupported item type {type} for reading."); // TODO: verify if needs to read int32 for small types + case TWTY.HANDLE: + intptr += IntPtr.Size * itemIndex; + return MarshalTo(intptr); case TWTY.INT8: intptr += 1 * itemIndex; if (isEnum) diff --git a/src/NTwain/Data/ValueWriter.cs b/src/NTwain/Data/ValueWriter.cs index 3f273e9..0f5cdd1 100644 --- a/src/NTwain/Data/ValueWriter.cs +++ b/src/NTwain/Data/ValueWriter.cs @@ -548,6 +548,8 @@ static TWTY GetItemType() where TValue : struct if (type == typeof(TW_STR128)) return TWTY.STR128; if (type == typeof(TW_STR255)) return TWTY.STR255; if (type == typeof(TW_FRAME)) return TWTY.FRAME; + if (type == typeof(IntPtr)) return TWTY.HANDLE; + if (type == typeof(UIntPtr)) return TWTY.HANDLE; if (type.IsEnum) { @@ -579,6 +581,10 @@ static void WriteContainerData(IntPtr intptr, TWTY type, TValue value, i default: throw new NotSupportedException($"Unsupported item type {type} for writing."); // TODO: for small types needs to fill whole int32 before writing? + case TWTY.HANDLE: + intptr += IntPtr.Size * itemIndex; + Marshal.StructureToPtr(value, intptr, false); + break; case TWTY.INT8: intptr += 1 * itemIndex; //int intval = Convert.ToSByte(value);