From 138df73e81ddc732d71d66d8a7af2db2f0d826c4 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Tue, 26 Jul 2022 12:42:17 +0100 Subject: [PATCH] Windows printing: handle failure of EnumPrinters. A user reports that if the Print Spooler service is disabled via services.msc, then PuTTY can report 'Out of memory!' when you try to open the Terminal config pane, which is the one containing the combo box enumerating the available printers. Apparently this is because the call to EnumPrinters failed with the error code other than the expected ERROR_INSUFFICIENT_BUFFER, and in the process, left garbage in the pcbNeeded output parameter. That wouldn't be too surprising if it had simply _not written_ to that parameter and therefore it was never initialised at all in the calling function printer_add_enum. But in fact, printer_add_enum *does* precautionarily initialise needed=0 before the initial call to EnumPrinters. So EnumPrinters must have actively written one of its *own* uninitialised variables into it! Anyway, the obvious fix is to distinguish ERROR_INSUFFICIENT_BUFFER from any other kind of EnumPrinters failure (in fact turning off Print Spooler seems to lead to RPC_S_SERVER_UNAVAILABLE), and not attempt to proceed in the case of other failures. --- windows/printing.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/windows/printing.c b/windows/printing.c index e6b3531d..0ec81376 100644 --- a/windows/printing.c +++ b/windows/printing.c @@ -67,11 +67,15 @@ static bool printer_add_enum(int param, DWORD level, char **buffer, /* * Exploratory call to EnumPrinters to determine how much space - * we'll need for the output. Discard the return value since it - * will almost certainly be a failure due to lack of space. + * we'll need for the output. + * + * If we get ERROR_INSUFFICIENT_BUFFER, that's fine, we're + * prepared to deal with it. Any other error, we return failure. */ - p_EnumPrinters(param, NULL, level, (LPBYTE)((*buffer)+offset), 512, - &needed, &nprinters); + if (p_EnumPrinters(param, NULL, level, (LPBYTE)((*buffer)+offset), 512, + &needed, &nprinters) == 0 && + GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return false; if (needed < 512) needed = 512;