diff --git a/dll/win32/kernel32/winnls/string/nls.c b/dll/win32/kernel32/winnls/string/nls.c index 673da95bd1a..70fc01b1756 100644 --- a/dll/win32/kernel32/winnls/string/nls.c +++ b/dll/win32/kernel32/winnls/string/nls.c @@ -1812,6 +1812,25 @@ MultiByteToWideChar(UINT CodePage, MultiByteCount = lstrlenA(MultiByteString) + 1; } + /* CORE-19134 temporary diagnostics: detect insane source lengths + * (e.g. caused by a corrupt BSTR length prefix) and log the context. */ + if (MultiByteCount > 0x1000000) + { + PVOID Caller = *((PVOID *)_AddressOfReturnAddress() + 1); + DPRINT1("MultiByteToWideChar: insane MultiByteCount 0x%08lx, src=%p, prefix=0x%08lx, first bytes='%c%c%c%c%c%c%c%c', caller=%p\n", + MultiByteCount, MultiByteString, + *((ULONG *)MultiByteString - 1), + IsBadStringPtrA(MultiByteString, 8) ? '?' : MultiByteString[0], + IsBadStringPtrA(MultiByteString, 8) ? '?' : MultiByteString[1], + IsBadStringPtrA(MultiByteString, 8) ? '?' : MultiByteString[2], + IsBadStringPtrA(MultiByteString, 8) ? '?' : MultiByteString[3], + IsBadStringPtrA(MultiByteString, 8) ? '?' : MultiByteString[4], + IsBadStringPtrA(MultiByteString, 8) ? '?' : MultiByteString[5], + IsBadStringPtrA(MultiByteString, 8) ? '?' : MultiByteString[6], + IsBadStringPtrA(MultiByteString, 8) ? '?' : MultiByteString[7], + Caller); + } + switch (CodePage) { case CP_UTF8: diff --git a/win32ss/printing/providers/localspl/printers.c b/win32ss/printing/providers/localspl/printers.c index aaa313d5a4c..5fafbc51356 100644 --- a/win32ss/printing/providers/localspl/printers.c +++ b/win32ss/printing/providers/localspl/printers.c @@ -1999,6 +1999,76 @@ LocalClosePrinter(HANDLE hPrinter) return TRUE; } +static +PWSTR +BuildDeviceEntryValue(PCWSTR pwszDriverName, PCWSTR pwszPortName, BOOL bWithTimeouts) +{ + SIZE_T cchNeeded; + PWSTR pwszValue; + + // Build a value of the format ",[,15,45]". + cchNeeded = wcslen(pwszDriverName) + 1 + wcslen(pwszPortName) + 1; + if (bWithTimeouts) + cchNeeded += 6; + + pwszValue = DllAllocSplMem(cchNeeded * sizeof(WCHAR)); + if (!pwszValue) + return NULL; + + wcscpy(pwszValue, pwszDriverName); + wcscat(pwszValue, L","); + wcscat(pwszValue, pwszPortName); + + if (bWithTimeouts) + wcscat(pwszValue, L",15,45"); + + return pwszValue; +} + +static +VOID +MaintainWinIniEntries(PCWSTR pwszPrinterName, PCWSTR pwszDriverName, PCWSTR pwszPortName) +{ + BOOL bOk; + PWSTR pwszValue; + + /* CORE-19134 temporary diagnostics */ + FIXME("MaintainWinIniEntries printer='%S' driver='%S' port='%S'\n", + pwszPrinterName, pwszDriverName, pwszPortName); + + if (!pwszPrinterName || !*pwszPrinterName) + return; + + // Passing NULL as the value deletes the entry. + if (!pwszDriverName || !*pwszDriverName || !pwszPortName || !*pwszPortName) + { + bOk = WriteProfileStringW(L"devices", pwszPrinterName, NULL); + FIXME("MaintainWinIniEntries delete [devices] -> %d, gle=%lu\n", bOk, bOk ? 0 : GetLastError()); + bOk = WriteProfileStringW(L"PrinterPorts", pwszPrinterName, NULL); + FIXME("MaintainWinIniEntries delete [PrinterPorts] -> %d, gle=%lu\n", bOk, bOk ? 0 : GetLastError()); + return; + } + + // Maintain the legacy win.ini sections [devices] and [PrinterPorts] like the + // Windows NT print spooler does, so that applications which enumerate printers + // through them (e.g. Visual Basic 6 programs using their Printers collection) work. + pwszValue = BuildDeviceEntryValue(pwszDriverName, pwszPortName, FALSE); + if (pwszValue) + { + bOk = WriteProfileStringW(L"devices", pwszPrinterName, pwszValue); + FIXME("MaintainWinIniEntries write [devices]='%S' -> %d, gle=%lu\n", pwszValue, bOk, bOk ? 0 : GetLastError()); + DllFreeSplMem(pwszValue); + } + + pwszValue = BuildDeviceEntryValue(pwszDriverName, pwszPortName, TRUE); + if (pwszValue) + { + bOk = WriteProfileStringW(L"PrinterPorts", pwszPrinterName, pwszValue); + FIXME("MaintainWinIniEntries write [PrinterPorts]='%S' -> %d, gle=%lu\n", pwszValue, bOk, bOk ? 0 : GetLastError()); + DllFreeSplMem(pwszValue); + } +} + HANDLE WINAPI LocalAddPrinter(LPWSTR pName, DWORD level, LPBYTE pPrinterInfo) { @@ -2204,6 +2274,10 @@ LocalAddPrinter(LPWSTR pName, DWORD level, LPBYTE pPrinterInfo) // The Printer was added successfully. RegCloseKey(hPrinterKey); + + // Keep the legacy win.ini entries in sync. + MaintainWinIniEntries(pInfo->pPrinterName, pLocalPrinter->pwszPrinterDriver, pPort->pwszName); + SetLastError(ROUTER_SUCCESS); return hPrinter; @@ -2274,6 +2348,9 @@ LocalDeletePrinter(HANDLE hPrinter) // Delete the Printer's registry key. RegDeleteKeyW(hPrintersKey, pPrinter->pwszPrinterName); + // Keep the legacy win.ini entries in sync. + MaintainWinIniEntries(pPrinter->pwszPrinterName, NULL, NULL); + // Free all resources of the Printer. DllFreeSplStr(pPrinter->pwszPrinterName); DllFreeSplStr(pPrinter->pwszLocation);