2 * PROJECT: ReactOS Spooler Router
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Functions for managing print Forms
5 * COPYRIGHT: Copyright 2020 ReactOS
10 #define FORMINFOSIG '.2'
11 #define FORMMAXNAMESIZE CCHDEVICENAME-1
13 typedef struct _FORM_INFO_LIST
19 } FORM_INFO_LIST
, *PFORM_INFO_LIST
;
22 static DWORD _dwLastForm
;
25 static DWORD dwFormInfo1Offsets
[] = {
26 FIELD_OFFSET(FORM_INFO_1W
, pName
),
30 static DWORD dwFormInfo2Offsets
[] = {
31 FIELD_OFFSET(FORM_INFO_2W
, pName
),
32 FIELD_OFFSET(FORM_INFO_2W
, pKeyword
),
33 FIELD_OFFSET(FORM_INFO_2W
, pMuiDll
),
34 FIELD_OFFSET(FORM_INFO_2W
, pDisplayName
),
39 // Built in Form names
40 WCHAR wszLetter
[] = L
"Letter";
41 WCHAR wszLetterSmall
[] = L
"Letter Small";
42 WCHAR wszTabloid
[] = L
"Tabloid";
43 WCHAR wszLedger
[] = L
"Ledger";
44 WCHAR wszLegal
[] = L
"Legal";
45 WCHAR wszStatement
[] = L
"Statement";
46 WCHAR wszExecutive
[] = L
"Executive";
47 WCHAR wszA3
[] = L
"A3";
48 WCHAR wszA4
[] = L
"A4";
49 WCHAR wszA4Small
[] = L
"A4 Small";
50 WCHAR wszA5
[] = L
"A5";
51 WCHAR wszB4JIS
[] = L
"B4 (JIS)";
52 WCHAR wszB5JIS
[] = L
"B5 (JIS)";
53 WCHAR wszFolio
[] = L
"Folio";
54 WCHAR wszQuarto
[] = L
"Quarto";
55 WCHAR wsz10x14
[] = L
"10 x 14";
56 WCHAR wsz11x17
[] = L
"11 x 17";
57 WCHAR wszNote
[] = L
"Note";
58 WCHAR wszEnvelope9
[] = L
"Envelope #9";
59 WCHAR wszEnvelope10
[] = L
"Envelope #10";
60 WCHAR wszEnvelope11
[] = L
"Envelope #11";
61 WCHAR wszEnvelope12
[] = L
"Envelope #12";
62 WCHAR wszEnvelope14
[] = L
"Envelope #14";
63 WCHAR wszCsizesheet
[] = L
"C size sheet";
64 WCHAR wszDsizesheet
[] = L
"D size sheet";
65 WCHAR wszEsizesheet
[] = L
"E size sheet";
66 WCHAR wszEnvelopeDL
[] = L
"Envelope DL";
67 WCHAR wszEnvelopeC5
[] = L
"Envelope C5";
68 WCHAR wszEnvelopeC3
[] = L
"Envelope C3";
69 WCHAR wszEnvelopeC4
[] = L
"Envelope C4";
70 WCHAR wszEnvelopeC6
[] = L
"Envelope C6";
71 WCHAR wszEnvelope65
[] = L
"Envelope 65";
72 WCHAR wszEnvelopeB4
[] = L
"Envelope B4";
73 WCHAR wszEnvelopeB5
[] = L
"Envelope B5";
74 WCHAR wszEnvelopeB6
[] = L
"Envelope B6";
75 WCHAR wszEnvelope
[] = L
"Envelope";
76 WCHAR wszEnvelopeMonarch
[] = L
"Envelope Monarch";
77 WCHAR wsz634Envelope
[] = L
"6 3/4 Envelope";
78 WCHAR wszUSStdFanfold
[] = L
"US Std Fanfold";
79 WCHAR wszGermanStdFanfold
[] = L
"German Std Fanfold";
80 WCHAR wszGermanLegalFanfold
[] = L
"German Legal Fanfold";
81 WCHAR wszB4ISO
[] = L
"B4 (ISO)";
82 WCHAR wszJapanesePostcard
[] = L
"Japanese Postcard";
83 WCHAR wsz9x11
[] = L
"9 x 11";
84 WCHAR wsz10x11
[] = L
"10 x 11";
85 WCHAR wsz15x11
[] = L
"15 x 11";
86 WCHAR wszEnvelopeInvite
[] = L
"Envelope Invite";
87 WCHAR wszReserved48
[] = L
"Reserved48";
88 WCHAR wszReserved49
[] = L
"Reserved49";
89 WCHAR wszLetterExtra
[] = L
"Letter Extra";
90 WCHAR wszLegalExtra
[] = L
"Legal Extra";
91 WCHAR wszTabloidExtra
[] = L
"Tabloid Extra";
92 WCHAR wszA4Extra
[] = L
"A4 Extra";
93 WCHAR wszLetterTransverse
[] = L
"Letter Transverse";
94 WCHAR wszA4Transverse
[] = L
"A4 Transverse";
95 WCHAR wszLetterExtraTransverse
[] = L
"Letter Extra Transverse";
96 WCHAR wszSuperA
[] = L
"Super A";
97 WCHAR wszSuperB
[] = L
"Super B";
98 WCHAR wszLetterPlus
[] = L
"Letter Plus";
99 WCHAR wszA4Plus
[] = L
"A4 Plus";
100 WCHAR wszA5Transverse
[] = L
"A5 Transverse";
101 WCHAR wszB5JISTransverse
[] = L
"B5 (JIS) Transverse";
102 WCHAR wszA3Extra
[] = L
"A3 Extra";
103 WCHAR wszA5Extra
[] = L
"A5 Extra";
104 WCHAR wszB5ISOExtra
[] = L
"B5 (ISO) Extra";
105 WCHAR wszA0
[] = L
"A0";
106 WCHAR wszA3Transverse
[] = L
"A3 Transverse";
107 WCHAR wszA3ExtraTransverse
[] = L
"A3 Extra Transverse";
108 WCHAR wszJapaneseDoublePostcard
[] = L
"Japanese Double Postcard";
109 WCHAR wszA1
[] = L
"A1";
110 WCHAR wszJapaneseEnvelopeKaku2
[] = L
"Japanese Envelope Kaku #2";
111 WCHAR wszJapaneseEnvelopeKaku3
[] = L
"Japanese Envelope Kaku #3";
112 WCHAR wszJapaneseEnvelopeChou3
[] = L
"Japanese Envelope Chou #3";
113 WCHAR wszJapaneseEnvelopeChou4
[] = L
"Japanese Envelope Chou #4";
114 WCHAR wszLetterRotated
[] = L
"Letter Rotated";
115 WCHAR wszA3Rotated
[] = L
"A3 Rotated";
116 WCHAR wszA4Rotated
[] = L
"A4 Rotated";
117 WCHAR wszA5Rotated
[] = L
"A5 Rotated";
118 WCHAR wszB4JISRotated
[] = L
"B4 (JIS) Rotated";
119 WCHAR wszB5JISRotated
[] = L
"B5 (JIS) Rotated";
120 WCHAR wszJapanesePostcardRotated
[] = L
"Japanese Postcard Rotated";
121 WCHAR wszDoubleJapanPostcardRotated
[] = L
"Double Japan Postcard Rotated";
122 WCHAR wsA6Rotatedz
[] = L
"A6 Rotated";
123 WCHAR wszJapanEnvelopeKaku2Rotated
[] = L
"Japan Envelope Kaku #2 Rotated";
124 WCHAR wszJapanEnvelopeKaku3Rotated
[] = L
"Japan Envelope Kaku #3 Rotated";
125 WCHAR wszJapanEnvelopeChou3Rotated
[] = L
"Japan Envelope Chou #3 Rotated";
126 WCHAR wszJapanEnvelopeChou4Rotated
[] = L
"Japan Envelope Chou #4 Rotated";
127 WCHAR wszB6JIS
[] = L
"B6 (JIS)";
128 WCHAR wszB6JISRotated
[] = L
"B6 (JIS) Rotated";
129 WCHAR wsz12x11
[] = L
"12 x 11";
130 WCHAR wszJapanEnvelopeYou4
[] = L
"Japan Envelope You #4";
131 WCHAR wszJapanEnvelopeYou4Rotated
[] = L
"Japan Envelope You #4 Rotated";
132 WCHAR wszPRC16K
[] = L
"PRC 16K";
133 WCHAR wszPRC32K
[] = L
"PRC 32K";
134 WCHAR wszPRC32KBig
[] = L
"PRC 32K(Big)";
135 WCHAR wszPRCEnvelope1
[] = L
"PRC Envelope #1";
136 WCHAR wszPRCEnvelope2
[] = L
"PRC Envelope #2";
137 WCHAR wszPRCEnvelope3
[] = L
"PRC Envelope #3";
138 WCHAR wszPRCEnvelope4
[] = L
"PRC Envelope #4";
139 WCHAR wszPRCEnvelope5
[] = L
"PRC Envelope #5";
140 WCHAR wszPRCEnvelope6
[] = L
"PRC Envelope #6";
141 WCHAR wszPRCEnvelope7
[] = L
"PRC Envelope #7";
142 WCHAR wszPRCEnvelope8
[] = L
"PRC Envelope #8";
143 WCHAR wszPRCEnvelope9
[] = L
"PRC Envelope #9";
144 WCHAR wszPRCEnvelope10
[] = L
"PRC Envelope #10";
145 WCHAR wszPRC16KRotated
[] = L
"PRC 16K Rotated";
146 WCHAR wszPRC32KRotated
[] = L
"PRC 32K Rotated";
147 WCHAR wszPRC32KBigRotated
[] = L
"PRC 32K(Big) Rotated";
148 WCHAR wszPRCEnvelope1Rotated
[] = L
"PRC Envelope #1 Rotated";
149 WCHAR wszPRCEnvelope2Rotated
[] = L
"PRC Envelope #2 Rotated";
150 WCHAR wszPRCEnvelope3Rotated
[] = L
"PRC Envelope #3 Rotated";
151 WCHAR wszPRCEnvelope4Rotated
[] = L
"PRC Envelope #4 Rotated";
152 WCHAR wszPRCEnvelope5Rotated
[] = L
"PRC Envelope #5 Rotated";
153 WCHAR wszPRCEnvelope6Rotated
[] = L
"PRC Envelope #6 Rotated";
154 WCHAR wszPRCEnvelope7Rotated
[] = L
"PRC Envelope #7 Rotated";
155 WCHAR wszPRCEnvelope8Rotated
[] = L
"PRC Envelope #8 Rotated";
156 WCHAR wszPRCEnvelope9Rotated
[] = L
"PRC Envelope #9 Rotated";
157 WCHAR wszPRCEnvelope10Rotated
[] = L
"PRC Envelope #10 Rotated";
160 FORM_INFO_1W BuiltInForms
[] =
162 { FORM_USER
, wszLetter
, {215900, 279400},{ 0, 0, 215900, 279400}},
163 { FORM_USER
, wszLetterSmall
, {215900, 279400},{ 0, 0, 215900, 279400}},
164 { FORM_USER
, wszTabloid
, {279400, 431800},{ 0, 0, 279400, 431800}},
165 { FORM_USER
, wszLedger
, {431800, 279400},{ 0, 0, 431800, 279400}},
166 { FORM_USER
, wszLegal
, {215900, 355600},{ 0, 0, 215900, 355600}},
167 { FORM_USER
, wszStatement
, {139700, 215900},{ 0, 0, 139700, 215900}},
168 { FORM_USER
, wszExecutive
, {184150, 266700},{ 0, 0, 184150, 266700}},
169 { FORM_USER
, wszA3
, {297000, 420000},{ 0, 0, 297000, 420000}},
170 { FORM_USER
, wszA4
, {210000, 297000},{ 0, 0, 210000, 297000}},
171 { FORM_USER
, wszA4Small
, {210000, 297000},{ 0, 0, 210000, 297000}},
172 { FORM_USER
, wszA5
, {148000, 210000},{ 0, 0, 148000, 210000}},
173 { FORM_USER
, wszB4JIS
, {257000, 364000},{ 0, 0, 257000, 364000}},
174 { FORM_USER
, wszB5JIS
, {182000, 257000},{ 0, 0, 182000, 257000}},
175 { FORM_USER
, wszFolio
, {215900, 330200},{ 0, 0, 215900, 330200}},
176 { FORM_USER
, wszQuarto
, {215000, 275000},{ 0, 0, 215000, 275000}},
177 { FORM_USER
, wsz10x14
, {254000, 355600},{ 0, 0, 254000, 355600}},
178 { FORM_USER
, wsz11x17
, {279400, 431800},{ 0, 0, 279400, 431800}},
179 { FORM_USER
, wszNote
, {215900, 279400},{ 0, 0, 215900, 279400}},
180 { FORM_USER
, wszEnvelope9
, { 98425, 225425},{ 0, 0, 98425, 225425}},
181 { FORM_USER
, wszEnvelope10
, {104775, 241300},{ 0, 0, 104775, 241300}},
182 { FORM_USER
, wszEnvelope11
, {114300, 263525},{ 0, 0, 114300, 263525}},
183 { FORM_USER
, wszEnvelope12
, {120650, 279400},{ 0, 0, 120650, 279400}},
184 { FORM_USER
, wszEnvelope14
, {127000, 292100},{ 0, 0, 127000, 292100}},
185 { FORM_USER
, wszCsizesheet
, {431800, 558800},{ 0, 0, 431800, 558800}},
186 { FORM_USER
, wszDsizesheet
, {558800, 863600},{ 0, 0, 558800, 863600}},
187 { FORM_USER
, wszEsizesheet
, {863600,1117600},{ 0, 0, 863600,1117600}},
188 { FORM_USER
, wszEnvelopeDL
, {110000, 220000},{ 0, 0, 110000, 220000}},
189 { FORM_USER
, wszEnvelopeC5
, {162000, 229000},{ 0, 0, 162000, 229000}},
190 { FORM_USER
, wszEnvelopeC3
, {324000, 458000},{ 0, 0, 324000, 458000}},
191 { FORM_USER
, wszEnvelopeC4
, {229000, 324000},{ 0, 0, 229000, 324000}},
192 { FORM_USER
, wszEnvelopeC6
, {114000, 162000},{ 0, 0, 114000, 162000}},
193 { FORM_USER
, wszEnvelope65
, {114000, 229000},{ 0, 0, 114000, 229000}},
194 { FORM_USER
, wszEnvelopeB4
, {250000, 353000},{ 0, 0, 250000, 353000}},
195 { FORM_USER
, wszEnvelopeB5
, {176000, 250000},{ 0, 0, 176000, 250000}},
196 { FORM_USER
, wszEnvelopeB6
, {176000, 125000},{ 0, 0, 176000, 125000}},
197 { FORM_USER
, wszEnvelope
, {110000, 230000},{ 0, 0, 110000, 230000}},
198 { FORM_USER
, wszEnvelopeMonarch
, { 98425, 190500},{ 0, 0, 98425, 190500}},
199 { FORM_USER
, wsz634Envelope
, { 92075, 165100},{ 0, 0, 92075, 165100}},
200 { FORM_USER
, wszUSStdFanfold
, {377825, 279400},{ 0, 0, 377825, 279400}},
201 { FORM_USER
, wszGermanStdFanfold
, {215900, 304800},{ 0, 0, 215900, 304800}},
202 { FORM_USER
, wszGermanLegalFanfold
, {215900, 330200},{ 0, 0, 215900, 330200}},
203 // add more, I'm lazy
204 { FORM_USER
, wszDoubleJapanPostcardRotated
,{148000, 200000},{ 0, 0, 148000, 200000}},
206 { FORM_USER
, wszPRCEnvelope10Rotated
, {458000, 324009},{ 0, 0, 458000, 324009}},
207 { FORM_USER
, 0, { 0, 0},{ 0, 0, 0, 0}}
211 // Form information Registry entry stucture, in correct format.
213 // Example : 11 x 17 REG_BINARY 68 43 04 00 b8 96 06 00 00 00 00 00 00 00 00 00 68 43 04 00 b8 96 06 00 01 00 00 00 02 00 00 00
214 // [ Size | ImageableArea | Index 1 + | Flags ] , is FORM_PRINTER.
216 typedef struct _REGISTRYFORMINFO
222 } REGISTRYFORMINFO
, *PREGISTRYFORMINFO
;
224 HKEY hFormCKey
= NULL
;
225 HKEY hFormsKey
= NULL
;
228 InitializeFormList(VOID
)
231 PFORM_INFO_LIST pfil
;
232 REGISTRYFORMINFO rfi
;
234 FIXME("InitializeFormList\n");
236 dwErrorCode
= (DWORD
)RegCreateKeyExW( HKEY_LOCAL_MACHINE
,
237 L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Forms",
244 NULL
); // KEY_OPENED_EXISTING_KEY );
246 if ( dwErrorCode
!= ERROR_SUCCESS
&& dwErrorCode
!= ERROR_ALREADY_EXISTS
)
248 ERR("RegCreateKeyExW failed for the Forms with error %lu!\n", dwErrorCode
);
252 // Open some registry keys and leave them open. We need them multiple times throughout the Local Spooler.
253 dwErrorCode
= (DWORD
)RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Forms", 0, KEY_ALL_ACCESS
, &hFormsKey
);
254 if (dwErrorCode
!= ERROR_SUCCESS
)
256 ERR("RegOpenKeyExW failed for \"Forms\" with error %lu!\n", dwErrorCode
);
262 InitializeListHead(&FormList
);
266 while ( BuiltInForms
[ i
].pName
!= NULL
)
268 TRACE("InitializeFormList L s %S\n",BuiltInForms
[ i
].pName
);
270 Size
= sizeof(FORM_INFO_LIST
) + ((wcslen(BuiltInForms
[ i
].pName
) + 1) * sizeof(WCHAR
));
272 pfil
= DllAllocSplMem( Size
);
274 pfil
->pName
= wcscpy( (PWSTR
)(pfil
+1), BuiltInForms
[ i
].pName
);
275 pfil
->Flags
= BuiltInForms
[ i
].Flags
;
276 pfil
->Size
= BuiltInForms
[ i
].Size
;
277 pfil
->ImageableArea
= BuiltInForms
[ i
].ImageableArea
;
278 pfil
->Sig
= FORMINFOSIG
;
279 pfil
->Index
= _dwLastForm
++;
280 pfil
->pKeyword
= NULL
;
281 pfil
->StringType
= STRING_NONE
;
282 pfil
->pMuiDll
= NULL
;
283 pfil
->dwResourceId
= 0;
284 pfil
->pDisplayName
= NULL
;
287 InsertTailList( &FormList
, &pfil
->List
);
289 rfi
.Size
= pfil
->Size
;
290 rfi
.ImageableArea
= pfil
->ImageableArea
;
291 rfi
.Index
= pfil
->Index
;
292 rfi
.Flags
= pfil
->Flags
;
294 dwErrorCode
= RegSetValueExW( hFormsKey
, pfil
->pName
, 0, REG_BINARY
, (PBYTE
)&rfi
, sizeof( rfi
) );
295 if ( dwErrorCode
== ERROR_SUCCESS
)
297 TRACE("Init : RQVEW : %S added\n",pfil
->pName
);
310 FindForm( WCHAR
* pFormName
, WCHAR
* pKeyword
)
312 PLIST_ENTRY ListEntry
;
313 PFORM_INFO_LIST pfil
;
315 ListEntry
= FormList
.Flink
;
317 while (ListEntry
!= &FormList
)
319 pfil
= CONTAINING_RECORD(ListEntry
, FORM_INFO_LIST
, List
);
321 ListEntry
= ListEntry
->Flink
;
323 if ( pFormName
&& !_wcsicmp( pfil
->pName
, pFormName
) )
326 if ( pKeyword
&& !_wcsicmp( (WCHAR
*)pfil
->pKeyword
, pKeyword
) )
333 _LocalGetFormLevel1(PFORM_INFO_LIST pfil
, PFORM_INFO_1W
* ppFormInfo
, PBYTE
* ppFormInfoEnd
, PDWORD pcbNeeded
)
336 PCWSTR pwszStrings
[1];
338 pwszStrings
[0] = pfil
->pName
;
340 // Calculate the string lengths.
343 for (n
= 0; n
< _countof(pwszStrings
); ++n
)
345 *pcbNeeded
+= (wcslen(pwszStrings
[n
]) + 1) * sizeof(WCHAR
);
348 *pcbNeeded
+= sizeof(FORM_INFO_1W
);
352 (*ppFormInfo
)->Flags
= pfil
->Flags
;
353 (*ppFormInfo
)->Size
= pfil
->Size
;
354 (*ppFormInfo
)->ImageableArea
= pfil
->ImageableArea
;
356 // Finally copy the structure and advance to the next one in the output buffer.
357 *ppFormInfoEnd
= PackStrings(pwszStrings
, (PBYTE
)(*ppFormInfo
), dwFormInfo1Offsets
, *ppFormInfoEnd
);
362 _LocalGetFormLevel2(PFORM_INFO_LIST pfil
, PFORM_INFO_2W
* ppFormInfo
, PBYTE
* ppFormInfoEnd
, PDWORD pcbNeeded
)
365 PCWSTR pwszStrings
[4];
367 pwszStrings
[0] = pfil
->pName
;
368 pwszStrings
[1] = (PCWSTR
)pfil
->pKeyword
;
369 pwszStrings
[2] = pfil
->pMuiDll
;
370 pwszStrings
[3] = pfil
->pDisplayName
;
372 // Calculate the string lengths.
375 for (n
= 0; n
< _countof(pwszStrings
); ++n
)
379 *pcbNeeded
+= (wcslen(pwszStrings
[n
]) + 1) * sizeof(WCHAR
);
382 *pcbNeeded
+= sizeof(FORM_INFO_2W
);
386 (*ppFormInfo
)->Flags
= pfil
->Flags
;
387 (*ppFormInfo
)->Size
= pfil
->Size
;
388 (*ppFormInfo
)->ImageableArea
= pfil
->ImageableArea
;
389 (*ppFormInfo
)->StringType
= pfil
->StringType
; //// If caller is remote, set STRING_LANGPAIR always;
390 (*ppFormInfo
)->dwResourceId
= pfil
->dwResourceId
;
392 // Finally copy the structure and advance to the next one in the output buffer.
393 *ppFormInfoEnd
= PackStrings(pwszStrings
, (PBYTE
)(*ppFormInfo
), dwFormInfo2Offsets
, *ppFormInfoEnd
);
397 typedef void (*PLocalGetFormLevelFunc
)(PFORM_INFO_LIST
, PVOID
, PBYTE
*, PDWORD
);
399 static const PLocalGetFormLevelFunc pfnGetFormLevels
[] = {
401 (PLocalGetFormLevelFunc
)&_LocalGetFormLevel1
,
402 (PLocalGetFormLevelFunc
)&_LocalGetFormLevel2
409 LocalAddForm(HANDLE hPrinter
, DWORD Level
, PBYTE pForm
)
411 DWORD dwErrorCode
, Size
, cbNeeded
;
412 PFORM_INFO_LIST pfil
;
413 PLOCAL_HANDLE pHandle
;
414 REGISTRYFORMINFO rfi
;
415 PFORM_INFO_1W pfi1w
= (PFORM_INFO_1W
)pForm
;
416 PFORM_INFO_2W pfi2w
= (PFORM_INFO_2W
)pForm
;
418 FIXME("AddForm(%p, %lu, %p)\n", hPrinter
, Level
, pForm
);
420 // Check if this is a printer handle.
421 pHandle
= (PLOCAL_HANDLE
)hPrinter
;
422 if (pHandle
->HandleType
!= HandleType_Printer
)
424 dwErrorCode
= ERROR_INVALID_HANDLE
;
428 // Only support 1 & 2
429 if (Level
< 1 || Level
> 2)
431 // The caller supplied an invalid level.
432 dwErrorCode
= ERROR_INVALID_LEVEL
;
436 pfil
= FindForm( pfi1w
->pName
, NULL
);
439 dwErrorCode
= ERROR_FILE_EXISTS
;
443 dwErrorCode
= RegQueryValueExW( hFormsKey
, pfi1w
->pName
, NULL
, NULL
, NULL
, &cbNeeded
);
444 if ( dwErrorCode
== ERROR_SUCCESS
)
446 dwErrorCode
= ERROR_FILE_EXISTS
;
450 if ( wcslen(pfi1w
->pName
) > FORMMAXNAMESIZE
) // Limit REG Name size.
452 dwErrorCode
= ERROR_INVALID_PARAMETER
;
456 Size
= sizeof(FORM_INFO_LIST
) + ((MAX_PATH
+ 1) * sizeof(WCHAR
));
458 pfil
= DllAllocSplMem( Size
);
461 dwErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
465 pfil
->Sig
= FORMINFOSIG
;
466 pfil
->Index
= _dwLastForm
++;
467 pfil
->pName
= wcscpy( (PWSTR
)(pfil
+1), pfi1w
->pName
);
468 pfil
->Flags
= pfi1w
->Flags
;
469 pfil
->Size
= pfi1w
->Size
;
470 pfil
->ImageableArea
= pfi1w
->ImageableArea
;
471 pfil
->StringType
= STRING_NONE
;
475 pfil
->pKeyword
= pfi2w
->pKeyword
;
476 pfil
->pMuiDll
= pfi2w
->pMuiDll
;
477 pfil
->pDisplayName
= pfi2w
->pDisplayName
;
478 pfil
->StringType
= pfi2w
->StringType
;
479 pfil
->dwResourceId
= pfi2w
->dwResourceId
;
482 rfi
.Size
= pfil
->Size
;
483 rfi
.ImageableArea
= pfil
->ImageableArea
;
484 rfi
.Index
= pfil
->Index
;
485 rfi
.Flags
= pfil
->Flags
;
487 dwErrorCode
= RegSetValueExW( hFormsKey
, pfil
->pName
, 0, REG_BINARY
, (PBYTE
)&rfi
, sizeof( rfi
) );
489 BroadcastChange(pHandle
);
491 InsertTailList( &FormList
, &pfil
->List
);
494 SetLastError(dwErrorCode
);
495 return (dwErrorCode
== ERROR_SUCCESS
);
499 LocalDeleteForm(HANDLE hPrinter
, PWSTR pFormName
)
501 DWORD dwErrorCode
, cbNeeded
;
502 PFORM_INFO_LIST pfil
;
503 REGISTRYFORMINFO rfi
;
504 PLOCAL_HANDLE pHandle
;
506 FIXME("DeleteForm(%p, %S)\n", hPrinter
, pFormName
);
508 // Check if this is a printer handle.
509 pHandle
= (PLOCAL_HANDLE
)hPrinter
;
510 if (pHandle
->HandleType
!= HandleType_Printer
)
512 dwErrorCode
= ERROR_INVALID_HANDLE
;
516 pfil
= FindForm( pFormName
, NULL
);
519 dwErrorCode
= ERROR_INVALID_PARAMETER
;
523 dwErrorCode
= RegQueryValueExW( hFormsKey
, pFormName
, NULL
, NULL
, (PBYTE
)&rfi
, &cbNeeded
);
524 if ( dwErrorCode
!= ERROR_SUCCESS
)
529 dwErrorCode
= RegDeleteValueW(hFormsKey
, pFormName
);
530 if ( dwErrorCode
!= ERROR_SUCCESS
)
535 RemoveEntryList(&pfil
->List
);
539 BroadcastChange(pHandle
);
541 dwErrorCode
= ERROR_SUCCESS
;
544 SetLastError(dwErrorCode
);
545 return (dwErrorCode
== ERROR_SUCCESS
);
549 LocalEnumForms(HANDLE hPrinter
, DWORD Level
, PBYTE pForm
, DWORD cbBuf
, PDWORD pcbNeeded
, PDWORD pcReturned
)
552 PFORM_INFO_LIST pfil
= NULL
;
553 PBYTE pEnd
= &pForm
[cbBuf
];
554 PLOCAL_HANDLE pHandle
;
555 PLIST_ENTRY ListEntry
;
557 FIXME("EnumForms(%p, %lu, %p, %lu, %p, %p)\n", hPrinter
, Level
, pForm
, cbBuf
, pcbNeeded
, pcReturned
);
559 // Check if this is a printer handle.
560 pHandle
= (PLOCAL_HANDLE
)hPrinter
;
561 if (pHandle
->HandleType
!= HandleType_Printer
)
563 dwErrorCode
= ERROR_INVALID_HANDLE
;
567 // Only support 1 & 2
568 if (Level
< 1 || Level
> 2)
570 // The caller supplied an invalid level.
571 dwErrorCode
= ERROR_INVALID_LEVEL
;
575 // Count the required buffer size.
578 ListEntry
= FormList
.Flink
;
580 if (IsListEmpty(ListEntry
))
582 dwErrorCode
= ERROR_INVALID_PARAMETER
;
586 while ( ListEntry
!= &FormList
)
588 pfil
= CONTAINING_RECORD(ListEntry
, FORM_INFO_LIST
, List
);
589 ListEntry
= ListEntry
->Flink
;
591 pfnGetFormLevels
[Level
](pfil
, NULL
, NULL
, pcbNeeded
);
594 // Check if the supplied buffer is large enough.
595 if (cbBuf
< *pcbNeeded
)
597 ERR("Insuffisient Buffer size\n");
598 dwErrorCode
= ERROR_INSUFFICIENT_BUFFER
;
602 // Copy over the information.
603 pEnd
= &pForm
[*pcbNeeded
];
605 ListEntry
= FormList
.Flink
;
607 while ( ListEntry
!= &FormList
)
609 pfil
= CONTAINING_RECORD(ListEntry
, FORM_INFO_LIST
, List
);
610 ListEntry
= ListEntry
->Flink
;
612 pfnGetFormLevels
[Level
](pfil
, &pForm
, &pEnd
, NULL
);
616 dwErrorCode
= ERROR_SUCCESS
;
619 SetLastError(dwErrorCode
);
620 return (dwErrorCode
== ERROR_SUCCESS
);
624 LocalGetForm(HANDLE hPrinter
, PWSTR pFormName
, DWORD Level
, PBYTE pForm
, DWORD cbBuf
, PDWORD pcbNeeded
)
627 PFORM_INFO_LIST pfil
;
628 PBYTE pEnd
= &pForm
[cbBuf
];
629 PLOCAL_HANDLE pHandle
;
631 FIXME("GetForm(%p, %S, %lu, %p, %lu, %p)\n", hPrinter
, pFormName
, Level
, pForm
, cbBuf
, pcbNeeded
);
633 // Check if this is a printer handle.
634 pHandle
= (PLOCAL_HANDLE
)hPrinter
;
635 if (pHandle
->HandleType
!= HandleType_Printer
)
637 dwErrorCode
= ERROR_INVALID_HANDLE
;
641 // Only support 1 & 2
642 if (Level
< 1 || Level
> 2)
644 // The caller supplied an invalid level.
645 dwErrorCode
= ERROR_INVALID_LEVEL
;
649 pfil
= FindForm( pFormName
, NULL
);
652 dwErrorCode
= ERROR_INVALID_PARAMETER
;
656 // Count the required buffer size.
659 pfnGetFormLevels
[Level
](pfil
, NULL
, NULL
, pcbNeeded
);
661 // Check if the supplied buffer is large enough.
662 if (cbBuf
< *pcbNeeded
)
664 ERR("Insuffisient Buffer size\n");
665 dwErrorCode
= ERROR_INSUFFICIENT_BUFFER
;
669 // Copy over the information.
670 pEnd
= &pForm
[*pcbNeeded
];
672 pfnGetFormLevels
[Level
](pfil
, &pForm
, &pEnd
, NULL
);
674 dwErrorCode
= ERROR_SUCCESS
;
677 SetLastError(dwErrorCode
);
678 return (dwErrorCode
== ERROR_SUCCESS
);
682 LocalSetForm(HANDLE hPrinter
, PWSTR pFormName
, DWORD Level
, PBYTE pForm
)
684 DWORD dwErrorCode
, cbNeeded
;
685 PFORM_INFO_LIST pfil
;
686 REGISTRYFORMINFO rfi
;
687 PLOCAL_HANDLE pHandle
;
688 PFORM_INFO_1W pfi1w
= (PFORM_INFO_1W
)pForm
;
689 PFORM_INFO_2W pfi2w
= (PFORM_INFO_2W
)pForm
;
691 FIXME("SetFormW(%p, %S, %lu, %p)\n", hPrinter
, pFormName
, Level
, pForm
);
693 // Check if this is a printer handle.
694 pHandle
= (PLOCAL_HANDLE
)hPrinter
;
695 if (pHandle
->HandleType
!= HandleType_Printer
)
697 dwErrorCode
= ERROR_INVALID_HANDLE
;
701 // Only support 1 & 2
702 if (Level
< 1 || Level
> 2)
704 // The caller supplied an invalid level.
705 dwErrorCode
= ERROR_INVALID_LEVEL
;
709 pfil
= FindForm( pFormName
, NULL
);
712 dwErrorCode
= ERROR_INVALID_PARAMETER
;
716 dwErrorCode
= RegQueryValueExW( hFormsKey
, pFormName
, NULL
, NULL
, (PBYTE
)&rfi
, &cbNeeded
) ;
717 if ( dwErrorCode
!= ERROR_SUCCESS
)
722 pfil
->Flags
= pfi1w
->Flags
;
723 pfil
->Size
= pfi1w
->Size
;
724 pfil
->ImageableArea
= pfi1w
->ImageableArea
;
728 pfil
->pKeyword
= pfi2w
->pKeyword
;
729 pfil
->pMuiDll
= pfi2w
->pMuiDll
;
730 pfil
->pDisplayName
= pfi2w
->pDisplayName
;
731 pfil
->StringType
= pfi2w
->StringType
;
732 pfil
->dwResourceId
= pfi2w
->dwResourceId
;
735 rfi
.Size
= pfil
->Size
;
736 rfi
.ImageableArea
= pfil
->ImageableArea
;
737 rfi
.Flags
= pfil
->Flags
;
739 dwErrorCode
= RegSetValueExW( hFormsKey
, pfil
->pName
, 0, REG_BINARY
, (PBYTE
)&rfi
, sizeof( rfi
) );
741 BroadcastChange(pHandle
);
744 SetLastError(dwErrorCode
);
745 return (dwErrorCode
== ERROR_SUCCESS
);