2 * PROJECT: ReactOS Spooler API
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Functions related to Forms
5 * COPYRIGHT: Copyright 2017 Colin Finck (colin@reactos.org)
9 #include <marshalling/forms.h>
12 AddFormA(HANDLE hPrinter
, DWORD Level
, PBYTE pForm
)
19 pfi2A
= (PFORM_INFO_2A
)pForm
;
21 TRACE("AddFormA(%p, %lu, %p)\n", hPrinter
, Level
, pForm
);
23 if ((Level
< 1) || (Level
> 2))
25 ERR("Level = %d, unsupported!\n", Level
);
26 SetLastError(ERROR_INVALID_LEVEL
);
32 SetLastError(ERROR_INVALID_PARAMETER
);
36 ZeroMemory(&pfi2W
, sizeof(FORM_INFO_2W
));
40 len
= MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pName
, -1, NULL
, 0);
41 pfi2W
.pName
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
42 MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pName
, -1, pfi2W
.pName
, len
);
45 pfi2W
.Flags
= pfi2A
->Flags
;
46 pfi2W
.Size
= pfi2A
->Size
;
47 pfi2W
.ImageableArea
= pfi2A
->ImageableArea
;
53 len
= MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pKeyword
, -1, NULL
, 0);
54 pfi2W
.pKeyword
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
55 MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pKeyword
, -1, (LPWSTR
)pfi2W
.pKeyword
, len
);
60 len
= MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pMuiDll
, -1, NULL
, 0);
61 pfi2W
.pMuiDll
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
62 MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pMuiDll
, -1, (LPWSTR
)pfi2W
.pMuiDll
, len
);
65 if (pfi2A
->pDisplayName
)
67 len
= MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pDisplayName
, -1, NULL
, 0);
68 pfi2W
.pDisplayName
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
69 MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pDisplayName
, -1, (LPWSTR
)pfi2W
.pDisplayName
, len
);
71 pfi2W
.StringType
= pfi2A
->StringType
;
72 pfi2W
.dwResourceId
= pfi2A
->dwResourceId
;
73 pfi2W
.wLangId
= pfi2A
->wLangId
;
76 res
= AddFormW( hPrinter
, Level
, (PBYTE
)&pfi2W
);
78 if (pfi2W
.pName
) HeapFree(GetProcessHeap(), 0, pfi2W
.pName
);
79 if (pfi2W
.pKeyword
) HeapFree(GetProcessHeap(), 0, (LPWSTR
)pfi2W
.pKeyword
);
80 if (pfi2W
.pMuiDll
) HeapFree(GetProcessHeap(), 0, (LPWSTR
)pfi2W
.pMuiDll
);
81 if (pfi2W
.pDisplayName
) HeapFree(GetProcessHeap(), 0, (LPWSTR
)pfi2W
.pDisplayName
);
87 AddFormW(HANDLE hPrinter
, DWORD Level
, PBYTE pForm
)
90 WINSPOOL_FORM_CONTAINER FormInfoContainer
;
91 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
93 TRACE("AddFormW(%p, %lu, %p)\n", hPrinter
, Level
, pForm
);
98 dwErrorCode
= ERROR_INVALID_HANDLE
;
102 if ((Level
< 1) || (Level
> 2))
104 ERR("Level = %d, unsupported!\n", Level
);
105 SetLastError(ERROR_INVALID_LEVEL
);
109 FormInfoContainer
.FormInfo
.pFormInfo1
= (WINSPOOL_FORM_INFO_1
*)pForm
;
110 FormInfoContainer
.Level
= Level
;
115 dwErrorCode
= _RpcAddForm(pHandle
->hPrinter
, &FormInfoContainer
);
117 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
119 dwErrorCode
= RpcExceptionCode();
120 ERR("_RpcAddForm failed with exception code %lu!\n", dwErrorCode
);
124 SetLastError(dwErrorCode
);
125 return (dwErrorCode
== ERROR_SUCCESS
);
129 DeleteFormA(HANDLE hPrinter
, PSTR pFormName
)
131 UNICODE_STRING FormNameW
;
134 TRACE("DeleteFormA(%p, %s)\n", hPrinter
, pFormName
);
136 AsciiToUnicode(&FormNameW
, pFormName
);
138 Ret
= DeleteFormW( hPrinter
, FormNameW
.Buffer
);
140 RtlFreeUnicodeString(&FormNameW
);
146 DeleteFormW(HANDLE hPrinter
, PWSTR pFormName
)
149 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
151 TRACE("DeleteFormW(%p, %S)\n", hPrinter
, pFormName
);
156 dwErrorCode
= ERROR_INVALID_HANDLE
;
163 dwErrorCode
= _RpcDeleteForm(pHandle
->hPrinter
, pFormName
);
165 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
167 dwErrorCode
= RpcExceptionCode();
168 ERR("_RpcDeleteForm failed with exception code %lu!\n", dwErrorCode
);
172 SetLastError(dwErrorCode
);
173 return (dwErrorCode
== ERROR_SUCCESS
);
177 EnumFormsA(HANDLE hPrinter
, DWORD Level
, PBYTE pForm
, DWORD cbBuf
, PDWORD pcbNeeded
, PDWORD pcReturned
)
179 DWORD dwErrorCode
, i
;
180 PFORM_INFO_2W pfi2w
= (PFORM_INFO_2W
)pForm
;
182 TRACE("EnumFormsA(%p, %lu, %p, %lu, %p, %p)\n", hPrinter
, Level
, pForm
, cbBuf
, pcbNeeded
, pcReturned
);
184 if ( EnumFormsW( hPrinter
, Level
, pForm
, cbBuf
, pcbNeeded
, pcReturned
) )
186 for ( i
= 0; i
< *pcReturned
; i
++ )
191 dwErrorCode
= UnicodeToAnsiInPlace((LPWSTR
)pfi2w
[i
].pKeyword
);
192 if (dwErrorCode
!= ERROR_SUCCESS
)
196 dwErrorCode
= UnicodeToAnsiInPlace((LPWSTR
)pfi2w
[i
].pMuiDll
);
197 if (dwErrorCode
!= ERROR_SUCCESS
)
201 dwErrorCode
= UnicodeToAnsiInPlace((LPWSTR
)pfi2w
[i
].pDisplayName
);
202 if (dwErrorCode
!= ERROR_SUCCESS
)
208 dwErrorCode
= UnicodeToAnsiInPlace(pfi2w
[i
].pName
);
209 if (dwErrorCode
!= ERROR_SUCCESS
)
222 EnumFormsW(HANDLE hPrinter
, DWORD Level
, PBYTE pForm
, DWORD cbBuf
, PDWORD pcbNeeded
, PDWORD pcReturned
)
225 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
227 TRACE("EnumFormsW(%p, %lu, %p, %lu, %p, %p)\n", hPrinter
, Level
, pForm
, cbBuf
, pcbNeeded
, pcReturned
);
232 dwErrorCode
= ERROR_INVALID_HANDLE
;
236 if ((Level
< 1) || (Level
> 2))
238 ERR("Level = %d, unsupported!\n", Level
);
239 dwErrorCode
= ERROR_INVALID_LEVEL
;
246 dwErrorCode
= _RpcEnumForms(pHandle
->hPrinter
, Level
, pForm
, cbBuf
, pcbNeeded
, pcReturned
);
248 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
250 dwErrorCode
= RpcExceptionCode();
251 ERR("_RpcEnumForms failed with exception code %lu!\n", dwErrorCode
);
255 if (dwErrorCode
== ERROR_SUCCESS
)
257 // Replace relative offset addresses in the output by absolute pointers.
258 ASSERT(Level
>= 1 && Level
<= 2);
259 MarshallUpStructuresArray(cbBuf
, pForm
, *pcReturned
, pFormInfoMarshalling
[Level
]->pInfo
, pFormInfoMarshalling
[Level
]->cbStructureSize
, TRUE
);
263 SetLastError(dwErrorCode
);
264 return (dwErrorCode
== ERROR_SUCCESS
);
268 GetFormA(HANDLE hPrinter
, PSTR pFormName
, DWORD Level
, PBYTE pForm
, DWORD cbBuf
, PDWORD pcbNeeded
)
270 DWORD dwErrorCode
, len
;
271 LPWSTR FormNameW
= NULL
;
272 FORM_INFO_2W
* pfi2w
= (FORM_INFO_2W
*)pForm
;
274 TRACE("GetFormA(%p, %s, %lu, %p, %lu, %p)\n", hPrinter
, pFormName
, Level
, pForm
, cbBuf
, pcbNeeded
);
278 len
= MultiByteToWideChar(CP_ACP
, 0, pFormName
, -1, NULL
, 0);
279 FormNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
280 MultiByteToWideChar(CP_ACP
, 0, pFormName
, -1, FormNameW
, len
);
283 if ( GetFormW( hPrinter
, FormNameW
, Level
, pForm
, cbBuf
, pcbNeeded
) )
288 dwErrorCode
= UnicodeToAnsiInPlace((LPWSTR
)pfi2w
->pKeyword
);
289 if (dwErrorCode
!= ERROR_SUCCESS
)
293 dwErrorCode
= UnicodeToAnsiInPlace((LPWSTR
)pfi2w
->pMuiDll
);
294 if (dwErrorCode
!= ERROR_SUCCESS
)
298 dwErrorCode
= UnicodeToAnsiInPlace((LPWSTR
)pfi2w
->pDisplayName
);
299 if (dwErrorCode
!= ERROR_SUCCESS
)
305 dwErrorCode
= UnicodeToAnsiInPlace(pfi2w
->pName
);
306 if (dwErrorCode
!= ERROR_SUCCESS
)
313 ERR("Level = %d, unsupported!\n", Level
);
314 dwErrorCode
= ERROR_INVALID_HANDLE
;
315 SetLastError(dwErrorCode
);
320 if (FormNameW
) HeapFree(GetProcessHeap(), 0, FormNameW
);
321 return (dwErrorCode
== ERROR_SUCCESS
);
325 GetFormW(HANDLE hPrinter
, PWSTR pFormName
, DWORD Level
, PBYTE pForm
, DWORD cbBuf
, PDWORD pcbNeeded
)
328 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
330 TRACE("GetFormW(%p, %S, %lu, %p, %lu, %p)\n", hPrinter
, pFormName
, Level
, pForm
, cbBuf
, pcbNeeded
);
335 dwErrorCode
= ERROR_INVALID_HANDLE
;
339 // Dismiss invalid levels already at this point.
340 if ((Level
< 1) || (Level
> 2))
342 ERR("Level = %d, unsupported!\n", Level
);
343 dwErrorCode
= ERROR_INVALID_LEVEL
;
348 ZeroMemory(pForm
, cbBuf
);
353 dwErrorCode
= _RpcGetForm(pHandle
->hPrinter
, pFormName
, Level
, pForm
, cbBuf
, pcbNeeded
);
355 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
357 dwErrorCode
= RpcExceptionCode();
358 ERR("_RpcGetForm failed with exception code %lu!\n", dwErrorCode
);
362 if (dwErrorCode
== ERROR_SUCCESS
)
364 // Replace relative offset addresses in the output by absolute pointers.
365 ASSERT(Level
>= 1 && Level
<= 2);
366 MarshallUpStructure(cbBuf
, pForm
, pFormInfoMarshalling
[Level
]->pInfo
, pFormInfoMarshalling
[Level
]->cbStructureSize
, TRUE
);
370 SetLastError(dwErrorCode
);
371 return (dwErrorCode
== ERROR_SUCCESS
);
375 SetFormA(HANDLE hPrinter
, PSTR pFormName
, DWORD Level
, PBYTE pForm
)
378 FORM_INFO_2A
* pfi2A
;
379 LPWSTR FormNameW
= NULL
;
383 pfi2A
= (FORM_INFO_2A
*) pForm
;
385 TRACE("SetFormA(%p, %s, %lu, %p)\n", hPrinter
, pFormName
, Level
, pForm
);
387 if ((Level
< 1) || (Level
> 2))
389 ERR("Level = %d, unsupported!\n", Level
);
390 SetLastError(ERROR_INVALID_LEVEL
);
396 SetLastError(ERROR_INVALID_PARAMETER
);
402 len
= MultiByteToWideChar(CP_ACP
, 0, pFormName
, -1, NULL
, 0);
403 FormNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
404 MultiByteToWideChar(CP_ACP
, 0, pFormName
, -1, FormNameW
, len
);
407 ZeroMemory(&pfi2W
, sizeof(FORM_INFO_2W
));
411 len
= MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pName
, -1, NULL
, 0);
412 pfi2W
.pName
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
413 MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pName
, -1, pfi2W
.pName
, len
);
416 pfi2W
.Flags
= pfi2A
->Flags
;
417 pfi2W
.Size
= pfi2A
->Size
;
418 pfi2W
.ImageableArea
= pfi2A
->ImageableArea
;
424 len
= MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pKeyword
, -1, NULL
, 0);
425 pfi2W
.pKeyword
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
426 MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pKeyword
, -1, (LPWSTR
)pfi2W
.pKeyword
, len
);
431 len
= MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pMuiDll
, -1, NULL
, 0);
432 pfi2W
.pMuiDll
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
433 MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pMuiDll
, -1, (LPWSTR
)pfi2W
.pMuiDll
, len
);
436 if (pfi2A
->pDisplayName
)
438 len
= MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pDisplayName
, -1, NULL
, 0);
439 pfi2W
.pDisplayName
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
440 MultiByteToWideChar(CP_ACP
, 0, pfi2A
->pDisplayName
, -1, (LPWSTR
)pfi2W
.pDisplayName
, len
);
442 pfi2W
.StringType
= pfi2A
->StringType
;
443 pfi2W
.dwResourceId
= pfi2A
->dwResourceId
;
444 pfi2W
.wLangId
= pfi2A
->wLangId
;
447 res
= SetFormW( hPrinter
, FormNameW
, Level
, (PBYTE
)&pfi2W
);
449 if (FormNameW
) HeapFree(GetProcessHeap(), 0, FormNameW
);
450 if (pfi2W
.pName
) HeapFree(GetProcessHeap(), 0, pfi2W
.pName
);
451 if (pfi2W
.pKeyword
) HeapFree(GetProcessHeap(), 0, (LPWSTR
)pfi2W
.pKeyword
);
452 if (pfi2W
.pMuiDll
) HeapFree(GetProcessHeap(), 0, (LPWSTR
)pfi2W
.pMuiDll
);
453 if (pfi2W
.pDisplayName
) HeapFree(GetProcessHeap(), 0, (LPWSTR
)pfi2W
.pDisplayName
);
459 SetFormW(HANDLE hPrinter
, PWSTR pFormName
, DWORD Level
, PBYTE pForm
)
462 WINSPOOL_FORM_CONTAINER FormInfoContainer
;
463 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
465 TRACE("SetFormW(%p, %S, %lu, %p)\n", hPrinter
, pFormName
, Level
, pForm
);
470 ERR("Level = %d, unsupported!\n", Level
);
471 dwErrorCode
= ERROR_INVALID_HANDLE
;
475 FormInfoContainer
.FormInfo
.pFormInfo1
= (WINSPOOL_FORM_INFO_1
*)pForm
;
476 FormInfoContainer
.Level
= Level
;
481 dwErrorCode
= _RpcSetForm(pHandle
->hPrinter
, pFormName
, &FormInfoContainer
);
483 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
485 dwErrorCode
= RpcExceptionCode();
489 SetLastError(dwErrorCode
);
490 return (dwErrorCode
== ERROR_SUCCESS
);