dahall / Vanara

A set of .NET libraries for Windows implementing PInvoke calls to many native Windows APIs with supporting wrappers.
MIT License
1.75k stars 190 forks source link

FindNextPrinterChangeNotification SafePRINTER_NOTIFY_INFO is invalid #434

Closed RikVanHaaren closed 8 months ago

RikVanHaaren commented 8 months ago

Describe the bug and how to reproduce

Having an issue with the 'FindNextPrinterChangeNotification' method within the "WinSpool". The 4th parameter, out SafePRINTER_NOTIFY_INFO pointer to a buffer that receives the printer information for the change notification, isn't set as it should be and keeps being invalid.

Below is the result of FindNextPrinterChangeNotification(hChange, out chg, default, out ppi) on the ppi: Name Value Type
ppi 0x0000000000000000 Vanara.PInvoke.WinSpool.SafePRINTER_NOTIFY_INFO
IsClosed false bool
IsInvalid true bool
IsNull true bool
handle 0x0000000000000000 System.IntPtr

What code is involved

This behavior is happening within the test StartWriteEndDocPagePrinterTest. Below is my own implementation:

SafeHPRINTER hprnt;
var printerName = "MyPrinterName";
if (!OpenPrinter(printerName, out hprnt))
{
    Console.WriteLine($"Failed to open printer {printerName}. Error: {GetLastError()}");
    return;
}

using var hChange = FindFirstPrinterChangeNotification(hprnt, PRINTER_CHANGE.PRINTER_CHANGE_ALL, PRINTER_NOTIFY_CATEGORY.PRINTER_NOTIFY_CATEGORY_2D);
while (true)
{
    var kernalStatus = Kernel32.WaitForSingleObject(hChange, 200);
    if (kernalStatus == Kernel32.WAIT_STATUS.WAIT_OBJECT_0)
    {
        SafePRINTER_NOTIFY_INFO ppi;
        PRINTER_CHANGE chg;
        bool foundPrinterNotification = FindNextPrinterChangeNotification(hChange, out chg, default, out ppi);
        if (foundPrinterNotification && !ppi.IsInvalid)
        {
            PRINTER_NOTIFY_INFO pi = ppi;
            Console.WriteLine($"{chg}: {string.Join(",", pi.aData?.Select(d => d.Field))}");
        }
    }
}

When running this program, I just request the printer to print a test page. Everything goes as expected until it hits the FindNextPrinterChangeNotification method and checks if the PPI is valid, which it is not.

Expected behavior

I expected that within the 'FindNextPrinterChangeNotification' the ppi 'SafePRINTER_NOTIFY_INFO ' should receive the printer information for the change notification.

dahall commented 8 months ago

See updated test in commit referenced above. You have to provide a PRINTER_NOTIFY_OPTIONS parameter value with the data you wish to see.

RikVanHaaren commented 7 months ago

Thanks for your addition and information, it works now!