Make sure the cmdline passed to CreateProcessA is writeable (thanks to
[wine/multimedia.git] / graphics / escape.c
blobb14cfc51f918d3244cc58616f1be2126485bbdb1
1 /*
2 * Escape() function.
4 * Copyright 1994 Bob Amstadt
5 */
7 #include <string.h>
8 #include "windef.h"
9 #include "wingdi.h"
10 #include "gdi.h"
11 #include "heap.h"
12 #include "ldt.h"
13 #include "dc.h"
14 #include "debugtools.h"
16 DEFAULT_DEBUG_CHANNEL(driver);
18 /***********************************************************************
19 * Escape16 [GDI.38]
21 INT16 WINAPI Escape16( HDC16 hdc, INT16 nEscape, INT16 cbInput,
22 SEGPTR lpszInData, SEGPTR lpvOutData )
24 DC * dc = DC_GetDCPtr( hdc );
25 if (!dc || !dc->funcs->pEscape) return 0;
26 if(nEscape == SETABORTPROC) SetAbortProc16(hdc, lpszInData);
27 return dc->funcs->pEscape( dc, nEscape, cbInput, lpszInData, lpvOutData );
30 /************************************************************************
31 * Escape [GDI32.200]
33 INT WINAPI Escape( HDC hdc, INT nEscape, INT cbInput,
34 LPCSTR lpszInData, LPVOID lpvOutData )
36 SEGPTR segin,segout;
37 INT ret;
38 DC * dc = DC_GetDCPtr( hdc );
39 if (!dc || !dc->funcs->pEscape) return 0;
41 segin = (SEGPTR)lpszInData;
42 segout = (SEGPTR)lpvOutData;
43 switch (nEscape) {
44 /* Escape(hdc,QUERYESCSUPPORT,LPINT,NULL) */
45 /* Escape(hdc,CLIP_TO_PATH,LPINT,NULL) */
46 case QUERYESCSUPPORT:
47 case CLIP_TO_PATH:
49 LPINT16 x = (LPINT16)SEGPTR_NEW(INT16);
50 *x = *(INT*)lpszInData;
51 segin = SEGPTR_GET(x);
52 cbInput = sizeof(INT16);
53 break;
56 /* Escape(hdc,GETSCALINGFACTOR,NULL,LPPOINT32) */
57 /* Escape(hdc,GETPHYSPAGESIZE,NULL,LPPOINT32) */
58 /* Escape(hdc,GETPRINTINGOFFSET,NULL,LPPOINT32) */
60 case GETSCALINGFACTOR:
61 case GETPHYSPAGESIZE:
62 case GETPRINTINGOFFSET:
63 segout = SEGPTR_GET(SEGPTR_NEW(POINT16));
64 cbInput = sizeof(POINT16);
65 break;
67 /* Escape(hdc,EXT_DEVICE_CAPS,LPINT,LPDWORD) */
68 case EXT_DEVICE_CAPS:
70 LPINT16 lpIndex = (LPINT16)SEGPTR_NEW(INT16);
71 LPDWORD lpCaps = (LPDWORD)SEGPTR_NEW(DWORD);
72 *lpIndex = *(INT*)lpszInData;
74 segin = SEGPTR_GET(lpIndex);
75 segout = SEGPTR_GET(lpCaps);
76 cbInput = sizeof(INT16);
77 break;
80 /* Escape(hdc,SETLINECAP,LPINT,LPINT) */
81 case SETLINECAP:
82 case SETLINEJOIN:
83 case SETMITERLIMIT:
85 LPINT16 new = (LPINT16)SEGPTR_NEW(INT16);
86 LPINT16 old = (LPINT16)SEGPTR_NEW(INT16);
87 *new = *(INT*)lpszInData;
88 segin = SEGPTR_GET(new);
89 segout = SEGPTR_GET(old);
90 cbInput = sizeof(INT16);
91 break;
93 /* Escape(hdc,GETTECHNOLOGY,NULL,LPSTR); */
94 case GETTECHNOLOGY: {
95 segout = SEGPTR_GET(SEGPTR_ALLOC(200)); /* enough I hope */
96 break;
100 /* Escape(hdc,ENABLEPAIRKERNING,LPINT16,LPINT16); */
102 case ENABLEPAIRKERNING: {
103 LPINT16 enab = SEGPTR_NEW(INT16);
104 segout = SEGPTR_GET(SEGPTR_NEW(INT16));
105 segin = SEGPTR_GET(enab);
106 *enab = *(INT*)lpszInData;
107 cbInput = sizeof(INT16);
108 break;
111 /* Escape(hdc,GETFACENAME,NULL,LPSTR); */
113 case GETFACENAME: {
114 segout = SEGPTR_GET(SEGPTR_ALLOC(200));
115 break;
118 /* Escape(hdc,STARTDOC,LPSTR,LPDOCINFOA);
119 * lpvOutData is actually a pointer to the DocInfo structure and used as
120 * a second input parameter
123 case STARTDOC: /* string may not be \0 terminated */
124 if(lpszInData) {
125 char *cp = SEGPTR_ALLOC(cbInput);
126 memcpy(cp, lpszInData, cbInput);
127 segin = SEGPTR_GET(cp);
128 } else
129 segin = 0;
131 if(lpvOutData) {
132 DOCINFO16 *lpsegdoc = SEGPTR_NEW(DOCINFO16);
133 DOCINFOA *lpdoc = lpvOutData;
134 memset(lpsegdoc, 0, sizeof(*lpsegdoc));
135 lpsegdoc->cbSize = sizeof(*lpsegdoc);
136 lpsegdoc->lpszDocName = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszDocName));
137 lpsegdoc->lpszOutput = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszOutput));
138 lpsegdoc->lpszDatatype = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszDatatype));
139 lpsegdoc->fwType = lpdoc->fwType;
140 segout = SEGPTR_GET(lpsegdoc);
142 break;
144 case SETABORTPROC:
145 SetAbortProc(hdc, (ABORTPROC)lpszInData);
146 break;
148 /* Escape(hdc,END_PATH,PATHINFO,NULL); */
149 case END_PATH:
151 BYTE *p = SEGPTR_ALLOC(cbInput);
152 memcpy(p, lpszInData, cbInput);
153 segin = SEGPTR_GET(p);
154 break;
157 default:
158 break;
162 ret = dc->funcs->pEscape( dc, nEscape, cbInput, segin, segout );
164 switch(nEscape) {
165 case QUERYESCSUPPORT:
166 if (ret)
167 TRACE("target DC implements Escape %d\n",nEscape);
168 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
169 break;
171 case SETLINECAP:
172 case SETLINEJOIN:
173 case SETMITERLIMIT:
174 *(LPINT)lpvOutData = *(LPINT16)PTR_SEG_TO_LIN(segout);
175 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
176 SEGPTR_FREE(PTR_SEG_TO_LIN(segout));
177 break;
178 case GETSCALINGFACTOR:
179 case GETPRINTINGOFFSET:
180 case GETPHYSPAGESIZE: {
181 LPPOINT16 x = (LPPOINT16)PTR_SEG_TO_LIN(segout);
182 CONV_POINT16TO32(x,(LPPOINT)lpvOutData);
183 SEGPTR_FREE(x);
184 break;
186 case EXT_DEVICE_CAPS:
187 *(LPDWORD)lpvOutData = *(LPDWORD)PTR_SEG_TO_LIN(segout);
188 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
189 SEGPTR_FREE(PTR_SEG_TO_LIN(segout));
190 break;
192 case GETTECHNOLOGY: {
193 LPSTR x=PTR_SEG_TO_LIN(segout);
194 lstrcpyA(lpvOutData,x);
195 SEGPTR_FREE(x);
196 break;
198 case ENABLEPAIRKERNING: {
199 LPINT16 enab = (LPINT16)PTR_SEG_TO_LIN(segout);
201 *(LPINT)lpvOutData = *enab;
202 SEGPTR_FREE(enab);
203 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
204 break;
206 case GETFACENAME: {
207 LPSTR x = (LPSTR)PTR_SEG_TO_LIN(segout);
208 lstrcpyA(lpvOutData,x);
209 SEGPTR_FREE(x);
210 break;
212 case STARTDOC: {
213 DOCINFO16 *doc = PTR_SEG_TO_LIN(segout);
214 SEGPTR_FREE(PTR_SEG_TO_LIN(doc->lpszDocName));
215 SEGPTR_FREE(PTR_SEG_TO_LIN(doc->lpszOutput));
216 SEGPTR_FREE(PTR_SEG_TO_LIN(doc->lpszDatatype));
217 SEGPTR_FREE(doc);
218 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
219 break;
222 case CLIP_TO_PATH:
223 case END_PATH:
224 SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
225 break;
227 default:
228 break;
230 return ret;
233 /******************************************************************************
234 * ExtEscape [GDI32.95]
236 * PARAMS
237 * hdc [I] Handle to device context
238 * nEscape [I] Escape function
239 * cbInput [I] Number of bytes in input structure
240 * lpszInData [I] Pointer to input structure
241 * cbOutput [I] Number of bytes in output structure
242 * lpszOutData [O] Pointer to output structure
244 * RETURNS
245 * Success: >0
246 * Not implemented: 0
247 * Failure: <0
249 INT WINAPI ExtEscape( HDC hdc, INT nEscape, INT cbInput,
250 LPCSTR lpszInData, INT cbOutput, LPSTR lpszOutData )
252 char *inBuf, *outBuf;
253 INT ret;
255 inBuf = SEGPTR_ALLOC(cbInput);
256 memcpy(inBuf, lpszInData, cbInput);
257 outBuf = cbOutput ? SEGPTR_ALLOC(cbOutput) : NULL;
258 ret = Escape16( hdc, nEscape, cbInput, SEGPTR_GET(inBuf),
259 SEGPTR_GET(outBuf) );
260 SEGPTR_FREE(inBuf);
261 if(outBuf) {
262 memcpy(lpszOutData, outBuf, cbOutput);
263 SEGPTR_FREE(outBuf);
265 return ret;
268 /*******************************************************************
269 * DrawEscape [GDI32.74]
273 INT WINAPI DrawEscape(HDC hdc, INT nEscape, INT cbInput, LPCSTR lpszInData)
275 FIXME("DrawEscape, stub\n");
276 return 0;