[PATCH] winspool: Implement EnumFormsA/W with built-in forms
Marcel Partap
mpartap at gmx.net
Sun Apr 27 14:50:18 CDT 2008
---
dlls/winspool.drv/info.c | 165 ++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 154 insertions(+), 11 deletions(-)
diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c
index 5057c0d..135c297 100644
--- a/dlls/winspool.drv/info.c
+++ b/dlls/winspool.drv/info.c
@@ -122,6 +122,17 @@ typedef struct {
WCHAR *document_title;
} job_t;
+typedef struct {
+ SIZEL size;
+ RECTL area;
+ DWORD formorder;
+ DWORD flags;
+} form_regentry_t;
+
+typedef struct {
+ WCHAR formname[CCHFORMNAME];
+ form_regentry_t formdata;
+} builtin_form_t;
typedef struct {
LPCWSTR envname;
@@ -253,6 +264,12 @@ static const WCHAR LPR_Port[] = {'L','P','R',':',0};
static const WCHAR default_doc_title[] = {'L','o','c','a','l',' ','D','o','w','n','l','e','v','e','l',' ',
'D','o','c','u','m','e','n','t',0};
+static const builtin_form_t builtin_forms[] = {
+ {{'L','e','t','t','e','r',0}, {{216000,279000}, {0,0,216000,279000}, 0, FORM_BUILTIN}},
+ {{'A','3',0}, {{297000,420000}, {0,0,297000,420000}, 0, FORM_BUILTIN}},
+ {{'A','4',0}, {{210000,297000}, {0,0,210000,297000}, 0, FORM_BUILTIN}},
+ {{'A','5',0}, {{148000,210000}, {0,0,148000,210000}, 0, FORM_BUILTIN}} };
+
static const DWORD di_sizeof[] = {0, sizeof(DRIVER_INFO_1W), sizeof(DRIVER_INFO_2W),
sizeof(DRIVER_INFO_3W), sizeof(DRIVER_INFO_4W),
sizeof(DRIVER_INFO_5W), sizeof(DRIVER_INFO_6W),
@@ -7159,23 +7176,149 @@ BOOL WINAPI DeletePrintProvidorW(LPWSTR pName, LPWSTR pEnvironment, LPWSTR pPrin
/******************************************************************************
* EnumFormsA (WINSPOOL.@)
*/
-BOOL WINAPI EnumFormsA( HANDLE hPrinter, DWORD Level, LPBYTE pForm,
- DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned )
-{
- FIXME("%p %x %p %x %p %p\n", hPrinter, Level, pForm, cbBuf, pcbNeeded, pcReturned);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+BOOL WINAPI EnumFormsA(HANDLE hPrinter, DWORD Level, LPBYTE pForm,
+ DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
+{
+ PFORM_INFO_1A fiA;
+ PFORM_INFO_1W fiW;
+ LPBYTE bufferW = NULL;
+ LPSTR strptr;
+ DWORD num = 0;
+ DWORD i;
+ DWORD len;
+ DWORD neededA = 0;
+ DWORD neededW = 0;
+ BOOL res = FALSE;
+
+ TRACE("(%p %d %p %d %p %p)\n", hPrinter, Level, pForm, cbBuf, pcbNeeded, pcReturned);
+
+ EnumFormsW(hPrinter, Level, NULL, 0, &neededW, &num);
+ if (!neededW)
+ goto end_efa;
+ bufferW = HeapAlloc(GetProcessHeap(), 0, neededW);
+ if (!EnumFormsW(hPrinter, Level, bufferW, neededW, &neededW, &num))
+ goto end_efa;
+ fiW = (PFORM_INFO_1W)bufferW;
+ for (i = 0; i < num; i++) {
+ neededA += sizeof(FORM_INFO_1A);
+ neededA += WideCharToMultiByte(CP_ACP, 0, fiW->pName, -1, NULL, 0, NULL, NULL);
+ fiW++;
+ }
+ if (cbBuf < neededA) {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ goto end_efa;
+ }
+ if (!pcbNeeded || !pcReturned) {
+ SetLastError(RPC_X_NULL_REF_POINTER);
+ goto end_efa;
+ }
+ if (!pForm) {
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ goto end_efa;
+ }
+ fiA = (PFORM_INFO_1A)pForm;
+ fiW = (PFORM_INFO_1W)bufferW;
+ strptr = (LPBYTE)fiA + num*sizeof(FORM_INFO_1A);
+ cbBuf -= num*sizeof(FORM_INFO_1A);
+ for (i = 0; i < num; i++) {
+ memcpy(fiA, fiW, sizeof(FORM_INFO_1A));
+ len = WideCharToMultiByte(CP_ACP, 0, fiW->pName, -1, strptr, cbBuf, NULL, NULL);
+ fiA->pName = strptr;
+ cbBuf -= len;
+ strptr += len;
+ fiA++;
+ fiW++;
+ }
+ res = TRUE;
+
+end_efa:
+ if (bufferW) HeapFree(GetProcessHeap(), 0, bufferW);
+ if (pcbNeeded) *pcbNeeded = neededA;
+ if (pcReturned && res) *pcReturned = num;
+
+ TRACE("returning %d with %d (%d Bytes for %d entries)\n", res, GetLastError(), neededA, num);
+ return res;
}
/******************************************************************************
* EnumFormsW (WINSPOOL.@)
+ * enumerates available paper forms (not printer specific even though
+ * MSDN suggests otherwise)
+ *
+ * PARAMS
+ * hPrinter (I) handle to printer (must be valid)
+ * Level (I) type of requested form information data structure
+ * pForm (O) pointer to user supplied buffer
+ * cbBuf (I) size of output buffer
+ * pcbNeeded (O) required/ written buffer space
+ * pcReturned (O) number of returned forms
+ *
+ * RETURNS
+ * Success: TRUE (non-zero value)
+ * Failure: FALSE (0)
+ *
+ * NOTES
+ * fixme: level 2 not supported
*/
-BOOL WINAPI EnumFormsW( HANDLE hPrinter, DWORD Level, LPBYTE pForm,
- DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned )
+BOOL WINAPI EnumFormsW(HANDLE hPrinter, DWORD Level, LPBYTE pForm,
+ DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
{
- FIXME("%p %x %p %x %p %p\n", hPrinter, Level, pForm, cbBuf, pcbNeeded, pcReturned);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ opened_printer_t *printer = NULL;
+ PFORM_INFO_1W fiW;
+ LPWSTR strptr;
+ DWORD numbuiltin = 0;
+ DWORD i;
+ DWORD needed = 0;
+ BOOL res = FALSE;
+
+ TRACE("(%p %d %p %d %p %p)\n", hPrinter, Level, pForm, cbBuf, pcbNeeded, pcReturned);
+
+ if (!(printer = get_opened_printer(hPrinter))) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ goto end_efw;
+ }
+ if (Level != 1) {
+ if (Level == 2)
+ FIXME("level 2 not yet supported\n");
+ SetLastError(ERROR_INVALID_LEVEL);
+ goto end_efw;
+ }
+
+ numbuiltin = sizeof(builtin_forms)/sizeof(builtin_form_t);
+ for (i = 0; i < numbuiltin; i++) {
+ needed += sizeof(FORM_INFO_1W) + (strlenW(builtin_forms[i].formname)+1)*sizeof(WCHAR);
+ }
+
+ if (cbBuf < needed) {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ goto end_efw;
+ }
+ if (!pForm) {
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ goto end_efw;
+ }
+ if (!pcbNeeded || !pcReturned) {
+ SetLastError(RPC_X_NULL_REF_POINTER);
+ goto end_efw;
+ }
+ strptr = (LPWSTR)(pForm + numbuiltin*sizeof(FORM_INFO_1W));
+ fiW = (PFORM_INFO_1W)pForm;
+ for (i = 0; i < numbuiltin; i++) {
+ fiW->pName = lstrcpyW(strptr, builtin_forms[i].formname);
+ fiW->Size = builtin_forms[i].formdata.size;
+ fiW->ImageableArea = builtin_forms[i].formdata.area;
+ fiW->Flags = builtin_forms[i].formdata.flags;
+ fiW++;
+ strptr += lstrlenW(builtin_forms[i].formname)+1;
+ }
+ res = TRUE;
+
+end_efw:
+ if (pcbNeeded) *pcbNeeded = needed;
+ if (pcReturned && res) *pcReturned = numbuiltin;
+
+ TRACE("returning %d with %d (%d Bytes for %d entries)\n", res, GetLastError(), needed, numbuiltin);
+ return res;
}
/*****************************************************************************
--
1.5.5.1
--------------060906090307040206020505--
More information about the wine-patches
mailing list