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 @@ namespace NTwain.Data
///
///
/// 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 @@ namespace NTwain.Data
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 @@ namespace NTwain.Data
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 @@ namespace NTwain.Data
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 @@ namespace NTwain.Data
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 @@ namespace NTwain.Data
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);