Added unit tests for newly added functions and applied needed fixes.

pull/83/head
David Hall 2019-12-13 14:28:25 -07:00
parent cab7d799c2
commit eb1bf547c2
4 changed files with 212 additions and 13 deletions

View File

@ -1,6 +1,9 @@
using System;
using Microsoft.Win32;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Text;
using Vanara.InteropServices;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
@ -667,7 +670,7 @@ namespace Vanara.PInvoke
[PInvokeData("winspool.h", MSDNShortId = "f34549c3-0474-48ba-9307-5b36f02dbe1c")]
public static bool AddPrintProvidor<T>([Optional] string pName, in T pProviderInfo) where T : struct
{
if (!TryGetLevel<T>("DRIVER_INFO_", out var lvl))
if (!TryGetLevel<T>("PROVIDOR_INFO_", out var lvl))
throw new ArgumentException($"{nameof(AddPrintProvidor)} cannot process a structure of type {typeof(T).Name}.");
using var mem = SafeCoTaskMemHandle.CreateFromStructure(pProviderInfo);
return AddPrintProvidor(pName, lvl, mem);
@ -857,7 +860,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winspool.h", MSDNShortId = "1a3d7c7f-1d45-4877-a8f7-a77f40e3c319")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeletePrinterDriverEx([Optional] string pName, [Optional] string pEnvironment, string pDriverName, DPD dwDeleteFlag, uint dwVersionFlag);
public static extern bool DeletePrinterDriverEx([Optional] string pName, [Optional] string pEnvironment, string pDriverName, DPD dwDeleteFlag, uint dwVersionFlag = 0);
/// <summary>Deletes a printer driver package from the driver store.</summary>
/// <param name="pszServer">
@ -932,6 +935,36 @@ namespace Vanara.PInvoke
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeletePrintProvidor([Optional] string pName, [Optional] string pEnvironment, string pPrintProviderName);
/// <summary>Retrieves GUID, version, and date of all core printer drivers and the path to their packages.</summary>
/// <param name="pszServer">
/// A pointer to a constant, null-terminated string that specifies the name of the print server. Use <c>NULL</c> for the local computer.
/// </param>
/// <param name="pszEnvironment">
/// A pointer to a constant, null-terminated string that specifies the processor architecture (for example, Windows NT x86). This
/// can be <c>NULL</c>.
/// </param>
/// <returns>A sequence of <c>CORE_PRINTER_DRIVER</c> structures.</returns>
/// <remarks>
/// This is a blocking or synchronous function and might not return immediately. How quickly this function returns depends on
/// run-time factors such as network status, print server configuration, and printer driver implementation factors that are
/// difficult to predict when writing an application. Calling this function from a thread that manages interaction with the user
/// interface could make the application appear to be unresponsive.
/// </remarks>
public static IEnumerable<CORE_PRINTER_DRIVER> EnumCorePrinterDrivers([Optional] string pszServer, [Optional] string pszEnvironment)
{
const string subKey32 = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\PackageInstallation\Windows NT x86\CorePrinterDrivers";
const string subKey64 = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\PackageInstallation\Windows x64\CorePrinterDrivers";
var is64bit = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432"));
using var baseKey = string.IsNullOrEmpty(pszServer) ? null : RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, pszServer);
using var reg = (baseKey ?? Registry.LocalMachine).OpenSubKey(is64bit ? subKey64 : subKey32, false);// RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.EnumerateSubKeys);
var keys = reg?.GetSubKeyNames();
if (keys?.Length == 0) return new CORE_PRINTER_DRIVER[0];
var drvs = new CORE_PRINTER_DRIVER[keys.Length];
GetCorePrinterDrivers(pszServer, pszEnvironment, keys, (uint)keys.Length, drvs).ThrowIfFailed();
return drvs;
}
/// <summary>The <c>EnumMonitors</c> function retrieves information about the port monitors installed on the specified server.</summary>
/// <param name="pName">
/// A pointer to a null-terminated string that specifies the name of the server on which the monitors reside. If this parameter is
@ -1244,7 +1277,7 @@ namespace Vanara.PInvoke
/// <returns>A sequence of <c>DATATYPES_INFO_1</c> structures.</returns>
/// <remarks>Starting with Windows Vista, the data type information from remote print servers is retrieved from a local cache.</remarks>
[PInvokeData("winspool.h", MSDNShortId = "27b6e074-d303-446b-9e5f-6cfa55c30d26")]
public static IEnumerable<T> EnumPrintProcessorDatatypes<T>([Optional] string pName, string pPrintProcessorName) where T : struct
public static IEnumerable<T> EnumPrintProcessorDatatypes<T>(string pPrintProcessorName, [Optional] string pName) where T : struct
{
if (!TryGetLevel<T>("DATATYPES_INFO_", out var lvl))
throw new ArgumentException($"{nameof(EnumPrintProcessorDatatypes)} cannot process a structure of type {typeof(T).Name}.");
@ -1645,7 +1678,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winspool.h", MSDNShortId = "69c9cc87-d7e3-496a-b631-b3ae30cdb3fd")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetPrinterDriverDirectory([Optional] string pName, [Optional] string pEnvironment, uint Level, StringBuilder pDriverDirectory, uint cbBuf, out uint pcbNeeded);
public static extern bool GetPrinterDriverDirectory([Optional] string pName, [Optional] string pEnvironment, uint Level, StringBuilder pDriverDirectory, int cbBuf, out int pcbNeeded);
/// <summary>Retrieves the path to the specified printer driver package on a print server.</summary>
/// <param name="pszServer">
@ -1682,7 +1715,7 @@ namespace Vanara.PInvoke
// pszDriverPackageCab, _In_ DWORD cchDriverPackageCab, _Out_ LPDWORD pcchRequiredSize );
[DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winspool.h", MSDNShortId = "e88e984b-d2c0-43b4-8f70-b05ec202ab14")]
public static extern HRESULT GetPrinterDriverPackagePath([Optional] string pszServer, [Optional] string pszEnvironment, [Optional] string pszLanguage, string pszPackageID, StringBuilder pszDriverPackageCab, uint cchDriverPackageCab, out uint pcchRequiredSize);
public static extern HRESULT GetPrinterDriverPackagePath([Optional] string pszServer, [Optional] string pszEnvironment, [Optional] string pszLanguage, string pszPackageID, StringBuilder pszDriverPackageCab, int cchDriverPackageCab, out int pcchRequiredSize);
/// <summary>
/// The <c>GetPrintProcessorDirectory</c> function retrieves the path to the print processor directory on the specified server.
@ -1717,7 +1750,7 @@ namespace Vanara.PInvoke
[DllImport(Lib.Winspool, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winspool.h", MSDNShortId = "a2443cfd-e5ba-41c6-aaf4-45051a3d0e26")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetPrintProcessorDirectory([Optional] string pName, [Optional] string pEnvironment, uint Level, StringBuilder pPrintProcessorInfo, uint cbBuf, out uint pcbNeeded);
public static extern bool GetPrintProcessorDirectory([Optional] string pName, [Optional] string pEnvironment, uint Level, StringBuilder pPrintProcessorInfo, int cbBuf, out int pcbNeeded);
/// <summary>Installs a printer driver from a driver package that is in the print server's driver store.</summary>
/// <param name="pszServer">

View File

@ -1834,7 +1834,7 @@ namespace Vanara.PInvoke
public static IEnumerable<(string valueName, REG_VALUE_TYPE valueType, object value)> EnumPrinterData(HPRINTER hPrinter)
{
var idx = 0U;
EnumPrinterData(hPrinter, idx, null, 0, out var valueNameSz, out var valueType, default, 0, out var dataSz).ThrowIfFailed();
EnumPrinterData(hPrinter, idx, null, 0, out var valueNameSz, out _, default, 0, out var dataSz).ThrowIfFailed();
if (valueNameSz == 0) yield break;
var name = new StringBuilder(1024);
using var mem = new SafeCoTaskMemHandle(dataSz);
@ -1842,7 +1842,7 @@ namespace Vanara.PInvoke
{
name.EnsureCapacity((int)valueNameSz);
if (mem.Size < dataSz) mem.Size = dataSz;
var ret = EnumPrinterData(hPrinter, idx, name, (uint)name.Capacity, out valueNameSz, out valueType, mem, mem.Size, out dataSz);
var ret = EnumPrinterData(hPrinter, idx, name, (uint)name.Capacity, out valueNameSz, out var valueType, mem, mem.Size, out dataSz);
if (ret == Win32Error.ERROR_NO_MORE_ITEMS) break;
if (ret == Win32Error.ERROR_MORE_DATA) continue;
ret.ThrowIfFailed();
@ -3997,9 +3997,9 @@ namespace Vanara.PInvoke
[PInvokeData("winspool.h", MSDNShortId = "b5a44b27-a4aa-4e58-9a64-05be87d12ab5")]
public static object GetPrinterData(HPRINTER hPrinter, string pValueName)
{
GetPrinterData(hPrinter, pValueName, out var type, default, 0, out var sz).ThrowUnless(Win32Error.ERROR_MORE_DATA);
GetPrinterData(hPrinter, pValueName, out _, default, 0, out var sz).ThrowUnless(Win32Error.ERROR_MORE_DATA);
using var mem = new SafeCoTaskMemHandle(sz);
GetPrinterData(hPrinter, pValueName, out type, mem, mem.Size, out sz).ThrowIfFailed();
GetPrinterData(hPrinter, pValueName, out var type, mem, mem.Size, out sz).ThrowIfFailed();
return type.GetValue(mem, mem.Size);
}
@ -4487,9 +4487,9 @@ namespace Vanara.PInvoke
[PInvokeData("winspool.h", MSDNShortId = "5d9183a7-97cc-46de-848e-e37ce51396eb")]
public static object GetPrinterDataEx(HPRINTER hPrinter, string pKeyName, string pValueName)
{
GetPrinterDataEx(hPrinter, pKeyName, pValueName, out var type, default, 0, out var sz).ThrowUnless(Win32Error.ERROR_MORE_DATA);
GetPrinterDataEx(hPrinter, pKeyName, pValueName, out _, default, 0, out var sz).ThrowUnless(Win32Error.ERROR_MORE_DATA);
using var mem = new SafeCoTaskMemHandle(sz);
GetPrinterDataEx(hPrinter, pKeyName, pValueName, out type, mem, mem.Size, out sz).ThrowIfFailed();
GetPrinterDataEx(hPrinter, pKeyName, pValueName, out var type, mem, mem.Size, out sz).ThrowIfFailed();
return type.GetValue(mem, mem.Size);
}

View File

@ -50,6 +50,10 @@
<Project>{d3e1f2b8-d475-4922-b334-919795b858cb}</Project>
<Name>Vanara.PInvoke.Printing</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\PInvoke\Security\Vanara.PInvoke.Security.csproj">
<Project>{392a14b0-1e10-4e88-9c13-0d965665ffb5}</Project>
<Name>Vanara.PInvoke.Security</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\PInvoke\Shared\Vanara.PInvoke.Shared.csproj">
<Project>{a5e519e9-feba-4fe3-93a5-b8269bef72f4}</Project>
<Name>Vanara.PInvoke.Shared</Name>

View File

@ -27,6 +27,23 @@ namespace Vanara.PInvoke.Tests
[OneTimeTearDown]
public void _TearDown() => hprnt?.Dispose();
[Test]
public void AddMonitorTest()
{
const string name = "mytestmon";
var mon = EnumMonitors<MONITOR_INFO_2>().First();
mon.pName = name;
Assert.That(AddMonitor(null, mon), ResultIs.Successful);
Assert.That(DeleteMonitor(null, mon.pEnvironment, mon.pName), ResultIs.Successful);
}
[Test]
public void AddPortTest()
{
var mon = EnumMonitors<MONITOR_INFO_1>().First().pName;
Assert.That(AddPort(null, HWND.NULL, mon), ResultIs.Successful);
}
[Test]
public void AddPrinterConnection2Test()
{
@ -42,6 +59,17 @@ namespace Vanara.PInvoke.Tests
Assert.That(DeletePrinterConnection(connPtrName), ResultIs.Successful);
}
[Test]
public void AddPrinterDriverExTest()
{
const string name = "mydriver";
var di2 = EnumPrinterDrivers<DRIVER_INFO_2>().First();
di2.pName = name;
using var priv = new ElevPriv("SeLoadDriverPrivilege");
Assert.That(AddPrinterDriverEx(null, di2), ResultIs.Successful);
Assert.That(DeletePrinterDriverEx(null, null, name, DPD.DPD_DELETE_UNUSED_FILES, 0), ResultIs.Successful);
}
[Test]
public void AddPrinterTest()
{
@ -91,6 +119,23 @@ namespace Vanara.PInvoke.Tests
Assert.That(DeletePrinterKey(p2, key), ResultIs.Successful);
}
}
[Test]
public void AddPrintProcessorTest()
{
using var priv = new ElevPriv("SeLoadDriverPrivilege");
Assert.That(AddPrintProcessor(null, null, "dummy.dll", "Dummy"), ResultIs.Successful);
Assert.That(DeletePrintProcessor(null, null, "Dummy"), ResultIs.Successful);
}
[Test]
public void AddPrintProvidorTest()
{
var pi1 = new PROVIDOR_INFO_1 { pName = "Dummy", pDLLName = "dummy.dll" };
Assert.That(AddPrintProvidor(null, pi1), ResultIs.Successful);
Assert.That(DeletePrintProvidor(null, null, pi1.pName), ResultIs.Successful);
}
[Test]
public void AdvancedDocumentPropertiesTest()
{
@ -107,6 +152,12 @@ namespace Vanara.PInvoke.Tests
p.Dispose();
}
[Test]
public void CorePrinterDriverInstalledTest()
{
//Assert.That(CorePrinterDriverInstalled(null, null, ), ResultIs.Successful);
}
[Test]
public void EnumFormsTest()
{
@ -127,6 +178,28 @@ namespace Vanara.PInvoke.Tests
Assert.That(EnumJobs<JOB_INFO_4>(hprnt), Is.Empty);
}
[Test]
public void EnumMonitorsTest()
{
MONITOR_INFO_1[] mon1;
Assert.That(mon1 = EnumMonitors<MONITOR_INFO_1>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", mon1.Select(v => v.pName)));
MONITOR_INFO_2[] mon2;
Assert.That(mon2 = EnumMonitors<MONITOR_INFO_2>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", mon2.Select(v => v.pEnvironment)));
}
[Test]
public void EnumPortsTest()
{
PORT_INFO_1[] port1;
Assert.That(port1 = EnumPorts<PORT_INFO_1>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", port1.Select(v => v.pName)));
PORT_INFO_2[] port2;
Assert.That(port2 = EnumPorts<PORT_INFO_2>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", port2.Select(v => v.fPortType)));
}
[Test]
public void EnumPrinterDataExTest()
{
@ -143,6 +216,32 @@ namespace Vanara.PInvoke.Tests
TestContext.WriteLine(string.Join(",", res1.Select(v => $"{v.valueName}={v.value} ({v.valueType})")));
}
[Test]
public void EnumPrinterDriversTest()
{
DRIVER_INFO_1[] res1;
Assert.That(res1 = EnumPrinterDrivers<DRIVER_INFO_1>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res1.Select(v => v.pName)));
DRIVER_INFO_2[] res2;
Assert.That(res2 = EnumPrinterDrivers<DRIVER_INFO_2>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res2.Select(v => v.pEnvironment)));
DRIVER_INFO_3[] res3;
Assert.That(res3 = EnumPrinterDrivers<DRIVER_INFO_3>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res3.Select(v => v.pDriverPath)));
DRIVER_INFO_4[] res4;
Assert.That(res4 = EnumPrinterDrivers<DRIVER_INFO_4>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res4.Select(v => v.pDataFile)));
DRIVER_INFO_5[] res5;
Assert.That(res5 = EnumPrinterDrivers<DRIVER_INFO_5>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res5.Select(v => v.pConfigFile)));
DRIVER_INFO_6[] res6;
Assert.That(res6 = EnumPrinterDrivers<DRIVER_INFO_6>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res6.Select(v => v.pHelpFile)));
DRIVER_INFO_8[] res8;
Assert.That(res8 = EnumPrinterDrivers<DRIVER_INFO_8>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res8.Select(v => v.pszMfgName)));
}
[Test]
public void EnumPrinterKeyTest()
{
@ -178,6 +277,23 @@ namespace Vanara.PInvoke.Tests
//Assert.That(res9 = EnumPrinters<PRINTER_INFO_9>().ToArray(), Is.Not.Empty);
}
[Test]
public void EnumPrintProcessorDatatypesTest()
{
var proc = EnumPrintProcessors<PRINTPROCESSOR_INFO_1>().First().pName;
DATATYPES_INFO_1[] res1;
Assert.That(res1 = EnumPrintProcessorDatatypes<DATATYPES_INFO_1>(proc).ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res1.Select(v => v.pName)));
}
[Test]
public void EnumPrintProcessorsTest()
{
PRINTPROCESSOR_INFO_1[] res1;
Assert.That(res1 = EnumPrintProcessors<PRINTPROCESSOR_INFO_1>().ToArray(), Is.Not.Empty);
TestContext.WriteLine(string.Join(",", res1.Select(v => v.pName)));
}
[Test]
public void FormTest()
{
@ -202,6 +318,12 @@ namespace Vanara.PInvoke.Tests
}
}
[Test]
public void GetCorePrinterDriversTest()
{
Assert.That(() => TestHelper.WriteValues(EnumCorePrinterDrivers(null, null)), Throws.Nothing);
}
[Test]
public void GetDefaultPrinterTest()
{
@ -211,6 +333,37 @@ namespace Vanara.PInvoke.Tests
TestContext.WriteLine(sb);
}
[Test]
public void GetPrinterDriverTest()
{
Assert.That(() => TestHelper.WriteValues(GetPrinterDriver<DRIVER_INFO_8>(hprnt)), Throws.Nothing);
}
[Test]
public void GetPrinterDriver2Test()
{
Assert.That(() => TestHelper.WriteValues(GetPrinterDriver2<DRIVER_INFO_8>(hprnt)), Throws.Nothing);
}
[Test]
public void GetPrinterDriverDirectoryTest()
{
Assert.That(GetPrinterDriverDirectory(null, null, 1, null, 0, out var req), ResultIs.Failure);
var sb = new StringBuilder(req);
Assert.That(GetPrinterDriverDirectory(null, null, 1, sb, sb.Capacity, out _), ResultIs.Successful);
TestContext.Write(sb);
}
[Test]
public void GetPrinterDriverPackagePathTest()
{
var pkg = EnumCorePrinterDrivers().First().szPackageID;
Assert.That(GetPrinterDriverPackagePath(null, null, null, pkg, null, 0, out var req), ResultIs.Successful);
var sb = new StringBuilder(req);
Assert.That(GetPrinterDriverPackagePath(null, null, null, pkg, sb, sb.Capacity, out _), ResultIs.Successful);
TestContext.Write(sb);
}
[Test]
public void GetPrintExecutionDataTest()
{
@ -218,6 +371,15 @@ namespace Vanara.PInvoke.Tests
TestHelper.WriteValues(data);
}
[Test]
public void GetPrintProcessorDirectoryTest()
{
Assert.That(GetPrintProcessorDirectory(null, null, 1, null, 0, out var req), ResultIs.Failure);
var sb = new StringBuilder(req);
Assert.That(GetPrintProcessorDirectory(null, null, 1, sb, sb.Capacity, out _), ResultIs.Successful);
TestContext.Write(sb);
}
[Test]
public void JobTest()
{