mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 08:54:05 +00:00
localspl: Use print processor in ScheduleJob.
This commit is contained in:
parent
b7714744c8
commit
017e9557db
|
@ -292,7 +292,7 @@ static LONG last_job_id;
|
||||||
static const WCHAR fmt_driversW[] =
|
static const WCHAR fmt_driversW[] =
|
||||||
L"System\\CurrentControlSet\\control\\Print\\Environments\\%s\\Drivers%s";
|
L"System\\CurrentControlSet\\control\\Print\\Environments\\%s\\Drivers%s";
|
||||||
static const WCHAR fmt_printprocessorsW[] =
|
static const WCHAR fmt_printprocessorsW[] =
|
||||||
L"System\\CurrentControlSet\\Control\\Print\\Environments\\%s\\Print Processors";
|
L"System\\CurrentControlSet\\Control\\Print\\Environments\\%s\\Print Processors\\";
|
||||||
static const WCHAR monitorsW[] = L"System\\CurrentControlSet\\Control\\Print\\Monitors\\";
|
static const WCHAR monitorsW[] = L"System\\CurrentControlSet\\Control\\Print\\Monitors\\";
|
||||||
static const WCHAR printersW[] = L"System\\CurrentControlSet\\Control\\Print\\Printers";
|
static const WCHAR printersW[] = L"System\\CurrentControlSet\\Control\\Print\\Printers";
|
||||||
static const WCHAR winnt_cv_portsW[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Ports";
|
static const WCHAR winnt_cv_portsW[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Ports";
|
||||||
|
@ -3557,19 +3557,127 @@ static BOOL WINAPI fpGetJob(HANDLE hprinter, DWORD job_id, DWORD level,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HMODULE hmod;
|
||||||
|
WCHAR *name;
|
||||||
|
BOOL (WINAPI *enum_datatypes)(WCHAR *, WCHAR *, DWORD,
|
||||||
|
BYTE *, DWORD, DWORD *, DWORD *);
|
||||||
|
HANDLE (WINAPI *open)(WCHAR *, PRINTPROCESSOROPENDATA *);
|
||||||
|
BOOL (WINAPI *print)(HANDLE, WCHAR *);
|
||||||
|
BOOL (WINAPI *close)(HANDLE);
|
||||||
|
} printproc_t;
|
||||||
|
|
||||||
|
static printproc_t * print_proc_load(const WCHAR *name)
|
||||||
|
{
|
||||||
|
WCHAR *reg_path, path[2 * MAX_PATH];
|
||||||
|
printproc_t *ret;
|
||||||
|
DWORD size, len;
|
||||||
|
LSTATUS status;
|
||||||
|
HKEY hkey;
|
||||||
|
|
||||||
|
size = sizeof(fmt_printprocessorsW) +
|
||||||
|
(wcslen(env_arch.envname) + wcslen(name)) * sizeof(WCHAR);
|
||||||
|
reg_path = malloc(size);
|
||||||
|
if (!reg_path)
|
||||||
|
return NULL;
|
||||||
|
swprintf(reg_path, size / sizeof(WCHAR), fmt_printprocessorsW, env_arch.envname);
|
||||||
|
wcscat(reg_path, name);
|
||||||
|
|
||||||
|
status = RegOpenKeyW(HKEY_LOCAL_MACHINE, reg_path, &hkey);
|
||||||
|
free(reg_path);
|
||||||
|
if (status != ERROR_SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!fpGetPrintProcessorDirectory(NULL, NULL, 1, (BYTE *)path, sizeof(path), &size))
|
||||||
|
{
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
len = size / sizeof(WCHAR);
|
||||||
|
path[len - 1] = '\\';
|
||||||
|
|
||||||
|
size = sizeof(path) - len * sizeof(WCHAR);
|
||||||
|
status = RegQueryValueExW(hkey, L"Driver", NULL, NULL, (BYTE *)(path + len), &size);
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
if (status != ERROR_SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ret = malloc(sizeof(*ret));
|
||||||
|
if (!ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
TRACE("loading print processor: %s\n", debugstr_w(path));
|
||||||
|
|
||||||
|
ret->hmod = LoadLibraryW(path);
|
||||||
|
if (!ret->hmod)
|
||||||
|
{
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->enum_datatypes = (void *)GetProcAddress(ret->hmod, "EnumPrintProcessorDatatypesW");
|
||||||
|
ret->open = (void *)GetProcAddress(ret->hmod, "OpenPrintProcessor");
|
||||||
|
ret->print = (void *)GetProcAddress(ret->hmod, "PrintDocumentOnPrintProcessor");
|
||||||
|
ret->close = (void *)GetProcAddress(ret->hmod, "ClosePrintProcessor");
|
||||||
|
if (!ret->enum_datatypes || !ret->open || !ret->print || !ret->close)
|
||||||
|
{
|
||||||
|
FreeLibrary(ret->hmod);
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret->name = wcsdup(name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL print_proc_check_datatype(printproc_t *pp, const WCHAR *datatype)
|
||||||
|
{
|
||||||
|
DATATYPES_INFO_1W *types;
|
||||||
|
DWORD size, no, i;
|
||||||
|
|
||||||
|
if (!datatype)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pp->enum_datatypes(NULL, pp->name, 1, NULL, 0, &size, &no);
|
||||||
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
types = malloc(size);
|
||||||
|
if (!types)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!pp->enum_datatypes(NULL, pp->name, 1, (BYTE *)types, size, &size, &no))
|
||||||
|
{
|
||||||
|
free(types);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < no; i++)
|
||||||
|
{
|
||||||
|
if (!wcscmp(types[i].pName, datatype))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(types);
|
||||||
|
return i < no;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_proc_unload(printproc_t *pp)
|
||||||
|
{
|
||||||
|
FreeLibrary(pp->hmod);
|
||||||
|
free(pp->name);
|
||||||
|
free(pp);
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL WINAPI fpScheduleJob(HANDLE hprinter, DWORD job_id)
|
static BOOL WINAPI fpScheduleJob(HANDLE hprinter, DWORD job_id)
|
||||||
{
|
{
|
||||||
BOOL ret_startdoc = FALSE, ret_open = FALSE, ret = TRUE;
|
|
||||||
printer_t *printer = (printer_t *)hprinter;
|
printer_t *printer = (printer_t *)hprinter;
|
||||||
|
WCHAR output[1024], name[1024], *datatype;
|
||||||
|
PRINTPROCESSOROPENDATA pp_data;
|
||||||
const WCHAR *port_name, *port;
|
const WCHAR *port_name, *port;
|
||||||
WCHAR output[1024];
|
|
||||||
DOC_INFO_1W info;
|
|
||||||
job_info_t *job;
|
job_info_t *job;
|
||||||
monitor_t *mon;
|
printproc_t *pp;
|
||||||
BYTE buf[4096];
|
BOOL ret = TRUE;
|
||||||
HANDLE hport;
|
HANDLE hpp;
|
||||||
DWORD r, w;
|
|
||||||
HANDLE hf;
|
|
||||||
HKEY hkey;
|
HKEY hkey;
|
||||||
|
|
||||||
TRACE("%p %ld\n", hprinter, job_id);
|
TRACE("%p %ld\n", hprinter, job_id);
|
||||||
|
@ -3594,18 +3702,6 @@ static BOOL WINAPI fpScheduleJob(HANDLE hprinter, DWORD job_id)
|
||||||
TRACE("need to schedule job %ld filename %s to port %s\n", job->id,
|
TRACE("need to schedule job %ld filename %s to port %s\n", job->id,
|
||||||
debugstr_w(job->filename), debugstr_w(port));
|
debugstr_w(job->filename), debugstr_w(port));
|
||||||
|
|
||||||
hf = CreateFileW(job->filename, GENERIC_READ, FILE_SHARE_READ,
|
|
||||||
NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
if (hf == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
WARN("can't open spool file: %s\n", debugstr_w(job->filename));
|
|
||||||
DeleteFileW(job->filename);
|
|
||||||
free_job(job);
|
|
||||||
LeaveCriticalSection(&printer->info->jobs_cs);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: use print processor */
|
|
||||||
port_name = port;
|
port_name = port;
|
||||||
if ((isalpha(port[0]) && port[1] == ':') ||
|
if ((isalpha(port[0]) && port[1] == ':') ||
|
||||||
!wcsncmp(port, L"FILE:", ARRAY_SIZE(L"FILE:") - 1))
|
!wcsncmp(port, L"FILE:", ARRAY_SIZE(L"FILE:") - 1))
|
||||||
|
@ -3623,37 +3719,53 @@ static BOOL WINAPI fpScheduleJob(HANDLE hprinter, DWORD job_id)
|
||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(mon = monitor_load_by_port(port_name)) || !mon->monitor.pfnOpenPort ||
|
pp = print_proc_load(printer->info->print_proc);
|
||||||
!mon->monitor.pfnStartDocPort || !mon->monitor.pfnWritePort ||
|
if (!pp)
|
||||||
!mon->monitor.pfnEndDocPort || !mon->monitor.pfnClosePort)
|
|
||||||
{
|
{
|
||||||
FIXME("port not supported: %s\n", debugstr_w(port_name));
|
WARN("failed to load %s print processor\n", debugstr_w(printer->info->print_proc));
|
||||||
ret = FALSE;
|
pp = print_proc_load(L"winprint");
|
||||||
|
}
|
||||||
|
if (!pp)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (job->datatype)
|
||||||
|
datatype = job->datatype;
|
||||||
|
else if (printer->datatype)
|
||||||
|
datatype = printer->datatype;
|
||||||
|
else
|
||||||
|
datatype = printer->info->datatype;
|
||||||
|
|
||||||
|
if (!print_proc_check_datatype(pp, datatype))
|
||||||
|
{
|
||||||
|
WARN("%s datatype not supported by %s\n", debugstr_w(datatype),
|
||||||
|
debugstr_w(printer->info->print_proc));
|
||||||
|
print_proc_unload(pp);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret)
|
swprintf(name, ARRAY_SIZE(name), L"%s, Port", port_name);
|
||||||
ret = ret_open = mon->monitor.pfnOpenPort(mon->hmon, (WCHAR *)port_name, &hport);
|
pp_data.pDevMode = job->devmode;
|
||||||
|
pp_data.pDatatype = datatype;
|
||||||
if (ret)
|
pp_data.pParameters = NULL;
|
||||||
|
pp_data.pDocumentName = job->document_title;
|
||||||
|
pp_data.JobId = job->id;
|
||||||
|
pp_data.pOutputFile = (WCHAR *)port;
|
||||||
|
pp_data.pPrinterName = printer->name;
|
||||||
|
hpp = pp->open(name, &pp_data);
|
||||||
|
if (!hpp)
|
||||||
{
|
{
|
||||||
info.pDocName = job->document_title;
|
WARN("OpenPrintProcessor failed %ld\n", GetLastError());
|
||||||
info.pOutputFile = (WCHAR *)port;
|
print_proc_unload(pp);
|
||||||
info.pDatatype = NULL;
|
return FALSE;
|
||||||
ret = ret_startdoc = mon->monitor.pfnStartDocPort(hport, printer->info->name,
|
|
||||||
job_id, 1, (BYTE *)&info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (ret && ReadFile(hf, buf, sizeof(buf), &r, NULL) && r)
|
swprintf(name, ARRAY_SIZE(name), L"%s, Job %d", printer->name, job->id);
|
||||||
ret = mon->monitor.pfnWritePort(hport, buf, r, &w) && r == w;
|
ret = pp->print(hpp, name);
|
||||||
|
if (!ret)
|
||||||
|
WARN("PrintDocumentOnPrintProcessor failed %ld\n", GetLastError());
|
||||||
|
pp->close(hpp);
|
||||||
|
print_proc_unload(pp);
|
||||||
|
|
||||||
if (ret_startdoc)
|
|
||||||
mon->monitor.pfnEndDocPort(hport);
|
|
||||||
if (ret_open)
|
|
||||||
mon->monitor.pfnClosePort(hport);
|
|
||||||
if (mon)
|
|
||||||
monitor_unload(mon);
|
|
||||||
|
|
||||||
CloseHandle(hf);
|
|
||||||
DeleteFileW(job->filename);
|
DeleteFileW(job->filename);
|
||||||
free_job(job);
|
free_job(job);
|
||||||
LeaveCriticalSection(&printer->info->jobs_cs);
|
LeaveCriticalSection(&printer->info->jobs_cs);
|
||||||
|
|
Loading…
Reference in a new issue