ReactOS 0.4.15-dev-7918-g2a2556c
devmode.c File Reference
#include "precomp.h"
Include dependency graph for devmode.c:

Go to the source code of this file.

Classes

struct  _MINIMUM_SIZE_TABLE
 

Typedefs

typedef struct _MINIMUM_SIZE_TABLE MINIMUM_SIZE_TABLE
 
typedef struct _MINIMUM_SIZE_TABLEPMINIMUM_SIZE_TABLE
 

Functions

static __inline void _FixStringA (PBYTE String, DWORD cbString)
 
static __inline void _FixStringW (PWSTR String, DWORD cbString)
 
BOOL WINAPI IsValidDevmodeA (PDEVMODEA pDevmode, size_t DevmodeSize)
 
BOOL WINAPI IsValidDevmodeW (PDEVMODEW pDevmode, size_t DevmodeSize)
 
BOOL WINAPI IsValidDevmodeNoSizeW (PDEVMODEW pDevmode)
 
void RosConvertAnsiDevModeToUnicodeDevmode (PDEVMODEA pDevModeInput, PDEVMODEW *pDevModeOutput)
 
static __inline DEVMODEA_ConvertToDevmodeA (const DEVMODEW *dmW)
 
void RosConvertUnicodeDevModeToAnsiDevmode (PDEVMODEW pDevModeInput, PDEVMODEA pDevModeOutput)
 

Variables

static MINIMUM_SIZE_TABLE MinimumSizeA []
 
static MINIMUM_SIZE_TABLE MinimumSizeW []
 

Typedef Documentation

◆ MINIMUM_SIZE_TABLE

◆ PMINIMUM_SIZE_TABLE

Function Documentation

◆ _ConvertToDevmodeA()

static __inline DEVMODEA * _ConvertToDevmodeA ( const DEVMODEW dmW)
static

Definition at line 298 of file devmode.c.

299{
300 DEVMODEA *dmA;
301 WORD dmA_size, dmW_size;
302 size_t BytesToCopy;
303
304 dmW_size = dmW->dmSize;
305
306 /* this is the minimal dmSize that XP accepts */
307 if (dmW_size < FIELD_OFFSET(DEVMODEW, dmFields))
308 return NULL;
309
310 // Guard against callers that set dmSize incorrectly.
311 if (dmW_size > sizeof(DEVMODEW))
312 dmW_size = sizeof(DEVMODEW);
313
314 // dmA_size must become dmW_size without the additional 1 byte per character for each Unicode string (dmDeviceName and dmFormName).
315 dmA_size = dmW_size - CCHDEVICENAME;
316 if (dmW_size >= FIELD_OFFSET(DEVMODEW, dmFormName) + CCHFORMNAME * sizeof(WCHAR))
317 dmA_size -= CCHFORMNAME;
318
319 // Allocate the required bytes, that is dmSize for the ANSI DEVMODEA structure plus any extra bytes requested through dmDriverExtra.
320 dmA = HeapAlloc(GetProcessHeap(), 0, dmA_size + dmW->dmDriverExtra);
321 if (!dmA) return NULL;
322
323 // Every valid DEVMODEW has a dmDeviceName, which we convert to ANSI here.
325
326 // Copy everything up to dmFormName or the remaining dmW_size, whatever is smaller.
327 BytesToCopy = min(FIELD_OFFSET(DEVMODEW, dmFormName) - FIELD_OFFSET(DEVMODEW, dmSpecVersion), dmW_size - CCHDEVICENAME * sizeof(WCHAR));
329
330 // Handle dmFormName if the input DEVMODEW is large enough to contain one.
331 if (dmW_size >= FIELD_OFFSET(DEVMODEW, dmFormName) + CCHFORMNAME * sizeof(WCHAR))
332 {
333 if (dmW->dmFields & DM_FORMNAME)
335 else
336 dmA->dmFormName[0] = 0;
337
338 // Copy the remaining fields.
339 if (dmW_size > FIELD_OFFSET(DEVMODEW, dmLogPixels))
340 memcpy(&dmA->dmLogPixels, &dmW->dmLogPixels, dmW_size - FIELD_OFFSET(DEVMODEW, dmLogPixels));
341 }
342
343 // Append dmDriverExtra if required.
344 if (dmW->dmDriverExtra)
345 memcpy((char *)dmA + dmA_size, (const char *)dmW + dmW_size, dmW->dmDriverExtra);
346
347 // Set the corrected dmSize and we are done.
348 dmA->dmSize = dmA_size;
349
350 return dmA;
351}
#define CCHDEVICENAME
Definition: ddrawi.h:63
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
#define WideCharToMultiByte
Definition: compat.h:111
unsigned short WORD
Definition: ntddk_ex.h:93
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define min(a, b)
Definition: monoChain.cc:55
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
BYTE dmFormName[CCHFORMNAME]
Definition: wingdi.h:1593
WORD dmSpecVersion
Definition: wingdi.h:1566
WORD dmLogPixels
Definition: wingdi.h:1594
BYTE dmDeviceName[CCHDEVICENAME]
Definition: wingdi.h:1565
WORD dmSize
Definition: wingdi.h:1568
WCHAR dmDeviceName[CCHDEVICENAME]
Definition: wingdi.h:1617
DWORD dmFields
Definition: wingdi.h:1622
WORD dmDriverExtra
Definition: wingdi.h:1621
WORD dmSpecVersion
Definition: wingdi.h:1618
WCHAR dmFormName[CCHFORMNAME]
Definition: wingdi.h:1645
WORD dmLogPixels
Definition: wingdi.h:1646
WORD dmSize
Definition: wingdi.h:1620
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define CCHFORMNAME
Definition: wingdi.h:67
struct _devicemodeW DEVMODEW
#define DM_FORMNAME
Definition: wingdi.h:1266
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by RosConvertUnicodeDevModeToAnsiDevmode().

◆ _FixStringA()

static __inline void _FixStringA ( PBYTE  String,
DWORD  cbString 
)
static

Replace the last character by a null terminator if the given ANSI string is not null-terminated.

Definition at line 95 of file devmode.c.

96{
97 const PBYTE pLastCharacter = &String[cbString / sizeof(BYTE) - 1];
98 PBYTE p = String;
99
100 while (*p)
101 {
102 if (p == pLastCharacter)
103 {
104 *p = 0;
105 break;
106 }
107
108 p++;
109 }
110}
GLfloat GLfloat p
Definition: glext.h:8902
BYTE * PBYTE
Definition: pedump.c:66
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
unsigned char BYTE
Definition: xxhash.c:193

Referenced by IsValidDevmodeA().

◆ _FixStringW()

static __inline void _FixStringW ( PWSTR  String,
DWORD  cbString 
)
static

Replace the last character by a null terminator if the given Unicode string is not null-terminated.

Definition at line 116 of file devmode.c.

117{
118 const PWSTR pLastCharacter = &String[cbString / sizeof(WCHAR) - 1];
119 PWSTR p = String;
120
121 while (*p)
122 {
123 if (p == pLastCharacter)
124 {
125 *p = 0;
126 break;
127 }
128
129 p++;
130 }
131}
uint16_t * PWSTR
Definition: typedefs.h:56

Referenced by IsValidDevmodeNoSizeW(), and IsValidDevmodeW().

◆ IsValidDevmodeA()

BOOL WINAPI IsValidDevmodeA ( PDEVMODEA  pDevmode,
size_t  DevmodeSize 
)

Definition at line 134 of file devmode.c.

135{
137 WORD wRequiredSize;
138
139 TRACE("IsValidDevmodeA(%p, %lu)\n", pDevmode, DevmodeSize);
140
141 // Check if a Devmode was given at all.
142 if (!pDevmode)
143 goto Failure;
144
145 // Verify that DevmodeSize is large enough to hold the public and private members of the structure.
146 if (DevmodeSize < pDevmode->dmSize + pDevmode->dmDriverExtra)
147 goto Failure;
148
149 // If the structure has private members, the public structure must be 32-bit packed.
150 if (pDevmode->dmDriverExtra && pDevmode->dmSize % 4)
151 goto Failure;
152
153 // Now determine the minimum possible dmSize based on the given fields in dmFields.
154 wRequiredSize = FIELD_OFFSET(DEVMODEA, dmFields) + RTL_FIELD_SIZE(DEVMODEA, dmFields);
155
156 while (pTable->dwField)
157 {
158 if (pDevmode->dmFields & pTable->dwField)
159 {
160 wRequiredSize = pTable->wSize;
161 break;
162 }
163
164 pTable++;
165 }
166
167 // Verify that the value in dmSize is big enough for the used fields.
168 if (pDevmode->dmSize < wRequiredSize)
169 goto Failure;
170
171 // Check if dmDeviceName and (if used) dmFormName are null-terminated.
172 // Fix this if they aren't.
173 _FixStringA(pDevmode->dmDeviceName, sizeof(pDevmode->dmDeviceName));
174 if (pDevmode->dmFields & DM_FORMNAME)
175 _FixStringA(pDevmode->dmFormName, sizeof(pDevmode->dmFormName));
176
177 // Return success without setting the error code.
178 return TRUE;
179
180Failure:
182 return FALSE;
183}
static MINIMUM_SIZE_TABLE MinimumSizeA[]
Definition: devmode.c:20
static __inline void _FixStringA(PBYTE String, DWORD cbString)
Definition: devmode.c:95
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define SetLastError(x)
Definition: compat.h:752
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:86
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dmFields
Definition: wingdi.h:1570
WORD dmDriverExtra
Definition: wingdi.h:1569
static const EHCI_PERIOD pTable[]
Definition: usbehci.c:29
#define ERROR_INVALID_DATA
Definition: winerror.h:116

Referenced by START_TEST().

◆ IsValidDevmodeNoSizeW()

BOOL WINAPI IsValidDevmodeNoSizeW ( PDEVMODEW  pDevmode)

Definition at line 238 of file devmode.c.

239{
241 WORD wRequiredSize;
242
243 TRACE("IsValidDevmodeNoSizeW(%p)\n", pDevmode);
244
245 // Check if a Devmode was given at all.
246 if (!pDevmode)
247 goto Failure;
248
249 // If the structure has private members, the public structure must be 32-bit packed.
250 if (pDevmode->dmDriverExtra && pDevmode->dmSize % 4)
251 goto Failure;
252
253 // Now determine the minimum possible dmSize based on the given fields in dmFields.
254 wRequiredSize = FIELD_OFFSET(DEVMODEW, dmFields) + RTL_FIELD_SIZE(DEVMODEW, dmFields);
255
256 while (pTable->dwField)
257 {
258 if (pDevmode->dmFields & pTable->dwField)
259 {
260 wRequiredSize = pTable->wSize;
261 break;
262 }
263
264 pTable++;
265 }
266
267 // Verify that the value in dmSize is big enough for the used fields.
268 if (pDevmode->dmSize < wRequiredSize)
269 goto Failure;
270
271 // Check if dmDeviceName and (if used) dmFormName are null-terminated.
272 // Fix this if they aren't.
273 _FixStringW(pDevmode->dmDeviceName, sizeof(pDevmode->dmDeviceName));
274 if (pDevmode->dmFields & DM_FORMNAME)
275 _FixStringW(pDevmode->dmFormName, sizeof(pDevmode->dmFormName));
276
277 // Return success without setting the error code.
278 return TRUE;
279
280Failure:
282 return FALSE;
283}
static __inline void _FixStringW(PWSTR String, DWORD cbString)
Definition: devmode.c:116
static MINIMUM_SIZE_TABLE MinimumSizeW[]
Definition: devmode.c:57

Referenced by AddPrinterW(), DeviceCapabilitiesW(), DocumentPropertiesW(), QueryColorProfile(), and SetPrinterW().

◆ IsValidDevmodeW()

BOOL WINAPI IsValidDevmodeW ( PDEVMODEW  pDevmode,
size_t  DevmodeSize 
)

Definition at line 186 of file devmode.c.

187{
189 WORD wRequiredSize;
190
191 TRACE("IsValidDevmodeW(%p, %lu)\n", pDevmode, DevmodeSize);
192
193 // Check if a Devmode was given at all.
194 if (!pDevmode)
195 goto Failure;
196
197 // Verify that DevmodeSize is large enough to hold the public and private members of the structure.
198 if (DevmodeSize < pDevmode->dmSize + pDevmode->dmDriverExtra)
199 goto Failure;
200
201 // If the structure has private members, the public structure must be 32-bit packed.
202 if (pDevmode->dmDriverExtra && pDevmode->dmSize % 4)
203 goto Failure;
204
205 // Now determine the minimum possible dmSize based on the given fields in dmFields.
206 wRequiredSize = FIELD_OFFSET(DEVMODEW, dmFields) + RTL_FIELD_SIZE(DEVMODEW, dmFields);
207
208 while (pTable->dwField)
209 {
210 if (pDevmode->dmFields & pTable->dwField)
211 {
212 wRequiredSize = pTable->wSize;
213 break;
214 }
215
216 pTable++;
217 }
218
219 // Verify that the value in dmSize is big enough for the used fields.
220 if (pDevmode->dmSize < wRequiredSize)
221 goto Failure;
222
223 // Check if dmDeviceName and (if used) dmFormName are null-terminated.
224 // Fix this if they aren't.
225 _FixStringW(pDevmode->dmDeviceName, sizeof(pDevmode->dmDeviceName));
226 if (pDevmode->dmFields & DM_FORMNAME)
227 _FixStringW(pDevmode->dmFormName, sizeof(pDevmode->dmFormName));
228
229 // Return success without setting the error code.
230 return TRUE;
231
232Failure:
234 return FALSE;
235}

Referenced by START_TEST(), and test_IsValidDevmodeW().

◆ RosConvertAnsiDevModeToUnicodeDevmode()

void RosConvertAnsiDevModeToUnicodeDevmode ( PDEVMODEA  pDevModeInput,
PDEVMODEW pDevModeOutput 
)

Definition at line 285 of file devmode.c.

286{
287 // FIXME: This function should become ConvertAnsiDevModeToUnicodeDevmode when its parameters are known!
288
289 // Check if a pDevModeInput and pDevModeOutput are both not NULL.
290 if (!pDevModeInput || !pDevModeOutput)
291 return;
292
293 *pDevModeOutput = GdiConvertToDevmodeW(pDevModeInput);
294}
DEVMODEW *WINAPI GdiConvertToDevmodeW(const DEVMODEA *)
Definition: misc.c:969

Referenced by AddPrinterA(), DeviceCapabilitiesA(), DocumentPropertiesA(), ResetPrinterA(), and SetPrinterA().

◆ RosConvertUnicodeDevModeToAnsiDevmode()

void RosConvertUnicodeDevModeToAnsiDevmode ( PDEVMODEW  pDevModeInput,
PDEVMODEA  pDevModeOutput 
)

Definition at line 353 of file devmode.c.

354{
355 PDEVMODEA pTmp;
356
357 // FIXME: This function should become ConvertUnicodeDevModeToAnsiDevmode when its parameters are known!
358
359 // Check if a pDevModeInput and pDevModeOutput are both not NULL.
360 if (!pDevModeInput || !pDevModeOutput)
361 return;
362
363 pTmp = _ConvertToDevmodeA(pDevModeInput);
364 memcpy( pDevModeOutput, pTmp, pTmp->dmSize + pTmp->dmDriverExtra); // Copy into a Wide char (Larger) buffer.
365 HeapFree(hProcessHeap, 0, pTmp);
366}
static __inline DEVMODEA * _ConvertToDevmodeA(const DEVMODEW *dmW)
Definition: devmode.c:298
#define HeapFree(x, y, z)
Definition: compat.h:735
HANDLE hProcessHeap
Definition: kbswitch.c:37

Referenced by DocumentPropertiesA(), EnumJobsA(), EnumPrintersA(), GetJobA(), and GetPrinterA().

Variable Documentation

◆ MinimumSizeA

MINIMUM_SIZE_TABLE MinimumSizeA[]
static

Minimum required DEVMODEA structure size based on the used fields. Must be in descending order!

Definition at line 20 of file devmode.c.

Referenced by IsValidDevmodeA().

◆ MinimumSizeW

MINIMUM_SIZE_TABLE MinimumSizeW[]
static

Minimum required DEVMODEW structure size based on the used fields. Must be in descending order!

Definition at line 57 of file devmode.c.

Referenced by IsValidDevmodeNoSizeW(), and IsValidDevmodeW().