winspool: Update the ppd file of an already installed printer in the first call to OpenPrinter.
This commit is contained in:
parent
0ef0ce2938
commit
28ef1af6d0
@ -450,6 +450,62 @@ static inline DWORD set_reg_DWORD( HKEY hkey, const WCHAR *keyname, const DWORD
|
|||||||
return RegSetValueExW( hkey, keyname, 0, REG_DWORD, (const BYTE*)&value, sizeof(value) );
|
return RegSetValueExW( hkey, keyname, 0, REG_DWORD, (const BYTE*)&value, sizeof(value) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* get_opened_printer
|
||||||
|
* Get the pointer to the opened printer referred by the handle
|
||||||
|
*/
|
||||||
|
static opened_printer_t *get_opened_printer(HANDLE hprn)
|
||||||
|
{
|
||||||
|
UINT_PTR idx = (UINT_PTR)hprn;
|
||||||
|
opened_printer_t *ret = NULL;
|
||||||
|
|
||||||
|
EnterCriticalSection(&printer_handles_cs);
|
||||||
|
|
||||||
|
if ((idx > 0) && (idx <= nb_printer_handles)) {
|
||||||
|
ret = printer_handles[idx - 1];
|
||||||
|
}
|
||||||
|
LeaveCriticalSection(&printer_handles_cs);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* get_opened_printer_name
|
||||||
|
* Get the pointer to the opened printer name referred by the handle
|
||||||
|
*/
|
||||||
|
static LPCWSTR get_opened_printer_name(HANDLE hprn)
|
||||||
|
{
|
||||||
|
opened_printer_t *printer = get_opened_printer(hprn);
|
||||||
|
if(!printer) return NULL;
|
||||||
|
return printer->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD open_printer_reg_key( const WCHAR *name, HKEY *key )
|
||||||
|
{
|
||||||
|
HKEY printers;
|
||||||
|
DWORD err;
|
||||||
|
|
||||||
|
*key = NULL;
|
||||||
|
err = RegCreateKeyW( HKEY_LOCAL_MACHINE, PrintersW, &printers );
|
||||||
|
if (err) return err;
|
||||||
|
|
||||||
|
err = RegOpenKeyW( printers, name, key );
|
||||||
|
if (err) err = ERROR_INVALID_PRINTER_NAME;
|
||||||
|
RegCloseKey( printers );
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* WINSPOOL_GetOpenedPrinterRegKey
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static DWORD WINSPOOL_GetOpenedPrinterRegKey(HANDLE hPrinter, HKEY *phkey)
|
||||||
|
{
|
||||||
|
LPCWSTR name = get_opened_printer_name(hPrinter);
|
||||||
|
|
||||||
|
if(!name) return ERROR_INVALID_HANDLE;
|
||||||
|
return open_printer_reg_key( name, phkey );
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
WINSPOOL_SetDefaultPrinter(const char *devname, const char *name, BOOL force) {
|
WINSPOOL_SetDefaultPrinter(const char *devname, const char *name, BOOL force) {
|
||||||
char qbuf[200];
|
char qbuf[200];
|
||||||
@ -476,13 +532,13 @@ WINSPOOL_SetDefaultPrinter(const char *devname, const char *name, BOOL force) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL add_printer_driver(WCHAR *name, WCHAR *ppd)
|
static BOOL add_printer_driver(const WCHAR *name, WCHAR *ppd)
|
||||||
{
|
{
|
||||||
DRIVER_INFO_3W di3;
|
DRIVER_INFO_3W di3;
|
||||||
|
|
||||||
ZeroMemory(&di3, sizeof(DRIVER_INFO_3W));
|
ZeroMemory(&di3, sizeof(DRIVER_INFO_3W));
|
||||||
di3.cVersion = 3;
|
di3.cVersion = 3;
|
||||||
di3.pName = name;
|
di3.pName = (WCHAR*)name;
|
||||||
di3.pEnvironment = envname_x86W;
|
di3.pEnvironment = envname_x86W;
|
||||||
di3.pDriverPath = driver_nt;
|
di3.pDriverPath = driver_nt;
|
||||||
di3.pDataFile = ppd;
|
di3.pDataFile = ppd;
|
||||||
@ -831,8 +887,62 @@ static BOOL CUPS_LoadPrinters(void)
|
|||||||
RegCloseKey(hkeyPrinters);
|
RegCloseKey(hkeyPrinters);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *get_cups_name( HANDLE printer )
|
||||||
|
{
|
||||||
|
WCHAR *port;
|
||||||
|
DWORD err, needed, type;
|
||||||
|
char *ret = NULL;
|
||||||
|
HKEY key;
|
||||||
|
|
||||||
|
err = WINSPOOL_GetOpenedPrinterRegKey( printer, &key );
|
||||||
|
if (err) return NULL;
|
||||||
|
err = RegQueryValueExW( key, PortW, 0, &type, NULL, &needed );
|
||||||
|
if (err || needed <= sizeof( CUPS_Port )) goto end;
|
||||||
|
port = HeapAlloc( GetProcessHeap(), 0, needed );
|
||||||
|
if (!port) goto end;
|
||||||
|
RegQueryValueExW( key, PortW, 0, &type, (BYTE*)port, &needed );
|
||||||
|
if (!memcmp( port, CUPS_Port, sizeof(CUPS_Port) - sizeof(WCHAR) ))
|
||||||
|
{
|
||||||
|
WCHAR *name = port + sizeof(CUPS_Port) / sizeof(WCHAR) - 1;
|
||||||
|
needed = WideCharToMultiByte( CP_UNIXCP, 0, name, -1, NULL, 0, NULL, NULL );
|
||||||
|
ret = HeapAlloc( GetProcessHeap(), 0, needed );
|
||||||
|
if(ret) WideCharToMultiByte( CP_UNIXCP, 0, name, -1, ret, needed, NULL, NULL );
|
||||||
|
}
|
||||||
|
HeapFree( GetProcessHeap(), 0, port );
|
||||||
|
end:
|
||||||
|
RegCloseKey( key );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static BOOL update_driver( HANDLE printer )
|
||||||
|
{
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
#ifdef SONAME_LIBCUPS
|
||||||
|
const WCHAR *name = get_opened_printer_name( printer );
|
||||||
|
WCHAR *ppd_dir, *ppd;
|
||||||
|
char *cups_name;
|
||||||
|
|
||||||
|
if (!name) return FALSE;
|
||||||
|
cups_name = get_cups_name( printer );
|
||||||
|
if (!cups_name) return FALSE;
|
||||||
|
|
||||||
|
ppd_dir = get_ppd_dir();
|
||||||
|
ppd = get_ppd_filename( ppd_dir, name );
|
||||||
|
if (get_cups_ppd( cups_name, ppd ))
|
||||||
|
{
|
||||||
|
TRACE( "updating driver %s\n", debugstr_w( name ) );
|
||||||
|
ret = add_printer_driver( name, ppd );
|
||||||
|
unlink_ppd( ppd );
|
||||||
|
}
|
||||||
|
HeapFree( GetProcessHeap(), 0, ppd_dir );
|
||||||
|
HeapFree( GetProcessHeap(), 0, ppd );
|
||||||
|
HeapFree( GetProcessHeap(), 0, cups_name );
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL PRINTCAP_ParseEntry( const char *pent, BOOL isfirst )
|
static BOOL PRINTCAP_ParseEntry( const char *pent, BOOL isfirst )
|
||||||
{
|
{
|
||||||
PRINTER_INFO_2A pinfo2a;
|
PRINTER_INFO_2A pinfo2a;
|
||||||
@ -1243,62 +1353,6 @@ end:
|
|||||||
return (HANDLE)handle;
|
return (HANDLE)handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* get_opened_printer
|
|
||||||
* Get the pointer to the opened printer referred by the handle
|
|
||||||
*/
|
|
||||||
static opened_printer_t *get_opened_printer(HANDLE hprn)
|
|
||||||
{
|
|
||||||
UINT_PTR idx = (UINT_PTR)hprn;
|
|
||||||
opened_printer_t *ret = NULL;
|
|
||||||
|
|
||||||
EnterCriticalSection(&printer_handles_cs);
|
|
||||||
|
|
||||||
if ((idx > 0) && (idx <= nb_printer_handles)) {
|
|
||||||
ret = printer_handles[idx - 1];
|
|
||||||
}
|
|
||||||
LeaveCriticalSection(&printer_handles_cs);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* get_opened_printer_name
|
|
||||||
* Get the pointer to the opened printer name referred by the handle
|
|
||||||
*/
|
|
||||||
static LPCWSTR get_opened_printer_name(HANDLE hprn)
|
|
||||||
{
|
|
||||||
opened_printer_t *printer = get_opened_printer(hprn);
|
|
||||||
if(!printer) return NULL;
|
|
||||||
return printer->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DWORD open_printer_reg_key( const WCHAR *name, HKEY *key )
|
|
||||||
{
|
|
||||||
HKEY printers;
|
|
||||||
DWORD err;
|
|
||||||
|
|
||||||
*key = NULL;
|
|
||||||
err = RegCreateKeyW( HKEY_LOCAL_MACHINE, PrintersW, &printers );
|
|
||||||
if (err) return err;
|
|
||||||
|
|
||||||
err = RegOpenKeyW( printers, name, key );
|
|
||||||
if (err) err = ERROR_INVALID_PRINTER_NAME;
|
|
||||||
RegCloseKey( printers );
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* WINSPOOL_GetOpenedPrinterRegKey
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static DWORD WINSPOOL_GetOpenedPrinterRegKey(HANDLE hPrinter, HKEY *phkey)
|
|
||||||
{
|
|
||||||
LPCWSTR name = get_opened_printer_name(hPrinter);
|
|
||||||
|
|
||||||
if(!name) return ERROR_INVALID_HANDLE;
|
|
||||||
return open_printer_reg_key( name, phkey );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void old_printer_check( BOOL delete_phase )
|
static void old_printer_check( BOOL delete_phase )
|
||||||
{
|
{
|
||||||
PRINTER_INFO_5W* pi;
|
PRINTER_INFO_5W* pi;
|
||||||
@ -1348,6 +1402,7 @@ static void old_printer_check( BOOL delete_phase )
|
|||||||
|
|
||||||
static const WCHAR winspool_mutex_name[] = {'_','_','W','I','N','E','_','W','I','N','S','P','O','O','L','_',
|
static const WCHAR winspool_mutex_name[] = {'_','_','W','I','N','E','_','W','I','N','S','P','O','O','L','_',
|
||||||
'M','U','T','E','X','_','_','\0'};
|
'M','U','T','E','X','_','_','\0'};
|
||||||
|
static HANDLE init_mutex;
|
||||||
|
|
||||||
void WINSPOOL_LoadSystemPrinters(void)
|
void WINSPOOL_LoadSystemPrinters(void)
|
||||||
{
|
{
|
||||||
@ -1355,19 +1410,18 @@ void WINSPOOL_LoadSystemPrinters(void)
|
|||||||
DWORD needed, num, i;
|
DWORD needed, num, i;
|
||||||
WCHAR PrinterName[256];
|
WCHAR PrinterName[256];
|
||||||
BOOL done = FALSE;
|
BOOL done = FALSE;
|
||||||
HANDLE mutex;
|
|
||||||
|
|
||||||
/* FIXME: The init code should be moved to spoolsv.exe */
|
/* FIXME: The init code should be moved to spoolsv.exe */
|
||||||
mutex = CreateMutexW( NULL, TRUE, winspool_mutex_name );
|
init_mutex = CreateMutexW( NULL, TRUE, winspool_mutex_name );
|
||||||
if (!mutex)
|
if (!init_mutex)
|
||||||
{
|
{
|
||||||
ERR( "Failed to create mutex\n" );
|
ERR( "Failed to create mutex\n" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
||||||
{
|
{
|
||||||
WaitForSingleObject( mutex, INFINITE );
|
WaitForSingleObject( init_mutex, INFINITE );
|
||||||
ReleaseMutex( mutex );
|
ReleaseMutex( init_mutex );
|
||||||
TRACE( "Init already done\n" );
|
TRACE( "Init already done\n" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1403,7 +1457,7 @@ void WINSPOOL_LoadSystemPrinters(void)
|
|||||||
|
|
||||||
old_printer_check( TRUE );
|
old_printer_check( TRUE );
|
||||||
|
|
||||||
ReleaseMutex( mutex );
|
ReleaseMutex( init_mutex );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2277,6 +2331,25 @@ BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter, LPPRINTER_DEFAU
|
|||||||
|
|
||||||
/* Get the unique handle of the printer or Printserver */
|
/* Get the unique handle of the printer or Printserver */
|
||||||
*phPrinter = get_opened_printer_entry(lpPrinterName, pDefault);
|
*phPrinter = get_opened_printer_entry(lpPrinterName, pDefault);
|
||||||
|
|
||||||
|
WaitForSingleObject( init_mutex, INFINITE );
|
||||||
|
if (*phPrinter)
|
||||||
|
{
|
||||||
|
HKEY key;
|
||||||
|
DWORD deleting = 0, size = sizeof( deleting ), type;
|
||||||
|
DWORD status;
|
||||||
|
WINSPOOL_GetOpenedPrinterRegKey( *phPrinter, &key );
|
||||||
|
RegQueryValueExW( key, May_Delete_Value, NULL, &type, (LPBYTE)&deleting, &size );
|
||||||
|
status = get_dword_from_reg( key, StatusW );
|
||||||
|
if (!deleting && (status & PRINTER_STATUS_DRIVER_UPDATE_NEEDED))
|
||||||
|
{
|
||||||
|
update_driver( *phPrinter );
|
||||||
|
set_reg_DWORD( key, StatusW, status & ~PRINTER_STATUS_DRIVER_UPDATE_NEEDED );
|
||||||
|
}
|
||||||
|
RegCloseKey( key );
|
||||||
|
}
|
||||||
|
ReleaseMutex( init_mutex );
|
||||||
|
|
||||||
TRACE("returning %d with %u and %p\n", *phPrinter != NULL, GetLastError(), *phPrinter);
|
TRACE("returning %d with %u and %p\n", *phPrinter != NULL, GetLastError(), *phPrinter);
|
||||||
return (*phPrinter != 0);
|
return (*phPrinter != 0);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user