2 * Print processor implementation.
4 * Copyright 2022 Piotr Caban for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* Missing datatypes support:
30 * Implement print processor features like e.g. printing multiple copies. */
36 #include "ddk/winsplp.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(winprint
);
42 #define PP_MAGIC 0x952173fd
52 static struct pp_data
* get_handle_data(HANDLE pp
)
54 struct pp_data
*ret
= (struct pp_data
*)pp
;
56 if (!ret
|| ret
->magic
!= PP_MAGIC
)
58 SetLastError(ERROR_INVALID_HANDLE
);
64 BOOL WINAPI
EnumPrintProcessorDatatypesW(WCHAR
*server
, WCHAR
*name
, DWORD level
,
65 BYTE
*datatypes
, DWORD size
, DWORD
*needed
, DWORD
*no
)
67 static const WCHAR raw
[] = L
"RAW";
68 static const WCHAR text
[] = L
"TEXT";
70 DATATYPES_INFO_1W
*info
= (DATATYPES_INFO_1W
*)datatypes
;
72 TRACE("%s, %s, %ld, %p, %ld, %p, %p\n", debugstr_w(server
), debugstr_w(name
),
73 level
, datatypes
, size
, needed
, no
);
77 SetLastError(ERROR_INVALID_PARAMETER
);
82 *needed
= 2 * sizeof(*info
) + sizeof(raw
) + sizeof(text
);
84 if (level
!= 1 || (size
&& !datatypes
))
86 SetLastError(ERROR_INVALID_PARAMETER
);
92 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
97 info
[0].pName
= (WCHAR
*)(info
+ 2);
98 info
[1].pName
= info
[0].pName
+ sizeof(raw
) / sizeof(WCHAR
);
99 memcpy(info
[0].pName
, raw
, sizeof(raw
));
100 memcpy(info
[1].pName
, text
, sizeof(text
));
104 HANDLE WINAPI
OpenPrintProcessor(WCHAR
*port
, PRINTPROCESSOROPENDATA
*open_data
)
106 struct pp_data
*data
;
109 TRACE("%s, %p\n", debugstr_w(port
), open_data
);
111 if (!port
|| !open_data
|| !open_data
->pDatatype
)
113 SetLastError(ERROR_INVALID_PARAMETER
);
116 if (wcscmp(open_data
->pDatatype
, L
"RAW") && wcscmp(open_data
->pDatatype
, L
"TEXT"))
118 SetLastError(ERROR_INVALID_DATATYPE
);
122 if (!OpenPrinterW(port
, &hport
, NULL
))
125 data
= LocalAlloc(LMEM_FIXED
| LMEM_ZEROINIT
, sizeof(*data
));
128 data
->magic
= PP_MAGIC
;
130 data
->doc_name
= wcsdup(open_data
->pDocumentName
);
131 data
->out_file
= wcsdup(open_data
->pOutputFile
);
135 BOOL WINAPI
PrintDocumentOnPrintProcessor(HANDLE pp
, WCHAR
*doc_name
)
137 struct pp_data
*data
= get_handle_data(pp
);
143 TRACE("%p, %s\n", pp
, debugstr_w(doc_name
));
148 if (!OpenPrinterW(doc_name
, &spool_data
, NULL
))
151 info
.pDocName
= data
->doc_name
;
152 info
.pOutputFile
= data
->out_file
;
153 info
.pDatatype
= (WCHAR
*)L
"RAW";
154 if (!StartDocPrinterW(data
->hport
, 1, (BYTE
*)&info
))
156 ClosePrinter(spool_data
);
160 while (ReadPrinter(spool_data
, buf
, sizeof(buf
), &r
) && r
)
162 if (!WritePrinter(data
->hport
, buf
, r
, &w
) || r
!= w
)
164 ClosePrinter(spool_data
);
165 EndDocPrinter(data
->hport
);
169 ClosePrinter(spool_data
);
171 return EndDocPrinter(data
->hport
);
174 BOOL WINAPI
ControlPrintProcessor(HANDLE pp
, DWORD cmd
)
176 FIXME("%p, %ld\n", pp
, cmd
);
177 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
181 BOOL WINAPI
ClosePrintProcessor(HANDLE pp
)
183 struct pp_data
*data
= get_handle_data(pp
);
190 ClosePrinter(data
->hport
);
191 free(data
->doc_name
);
192 free(data
->out_file
);
194 memset(data
, 0, sizeof(*data
));
199 HRESULT WINAPI
DllRegisterServer(void)
201 AddPrintProcessorW(NULL
, (WCHAR
*)L
"Windows 4.0", (WCHAR
*)L
"winprint.dll", (WCHAR
*)L
"winprint");
202 AddPrintProcessorW(NULL
, NULL
, (WCHAR
*)L
"winprint.dll", (WCHAR
*)L
"winprint");