mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-09 03:51:47 +00:00
The first time a process opens a PrintTicket provider for a queue whose provider is PrintConfig.dll, winspool.drv creates a process-wide cache without a lock. When two threads make those first calls together, winspool can keep a pointer to a cache it has already freed, and a later PTOpenProvider call crashes the process with an access violation in ntdll. Listing printers from several threads at once reaches it through two_sided. Hold one process-wide lock around every call that reaches the provider: PrintCapabilities::fetch in two_sided and driver_ticket, the PrintTicketBuilder in driver_ticket, fetch_xml_for_ticket in imageable_margin, and the start of print_with_progress, where winprint converts the ticket to a DEVMODE. The job releases the lock at its first progress report, before it sends progress to the submitting thread. A lock poisoned by a panic is still taken.