diff --git a/NAPS2.Core/NAPS2.Core.csproj b/NAPS2.Core/NAPS2.Core.csproj
index 661a49733..2456e1ec5 100644
--- a/NAPS2.Core/NAPS2.Core.csproj
+++ b/NAPS2.Core/NAPS2.Core.csproj
@@ -213,6 +213,7 @@
+
diff --git a/NAPS2.Core/Scan/Wia/Native/NativeWiaMethods.cs b/NAPS2.Core/Scan/Wia/Native/NativeWiaMethods.cs
index 127ffbbe7..4badf82d4 100644
--- a/NAPS2.Core/Scan/Wia/Native/NativeWiaMethods.cs
+++ b/NAPS2.Core/Scan/Wia/Native/NativeWiaMethods.cs
@@ -25,8 +25,19 @@ namespace NAPS2.Scan.Wia.Native
[DllImport("NAPS2.WIA.dll")]
public static extern uint GetItemPropertyStorage(IntPtr item, out IntPtr propStorage);
+ public delegate void EnumPropertyCallback(int propId, [MarshalAs(UnmanagedType.LPWStr)] string propName, ushort propType);
+
[DllImport("NAPS2.WIA.dll")]
- public static extern uint SetItemProperty(IntPtr item, int propId, int value);
+ public static extern uint EnumerateProperties(IntPtr propStorage, [MarshalAs(UnmanagedType.FunctionPtr)] EnumPropertyCallback func);
+
+ [DllImport("NAPS2.WIA.dll")]
+ public static extern uint GetPropertyBstr(IntPtr propStorage, int propId, [MarshalAs(UnmanagedType.BStr), Out] out string value);
+
+ [DllImport("NAPS2.WIA.dll")]
+ public static extern uint GetPropertyInt(IntPtr propStorage, int propId, [Out] out int value);
+
+ [DllImport("NAPS2.WIA.dll")]
+ public static extern uint SetPropertyInt(IntPtr propStorage, int propId, int value);
[DllImport("NAPS2.WIA.dll")]
public static extern uint StartTransfer(IntPtr item, [Out] out IntPtr transfer);
diff --git a/NAPS2.Core/Scan/Wia/Native/NativeWiaObject.cs b/NAPS2.Core/Scan/Wia/Native/NativeWiaObject.cs
index c78cfef65..d7ccea679 100644
--- a/NAPS2.Core/Scan/Wia/Native/NativeWiaObject.cs
+++ b/NAPS2.Core/Scan/Wia/Native/NativeWiaObject.cs
@@ -41,7 +41,10 @@ namespace NAPS2.Scan.Wia.Native
{
if (!disposed)
{
- Marshal.Release(Handle);
+ if (Handle != IntPtr.Zero)
+ {
+ Marshal.Release(Handle);
+ }
disposed = true;
}
}
diff --git a/NAPS2.Core/Scan/Wia/Native/WiaItemBase.cs b/NAPS2.Core/Scan/Wia/Native/WiaItemBase.cs
index 786f26ba9..a4d3e7234 100644
--- a/NAPS2.Core/Scan/Wia/Native/WiaItemBase.cs
+++ b/NAPS2.Core/Scan/Wia/Native/WiaItemBase.cs
@@ -35,5 +35,14 @@ namespace NAPS2.Scan.Wia.Native
WiaException.Check(NativeWiaMethods.GetItem(Handle, name, out var itemHandle));
return new WiaItem(itemHandle);
}
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ if (disposing)
+ {
+ properties?.Dispose();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/NAPS2.Core/Scan/Wia/Native/WiaItemExtensions.cs b/NAPS2.Core/Scan/Wia/Native/WiaItemExtensions.cs
index 8b39de480..3d3b96a07 100644
--- a/NAPS2.Core/Scan/Wia/Native/WiaItemExtensions.cs
+++ b/NAPS2.Core/Scan/Wia/Native/WiaItemExtensions.cs
@@ -16,25 +16,25 @@ namespace NAPS2.Scan.Wia.Native
return device.Properties[WiaPropertyId.DIP_DEV_NAME].Value.ToString();
}
- public static bool SupportsFeeder(this IWiaDeviceProps device)
+ public static bool SupportsFeeder(this WiaDevice device)
{
int capabilities = (int)device.Properties[WiaPropertyId.DPS_DOCUMENT_HANDLING_CAPABILITIES].Value;
return (capabilities & WiaPropertyValue.FEEDER) != 0;
}
- public static bool SupportsDuplex(this IWiaDeviceProps device)
+ public static bool SupportsDuplex(this WiaDevice device)
{
int capabilities = (int)device.Properties[WiaPropertyId.DPS_DOCUMENT_HANDLING_CAPABILITIES].Value;
return (capabilities & WiaPropertyValue.DUPLEX) != 0;
}
- public static bool FeederReady(this IWiaDeviceProps device)
+ public static bool FeederReady(this WiaDevice device)
{
int status = (int)device.Properties[WiaPropertyId.DPS_DOCUMENT_HANDLING_STATUS].Value;
return (status & WiaPropertyValue.FEED_READY) != 0;
}
- public static void SetProperty(this WiaItem item, int propId, int value)
+ public static void SetProperty(this WiaItemBase item, int propId, int value)
{
var prop = item.Properties[propId];
if (prop != null)
@@ -43,7 +43,7 @@ namespace NAPS2.Scan.Wia.Native
}
}
- public static void SetPropertyRange(this WiaItem item, int propId, int value, int expectedMin, int expectedMax)
+ public static void SetPropertyRange(this WiaItemBase item, int propId, int value, int expectedMin, int expectedMax)
{
var prop = item.Properties[propId];
if (prop != null)
diff --git a/NAPS2.Core/Scan/Wia/Native/WiaProperty.cs b/NAPS2.Core/Scan/Wia/Native/WiaProperty.cs
index 8a4f76fd2..e2368c37e 100644
--- a/NAPS2.Core/Scan/Wia/Native/WiaProperty.cs
+++ b/NAPS2.Core/Scan/Wia/Native/WiaProperty.cs
@@ -6,29 +6,44 @@ namespace NAPS2.Scan.Wia.Native
{
public class WiaProperty
{
- private object value;
-
- protected internal WiaProperty(WiaItem owner, int id)
+ protected internal WiaProperty(IntPtr storage, int id, string name, ushort type)
{
- Owner = owner;
+ Storage = storage;
Id = id;
+ Name = name;
+ Type = type;
}
- private WiaItem Owner { get; }
+ private IntPtr Storage { get; }
public int Id { get; set; }
+ public string Name { get; }
+
+ public ushort Type { get; }
+
// TODO: Full R/W impl
public object Value
{
- get => value;
+ get
+ {
+ if (Type == WiaPropertyType.I4)
+ {
+ WiaException.Check(NativeWiaMethods.GetPropertyInt(Storage, Id, out int value));
+ return value;
+ }
+ if (Type == WiaPropertyType.BSTR)
+ {
+ WiaException.Check(NativeWiaMethods.GetPropertyBstr(Storage, Id, out string value));
+ return value;
+ }
+ throw new NotImplementedException("Not implemented property type");
+ }
set
{
- if (value is int valueInt)
+ if (Type == WiaPropertyType.I4)
{
- WiaException.Check(NativeWiaMethods.SetItemProperty(Owner.Handle, Id, valueInt));
- // TODO: Get the value from the backing in case it changes
- this.value = value;
+ WiaException.Check(NativeWiaMethods.SetPropertyInt(Storage, Id, (int)value));
}
else
{
@@ -47,6 +62,8 @@ namespace NAPS2.Scan.Wia.Native
public object[] SubTypeValues { get; set; }
+ public override string ToString() => Name;
+
public enum SubTypes
{
None,
diff --git a/NAPS2.Core/Scan/Wia/Native/WiaPropertyCollection.cs b/NAPS2.Core/Scan/Wia/Native/WiaPropertyCollection.cs
index 686758019..0dba62ff8 100644
--- a/NAPS2.Core/Scan/Wia/Native/WiaPropertyCollection.cs
+++ b/NAPS2.Core/Scan/Wia/Native/WiaPropertyCollection.cs
@@ -1,28 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Runtime.InteropServices;
using NAPS2.Util;
namespace NAPS2.Scan.Wia.Native
{
- public class WiaPropertyCollection
+ public class WiaPropertyCollection : NativeWiaObject
{
private readonly Dictionary propertyDict;
- public WiaPropertyCollection(IntPtr propertyStorageHandle)
+ public WiaPropertyCollection(IntPtr propertyStorageHandle) : base(propertyStorageHandle)
{
propertyDict = new Dictionary();
- // TODO
- try
- {
- }
- finally
- {
- Marshal.Release(propertyStorageHandle);
- }
+ WiaException.Check(NativeWiaMethods.EnumerateProperties(Handle,
+ (id, name, type) => propertyDict.Add(id, new WiaProperty(Handle, id, name, type))));
}
-
+
public WiaProperty this[int propId] => propertyDict.Get(propId);
}
}
diff --git a/NAPS2.Core/Scan/Wia/Native/WiaPropertyId.cs b/NAPS2.Core/Scan/Wia/Native/WiaPropertyId.cs
index d50206ef5..83484768b 100644
--- a/NAPS2.Core/Scan/Wia/Native/WiaPropertyId.cs
+++ b/NAPS2.Core/Scan/Wia/Native/WiaPropertyId.cs
@@ -43,6 +43,8 @@ namespace NAPS2.Scan.Wia.Native
public const int IPS_BRIGHTNESS = 6154;
public const int IPS_CONTRAST = 6155;
public const int IPS_ORIENTATION = 6156;
+ public const int IPS_MAX_HORIZONTAL_SIZE = 6165;
+ public const int IPS_MAX_VERTICAL_SIZE = 6166;
public const int IPS_PAGES = 3096;
}
}
diff --git a/NAPS2.Core/Scan/Wia/Native/WiaPropertyType.cs b/NAPS2.Core/Scan/Wia/Native/WiaPropertyType.cs
new file mode 100644
index 000000000..f16c0dba8
--- /dev/null
+++ b/NAPS2.Core/Scan/Wia/Native/WiaPropertyType.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace NAPS2.Scan.Wia.Native
+{
+ ///
+ /// Property type constants.
+ ///
+ public static class WiaPropertyType
+ {
+ public const int I4 = 3;
+ public const int BSTR = 8;
+ }
+}
\ No newline at end of file
diff --git a/NAPS2.Core/Scan/Wia/WiaScanDriver.cs b/NAPS2.Core/Scan/Wia/WiaScanDriver.cs
index db1f9d494..d920b3bae 100644
--- a/NAPS2.Core/Scan/Wia/WiaScanDriver.cs
+++ b/NAPS2.Core/Scan/Wia/WiaScanDriver.cs
@@ -44,7 +44,13 @@ namespace NAPS2.Scan.Wia
{
using (var deviceManager = new WiaDeviceManager())
{
- return deviceManager.GetDeviceInfos().Select(x => new ScanDevice(x.Id(), x.Name())).ToList();
+ return deviceManager.GetDeviceInfos().Select(x =>
+ {
+ using (x)
+ {
+ return new ScanDevice(x.Id(), x.Name());
+ }
+ }).ToList();
}
}
@@ -73,7 +79,7 @@ namespace NAPS2.Scan.Wia
// TODO: Props
ConfigureDeviceProps(device);
- ConfigureItemProps(device, item);
+ ConfigureItemProps(item);
// TODO: Format BMP "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}"
// TODO: Arrrggg... WIA native UI is an option I'm supposed to support.
@@ -115,7 +121,7 @@ namespace NAPS2.Scan.Wia
}
}
- private void ConfigureItemProps(WiaDevice device, WiaItem item)
+ private void ConfigureItemProps(WiaItem item)
{
switch (ScanProfile.BitDepth)
{
@@ -143,14 +149,8 @@ namespace NAPS2.Scan.Wia
int pageWidth = pageDimensions.WidthInThousandthsOfAnInch() * resolution / 1000;
int pageHeight = pageDimensions.HeightInThousandthsOfAnInch() * resolution / 1000;
- int horizontalSize =
- (int)device.Properties[ScanProfile.PaperSource == ScanSource.Glass
- ? WiaPropertyId.DPS_HORIZONTAL_BED_SIZE
- : WiaPropertyId.DPS_HORIZONTAL_SHEET_FEED_SIZE].Value;
- int verticalSize =
- (int)device.Properties[ScanProfile.PaperSource == ScanSource.Glass
- ? WiaPropertyId.DPS_VERTICAL_BED_SIZE
- : WiaPropertyId.DPS_VERTICAL_SHEET_FEED_SIZE].Value;
+ int horizontalSize = (int)item.Properties[WiaPropertyId.IPS_MAX_HORIZONTAL_SIZE].Value;
+ int verticalSize = (int)item.Properties[WiaPropertyId.IPS_MAX_VERTICAL_SIZE].Value;
int pagemaxwidth = horizontalSize * resolution / 1000;
int pagemaxheight = verticalSize * resolution / 1000;
diff --git a/NAPS2.WIA/NAPS2.WIA.cpp b/NAPS2.WIA/NAPS2.WIA.cpp
index 789544193..e58c4c76c 100644
Binary files a/NAPS2.WIA/NAPS2.WIA.cpp and b/NAPS2.WIA/NAPS2.WIA.cpp differ