ReactOS  0.4.15-dev-3303-g1ade494
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 WideCharToMultiByte
Definition: compat.h:111
DWORD dmFields
Definition: wingdi.h:1622
WORD dmSize
Definition: wingdi.h:1568
#define CP_ACP
Definition: compat.h:109
WORD dmDriverExtra
Definition: wingdi.h:1621
WCHAR dmFormName[CCHFORMNAME]
Definition: wingdi.h:1645
char * LPSTR
Definition: xmlstorage.h:182
BYTE dmFormName[CCHFORMNAME]
Definition: wingdi.h:1593
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3167
WORD dmLogPixels
Definition: wingdi.h:1646
WORD dmSpecVersion
Definition: wingdi.h:1566
#define DM_FORMNAME
Definition: wingdi.h:1266
WORD dmSpecVersion
Definition: wingdi.h:1618
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WORD dmSize
Definition: wingdi.h:1620
unsigned short WORD
Definition: ntddk_ex.h:93
WCHAR dmDeviceName[CCHDEVICENAME]
Definition: wingdi.h:1617
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define CCHFORMNAME
Definition: wingdi.h:67
#define CCHDEVICENAME
Definition: ddrawi.h:63
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
WORD dmLogPixels
Definition: wingdi.h:1594
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
BYTE dmDeviceName[CCHDEVICENAME]
Definition: wingdi.h:1565
struct _devicemodeW DEVMODEW

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 }
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
unsigned char BYTE
Definition: xxhash.c:193
GLfloat GLfloat p
Definition: glext.h:8902
BYTE * PBYTE
Definition: pedump.c:66

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
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
__wchar_t WCHAR
Definition: xmlstorage.h:180
GLfloat GLfloat p
Definition: glext.h:8902

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 
180 Failure:
182  return FALSE;
183 }
static __inline void _FixStringA(PBYTE String, DWORD cbString)
Definition: devmode.c:95
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:84
WORD dmSize
Definition: wingdi.h:1568
#define TRUE
Definition: types.h:120
WORD dmDriverExtra
Definition: wingdi.h:1569
BYTE dmFormName[CCHFORMNAME]
Definition: wingdi.h:1593
#define FALSE
Definition: types.h:117
#define DM_FORMNAME
Definition: wingdi.h:1266
#define TRACE(s)
Definition: solgame.cpp:4
unsigned short WORD
Definition: ntddk_ex.h:93
#define SetLastError(x)
Definition: compat.h:611
DWORD dmFields
Definition: wingdi.h:1570
#define ERROR_INVALID_DATA
Definition: winerror.h:116
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
BYTE dmDeviceName[CCHDEVICENAME]
Definition: wingdi.h:1565
static MINIMUM_SIZE_TABLE MinimumSizeA[]
Definition: devmode.c:20
static const EHCI_PERIOD pTable[]
Definition: usbehci.c:29

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 
280 Failure:
282  return FALSE;
283 }
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:84
static MINIMUM_SIZE_TABLE MinimumSizeW[]
Definition: devmode.c:57
DWORD dmFields
Definition: wingdi.h:1622
#define TRUE
Definition: types.h:120
WORD dmDriverExtra
Definition: wingdi.h:1621
WCHAR dmFormName[CCHFORMNAME]
Definition: wingdi.h:1645
#define FALSE
Definition: types.h:117
#define DM_FORMNAME
Definition: wingdi.h:1266
#define TRACE(s)
Definition: solgame.cpp:4
WORD dmSize
Definition: wingdi.h:1620
unsigned short WORD
Definition: ntddk_ex.h:93
static __inline void _FixStringW(PWSTR String, DWORD cbString)
Definition: devmode.c:116
#define SetLastError(x)
Definition: compat.h:611
WCHAR dmDeviceName[CCHDEVICENAME]
Definition: wingdi.h:1617
#define ERROR_INVALID_DATA
Definition: winerror.h:116
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
static const EHCI_PERIOD pTable[]
Definition: usbehci.c:29

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 
232 Failure:
234  return FALSE;
235 }
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:84
static MINIMUM_SIZE_TABLE MinimumSizeW[]
Definition: devmode.c:57
DWORD dmFields
Definition: wingdi.h:1622
#define TRUE
Definition: types.h:120
WORD dmDriverExtra
Definition: wingdi.h:1621
WCHAR dmFormName[CCHFORMNAME]
Definition: wingdi.h:1645
#define FALSE
Definition: types.h:117
#define DM_FORMNAME
Definition: wingdi.h:1266
#define TRACE(s)
Definition: solgame.cpp:4
WORD dmSize
Definition: wingdi.h:1620
unsigned short WORD
Definition: ntddk_ex.h:93
static __inline void _FixStringW(PWSTR String, DWORD cbString)
Definition: devmode.c:116
#define SetLastError(x)
Definition: compat.h:611
WCHAR dmDeviceName[CCHDEVICENAME]
Definition: wingdi.h:1617
#define ERROR_INVALID_DATA
Definition: winerror.h:116
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
static const EHCI_PERIOD pTable[]
Definition: usbehci.c:29

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 }
WORD dmSize
Definition: wingdi.h:1568
WORD dmDriverExtra
Definition: wingdi.h:1569
static __inline DEVMODEA * _ConvertToDevmodeA(const DEVMODEW *dmW)
Definition: devmode.c:298
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define HeapFree(x, y, z)
Definition: compat.h:594
HANDLE hProcessHeap
Definition: kbswitch.c:25

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().