wineps: Move ppd filename retrieval to a separate function.
This commit is contained in:
parent
cd83f88576
commit
72cfc219f0
|
@ -573,6 +573,106 @@ static BOOL set_devmode( HANDLE printer, PSDRV_DEVMODE *dm )
|
|||
return SetPrinterW( printer, 9, (BYTE *)&info, 0 );
|
||||
}
|
||||
|
||||
static inline char *expand_env_string( char *str, DWORD type )
|
||||
{
|
||||
if (type == REG_EXPAND_SZ)
|
||||
{
|
||||
char *tmp;
|
||||
DWORD needed = ExpandEnvironmentStringsA( str, NULL, 0 );
|
||||
tmp = HeapAlloc( GetProcessHeap(), 0, needed );
|
||||
if (tmp)
|
||||
{
|
||||
ExpandEnvironmentStringsA( str, tmp, needed );
|
||||
HeapFree( GetProcessHeap(), 0, str );
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static char *get_ppd_filename( HANDLE printer, const char *nameA, BOOL *needs_unlink )
|
||||
{
|
||||
char *ret = NULL;
|
||||
DWORD needed, err, type;
|
||||
HKEY hkey;
|
||||
const char *data_dir, *filename;
|
||||
|
||||
*needs_unlink = FALSE;
|
||||
|
||||
#ifdef SONAME_LIBCUPS
|
||||
if (cupshandle != (void*)-1)
|
||||
{
|
||||
typeof(cupsGetPPD) *pcupsGetPPD;
|
||||
|
||||
pcupsGetPPD = wine_dlsym( cupshandle, "cupsGetPPD", NULL, 0 );
|
||||
if (pcupsGetPPD)
|
||||
{
|
||||
filename = pcupsGetPPD( nameA );
|
||||
|
||||
if (filename)
|
||||
{
|
||||
needed = strlen( filename ) + 1;
|
||||
ret = HeapAlloc( GetProcessHeap(), 0, needed );
|
||||
memcpy( ret, filename, needed );
|
||||
*needs_unlink = TRUE;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
WARN( "CUPS did not find ppd for %s\n", debugstr_a(nameA) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
err = GetPrinterDataExA( printer, "PrinterDriverData", "PPD File", NULL, NULL, 0, &needed );
|
||||
if (err == ERROR_MORE_DATA)
|
||||
{
|
||||
ret = HeapAlloc( GetProcessHeap(), 0, needed );
|
||||
if (!ret) return NULL;
|
||||
GetPrinterDataExA( printer, "PrinterDriverData", "PPD File", &type,
|
||||
(BYTE *)ret, needed, &needed );
|
||||
return expand_env_string( ret, type );
|
||||
}
|
||||
|
||||
/* Look for a ppd file for this printer in the config file.
|
||||
* First look under that printer's name, and then under 'generic'
|
||||
*/
|
||||
/* @@ Wine registry key: HKCU\Software\Wine\Printing\PPD Files */
|
||||
if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Printing\\PPD Files", &hkey ) == ERROR_SUCCESS )
|
||||
{
|
||||
const char *value_name = NULL;
|
||||
|
||||
if (RegQueryValueExA( hkey, nameA, 0, NULL, NULL, &needed ) == ERROR_SUCCESS)
|
||||
value_name = nameA;
|
||||
else if (RegQueryValueExA( hkey, "generic", 0, NULL, NULL, &needed ) == ERROR_SUCCESS)
|
||||
value_name = "generic";
|
||||
|
||||
if (value_name)
|
||||
{
|
||||
ret = HeapAlloc( GetProcessHeap(), 0, needed );
|
||||
if (!ret) return NULL;
|
||||
RegQueryValueExA( hkey, value_name, 0, &type, (BYTE *)ret, &needed );
|
||||
}
|
||||
RegCloseKey( hkey );
|
||||
if (ret) return expand_env_string( ret, type );
|
||||
}
|
||||
|
||||
if ((data_dir = wine_get_data_dir())) filename = "/generic.ppd";
|
||||
else if ((data_dir = wine_get_build_dir())) filename = "/dlls/wineps.drv/generic.ppd";
|
||||
else
|
||||
{
|
||||
ERR( "Error getting PPD file name for printer '%s'\n", debugstr_a(nameA) );
|
||||
return NULL;
|
||||
}
|
||||
ret = HeapAlloc( GetProcessHeap(), 0, strlen(data_dir) + strlen(filename) + 1 );
|
||||
if (ret)
|
||||
{
|
||||
strcpy( ret, data_dir );
|
||||
strcat( ret, filename );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct list printer_list = LIST_INIT( printer_list );
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -585,11 +685,8 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCWSTR name)
|
|||
FONTNAME *font;
|
||||
const AFM *afm;
|
||||
HANDLE hPrinter = 0;
|
||||
const char *ppd = NULL;
|
||||
DWORD ppdType;
|
||||
char *ppdFileName = NULL, *nameA = NULL;
|
||||
HKEY hkey;
|
||||
BOOL using_default_devmode = FALSE;
|
||||
char *ppd_filename = NULL, *nameA = NULL;
|
||||
BOOL using_default_devmode = FALSE, needs_unlink = FALSE;
|
||||
int len;
|
||||
|
||||
TRACE("'%s'\n", debugstr_w(name));
|
||||
|
@ -618,92 +715,13 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCWSTR name)
|
|||
pi->Devmode = get_devmode( hPrinter, name, &using_default_devmode );
|
||||
if (!pi->Devmode) goto fail;
|
||||
|
||||
#ifdef SONAME_LIBCUPS
|
||||
if (cupshandle != (void*)-1) {
|
||||
typeof(cupsGetPPD) * pcupsGetPPD = NULL;
|
||||
ppd_filename = get_ppd_filename( hPrinter, nameA, &needs_unlink );
|
||||
if (!ppd_filename) goto fail;
|
||||
|
||||
pcupsGetPPD = wine_dlsym(cupshandle, "cupsGetPPD", NULL, 0);
|
||||
if (pcupsGetPPD) {
|
||||
ppd = pcupsGetPPD( nameA );
|
||||
|
||||
if (ppd) {
|
||||
needed=strlen(ppd)+1;
|
||||
ppdFileName=HeapAlloc(PSDRV_Heap, 0, needed);
|
||||
memcpy(ppdFileName, ppd, needed);
|
||||
ppdType=REG_SZ;
|
||||
res = ERROR_SUCCESS;
|
||||
/* we should unlink() that file later */
|
||||
} else {
|
||||
res = ERROR_FILE_NOT_FOUND;
|
||||
WARN("Did not find ppd for %s\n", debugstr_w(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!ppdFileName) {
|
||||
res = GetPrinterDataExA(hPrinter, "PrinterDriverData", "PPD File", NULL, NULL, 0, &needed);
|
||||
if ((res==ERROR_SUCCESS) || (res==ERROR_MORE_DATA)) {
|
||||
ppdFileName=HeapAlloc(PSDRV_Heap, 0, needed);
|
||||
res = GetPrinterDataExA(hPrinter, "PrinterDriverData", "PPD File", &ppdType,
|
||||
(LPBYTE)ppdFileName, needed, &needed);
|
||||
}
|
||||
}
|
||||
/* Look for a ppd file for this printer in the config file.
|
||||
* First look under that printer's name, and then under 'generic'
|
||||
*/
|
||||
/* @@ Wine registry key: HKCU\Software\Wine\Printing\PPD Files */
|
||||
if((res != ERROR_SUCCESS) && !RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Printing\\PPD Files", &hkey))
|
||||
pi->ppd = PSDRV_ParsePPD( ppd_filename );
|
||||
if (!pi->ppd)
|
||||
{
|
||||
const char* value_name;
|
||||
|
||||
if (RegQueryValueExA(hkey, nameA, 0, NULL, NULL, &needed) == ERROR_SUCCESS) {
|
||||
value_name=nameA;
|
||||
} else if (RegQueryValueExA(hkey, "generic", 0, NULL, NULL, &needed) == ERROR_SUCCESS) {
|
||||
value_name="generic";
|
||||
} else {
|
||||
value_name=NULL;
|
||||
}
|
||||
if (value_name) {
|
||||
HeapFree(PSDRV_Heap, 0, ppdFileName);
|
||||
ppdFileName=HeapAlloc(PSDRV_Heap, 0, needed);
|
||||
RegQueryValueExA(hkey, value_name, 0, &ppdType, (LPBYTE)ppdFileName, &needed);
|
||||
}
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
|
||||
if (!ppdFileName)
|
||||
{
|
||||
const char *data_dir, *filename;
|
||||
|
||||
if ((data_dir = wine_get_data_dir())) filename = "/generic.ppd";
|
||||
else if ((data_dir = wine_get_build_dir())) filename = "/dlls/wineps.drv/generic.ppd";
|
||||
else
|
||||
{
|
||||
res = ERROR_FILE_NOT_FOUND;
|
||||
ERR ("Error %i getting PPD file name for printer '%s'\n", res, debugstr_w(name));
|
||||
goto fail;
|
||||
}
|
||||
ppdFileName = HeapAlloc( PSDRV_Heap, 0, strlen(data_dir) + strlen(filename) + 1 );
|
||||
strcpy( ppdFileName, data_dir );
|
||||
strcat( ppdFileName, filename );
|
||||
} else {
|
||||
res = ERROR_SUCCESS;
|
||||
if (ppdType==REG_EXPAND_SZ) {
|
||||
char* tmp;
|
||||
|
||||
/* Expand environment variable references */
|
||||
needed=ExpandEnvironmentStringsA(ppdFileName,NULL,0);
|
||||
tmp=HeapAlloc(PSDRV_Heap, 0, needed);
|
||||
ExpandEnvironmentStringsA(ppdFileName,tmp,needed);
|
||||
HeapFree(PSDRV_Heap, 0, ppdFileName);
|
||||
ppdFileName=tmp;
|
||||
}
|
||||
}
|
||||
|
||||
pi->ppd = PSDRV_ParsePPD(ppdFileName);
|
||||
if(!pi->ppd) {
|
||||
MESSAGE("Couldn't find PPD file '%s', expect a crash now!\n",
|
||||
ppdFileName);
|
||||
WARN( "Couldn't parse PPD file '%s'\n", ppd_filename );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -780,19 +798,20 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCWSTR name)
|
|||
}
|
||||
ClosePrinter( hPrinter );
|
||||
HeapFree( GetProcessHeap(), 0, nameA );
|
||||
if (ppd) unlink(ppd);
|
||||
if (needs_unlink) unlink( ppd_filename );
|
||||
HeapFree( GetProcessHeap(), 0, ppd_filename );
|
||||
list_add_head( &printer_list, &pi->entry );
|
||||
return pi;
|
||||
|
||||
fail:
|
||||
if (hPrinter) ClosePrinter( hPrinter );
|
||||
HeapFree(PSDRV_Heap, 0, ppdFileName);
|
||||
HeapFree(PSDRV_Heap, 0, pi->FontSubTable);
|
||||
HeapFree(PSDRV_Heap, 0, pi->friendly_name);
|
||||
HeapFree(PSDRV_Heap, 0, pi->Devmode);
|
||||
HeapFree(PSDRV_Heap, 0, pi);
|
||||
HeapFree( GetProcessHeap(), 0, nameA );
|
||||
if (ppd) unlink(ppd);
|
||||
if (needs_unlink) unlink( ppd_filename );
|
||||
HeapFree( GetProcessHeap(), 0, ppd_filename );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue