ReactOS 0.4.16-dev-340-g0540c21
drawdib.c
Go to the documentation of this file.
1/*
2 * Copyright 2000 Bradley Baetz
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 *
18 * FIXME: Some flags are ignored
19 *
20 * Handle palettes
21 */
22
23#include <stdarg.h>
24#include <stdio.h>
25#include <string.h>
26
27#include "windef.h"
28#include "winbase.h"
29#include "wingdi.h"
30#include "winuser.h"
31#include "vfw.h"
32
33#include "wine/debug.h"
34
36
37typedef struct tagWINE_HDD {
44 HPALETTE hpal; /* Palette to use for the DIB */
45 BOOL begun; /* DrawDibBegin has been called */
46 LPBITMAPINFOHEADER lpbiOut; /* Output format */
47 HIC hic; /* HIC for decompression */
48 HDC hMemDC; /* DC for buffering */
49 HBITMAP hOldDib; /* Original Dib */
50 HBITMAP hDib; /* DibSection */
51 LPVOID lpvbits; /* Buffer for holding decompressed dib */
55
57{
58 if(lpbi->biClrUsed)
59 return lpbi->biClrUsed;
60 if(lpbi->biBitCount<=8)
61 return 1<<lpbi->biBitCount;
62 return 0;
63}
64
65static WINE_HDD* HDD_FirstHdd /* = NULL */;
66
68{
69 WINE_HDD* hdd;
70
71 for (hdd = HDD_FirstHdd; hdd != NULL && hdd->hSelf != hd; hdd = hdd->next);
72 return hdd;
73}
74
76
77/***********************************************************************
78 * DrawDibOpen [MSVFW32.@]
79 */
81{
82 WINE_HDD* whdd;
83
84 TRACE("(void)\n");
85
87 TRACE("=> %p\n", whdd);
88
90 whdd->hSelf = (HDRAWDIB)HDD_HandleRef++;
91
92 whdd->next = HDD_FirstHdd;
93 HDD_FirstHdd = whdd;
94
95 return whdd->hSelf;
96}
97
98/***********************************************************************
99 * DrawDibClose [MSVFW32.@]
100 */
102{
103 WINE_HDD* whdd = MSVIDEO_GetHddPtr(hdd);
104 WINE_HDD** p;
105
106 TRACE("(%p)\n", hdd);
107
108 if (!whdd) return FALSE;
109
110 if (whdd->begun) DrawDibEnd(hdd);
111
112 for (p = &HDD_FirstHdd; *p != NULL; p = &((*p)->next))
113 {
114 if (*p == whdd)
115 {
116 *p = whdd->next;
117 break;
118 }
119 }
120
121 HeapFree(GetProcessHeap(), 0, whdd);
122
123 return TRUE;
124}
125
126/***********************************************************************
127 * DrawDibEnd [MSVFW32.@]
128 */
130{
131 BOOL ret = TRUE;
132 WINE_HDD *whdd = MSVIDEO_GetHddPtr(hdd);
133
134 TRACE("(%p)\n", hdd);
135
136 if (!whdd) return FALSE;
137
138 whdd->hpal = 0; /* Do not free this */
139 whdd->hdc = 0;
140 HeapFree(GetProcessHeap(), 0, whdd->lpbi);
141 whdd->lpbi = NULL;
142 HeapFree(GetProcessHeap(), 0, whdd->lpbiOut);
143 whdd->lpbiOut = NULL;
144
145 whdd->begun = FALSE;
146
147 /*if (whdd->lpvbits)
148 HeapFree(GetProcessHeap(), 0, whdd->lpvbuf);*/
149
150 if (whdd->hMemDC)
151 {
152 SelectObject(whdd->hMemDC, whdd->hOldDib);
153 DeleteDC(whdd->hMemDC);
154 whdd->hMemDC = 0;
155 }
156
157 if (whdd->hDib) DeleteObject(whdd->hDib);
158 whdd->hDib = 0;
159
160 if (whdd->hic)
161 {
162 ICDecompressEnd(whdd->hic);
163 ICClose(whdd->hic);
164 whdd->hic = 0;
165 }
166
167 whdd->lpvbits = NULL;
168
169 return ret;
170}
171
172/***********************************************************************
173 * DrawDibBegin [MSVFW32.@]
174 */
176 HDC hdc,
177 INT dxDst,
178 INT dyDst,
180 INT dxSrc,
181 INT dySrc,
182 UINT wFlags)
183{
184 BOOL ret = TRUE;
185 WINE_HDD *whdd;
186
187 TRACE("(%p,%p,%d,%d,%p,%d,%d,0x%08x)\n",
188 hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, wFlags);
189
190 TRACE("lpbi: %d,%d/%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
195
196 if (wFlags & ~(DDF_BUFFER))
197 FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));
198
199 whdd = MSVIDEO_GetHddPtr(hdd);
200 if (!whdd) return FALSE;
201
202 if (whdd->begun) DrawDibEnd(hdd);
203
204 if (lpbi->biCompression)
205 {
206 DWORD size = 0;
207
209 if (!whdd->hic)
210 {
211 WARN("Could not open IC. biCompression == 0x%08x\n", lpbi->biCompression);
212 ret = FALSE;
213 }
214
215 if (ret)
216 {
218 if (size == ICERR_UNSUPPORTED)
219 {
220 WARN("Codec doesn't support GetFormat, giving up.\n");
221 ret = FALSE;
222 }
223 }
224
225 if (ret)
226 {
227 whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, size);
228
229 if (ICDecompressGetFormat(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK)
230 ret = FALSE;
231 }
232
233 if (ret)
234 {
235 /* FIXME: Use Ex functions if available? */
236 if (ICDecompressBegin(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK)
237 ret = FALSE;
238
239 TRACE("biSizeImage == %d\n", whdd->lpbiOut->biSizeImage);
240 TRACE("biCompression == %d\n", whdd->lpbiOut->biCompression);
241 TRACE("biBitCount == %d\n", whdd->lpbiOut->biBitCount);
242 }
243 }
244 else
245 {
247 /* No compression */
248 TRACE("Not compressed!\n");
249 if (lpbi->biHeight <= 0)
250 {
251 /* we don't draw inverted DIBs */
252 TRACE("detected inverted DIB\n");
253 ret = FALSE;
254 }
255 else
256 {
258 whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, dwSize);
259 memcpy(whdd->lpbiOut, lpbi, dwSize);
260 }
261 }
262
263 if (ret)
264 {
265 /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(), 0, whdd->lpbiOut->biSizeImage);*/
266
268 TRACE("Creating: %d, %p\n", whdd->lpbiOut->biSize, whdd->lpvbits);
269 whdd->hDib = CreateDIBSection(whdd->hMemDC, (BITMAPINFO *)whdd->lpbiOut, DIB_RGB_COLORS, &(whdd->lpvbits), 0, 0);
270 if (whdd->hDib)
271 {
272 TRACE("Created: %p,%p\n", whdd->hDib, whdd->lpvbits);
273 }
274 else
275 {
276 ret = FALSE;
277 TRACE("Error: %d\n", GetLastError());
278 }
279 whdd->hOldDib = SelectObject(whdd->hMemDC, whdd->hDib);
280 }
281
282 if (ret)
283 {
284 whdd->hdc = hdc;
285 whdd->dxDst = dxDst;
286 whdd->dyDst = dyDst;
287 whdd->lpbi = HeapAlloc(GetProcessHeap(), 0, lpbi->biSize);
288 memcpy(whdd->lpbi, lpbi, lpbi->biSize);
289 whdd->dxSrc = dxSrc;
290 whdd->dySrc = dySrc;
291 whdd->begun = TRUE;
292 whdd->hpal = 0;
293 }
294 else
295 {
296 if (whdd->hic)
297 ICClose(whdd->hic);
298 HeapFree(GetProcessHeap(), 0, whdd->lpbiOut);
299 whdd->lpbiOut = NULL;
300 }
301
302 return ret;
303}
304
305/**********************************************************************
306 * DrawDibDraw [MSVFW32.@]
307 */
309 INT xDst, INT yDst, INT dxDst, INT dyDst,
311 LPVOID lpBits,
312 INT xSrc, INT ySrc, INT dxSrc, INT dySrc,
313 UINT wFlags)
314{
315 WINE_HDD *whdd;
316 BOOL ret;
317 int reopen = 0;
318
319 TRACE("(%p,%p,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08x)\n",
320 hdd, hdc, xDst, yDst, dxDst, dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, wFlags);
321
322 whdd = MSVIDEO_GetHddPtr(hdd);
323 if (!whdd) return FALSE;
324
325 TRACE("whdd=%p\n", whdd);
326
328 FIXME("wFlags == 0x%08x not handled\n", wFlags);
329
330 if (!lpBits)
331 {
332 /* Undocumented? */
333 lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(num_colours(lpbi)*sizeof(RGBQUAD));
334 }
335
336
337#define CHANGED(x) (whdd->x != x)
338
339 /* Check if anything changed from the parameters passed and our struct.
340 * If anything changed we need to run DrawDibBegin again to ensure we
341 * can support the changes.
342 */
343 if (!whdd->begun)
344 reopen = 1;
345 else if (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc))
346 reopen = 2;
347 else if (!(wFlags & DDF_SAME_DRAW))
348 {
349 if (CHANGED(lpbi) && memcmp(lpbi, whdd->lpbi, sizeof(*lpbi))) reopen = 3;
350 else if (CHANGED(dxSrc)) reopen = 4;
351 else if (CHANGED(dySrc)) reopen = 5;
352 else if (CHANGED(dxDst)) reopen = 6;
353 else if (CHANGED(dyDst)) reopen = 7;
354 }
355 if (reopen)
356 {
357 TRACE("Something changed (reason %d)!\n", reopen);
358 ret = DrawDibBegin(hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, 0);
359 if (!ret)
360 return ret;
361 }
362
363#undef CHANGED
364
365 /* If source dimensions are not specified derive them from bitmap header */
366 if (dxSrc == -1 && dySrc == -1)
367 {
368 dxSrc = lpbi->biWidth;
370 }
371 /* If destination dimensions are not specified derive them from source */
372 if (dxDst == -1 && dyDst == -1)
373 {
374 dxDst = dxSrc;
375 dyDst = dySrc;
376 }
377
378 if (!(wFlags & DDF_UPDATE))
379 {
380 if (lpbi->biCompression)
381 {
382 DWORD flags = 0;
383
384 TRACE("Compression == 0x%08x\n", lpbi->biCompression);
385
388
389 ICDecompress(whdd->hic, flags, lpbi, lpBits, whdd->lpbiOut, whdd->lpvbits);
390 }
391 else
392 {
393 /* BI_RGB: lpbi->biSizeImage isn't reliable */
394 DWORD biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight;
395 memcpy(whdd->lpvbits, lpBits, biSizeImage);
396 }
397 }
398 if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
399 {
401 SelectPalette(hdc, whdd->hpal, TRUE);
402 else
403 SelectPalette(hdc, whdd->hpal, FALSE);
404 }
405
406 ret = StretchBlt(whdd->hdc, xDst, yDst, dxDst, dyDst, whdd->hMemDC, xSrc, ySrc, dxSrc, dySrc, SRCCOPY);
407 TRACE("Painting %dx%d at %d,%d from %dx%d at %d,%d -> %d\n",
408 dxDst, dyDst, xDst, yDst, dxSrc, dySrc, xSrc, ySrc, ret);
409
410 return ret;
411}
412
413/*************************************************************************
414 * DrawDibStart [MSVFW32.@]
415 */
417 FIXME("(%p, %d), stub\n", hdd, rate);
418 return TRUE;
419}
420
421/*************************************************************************
422 * DrawDibStop [MSVFW32.@]
423 */
425 FIXME("(%p), stub\n", hdd);
426 return TRUE;
427}
428
429/***********************************************************************
430 * DrawDibChangePalette [MSVFW32.@]
431 */
433{
434 FIXME("(%p, 0x%08x, 0x%08x, %p), stub\n", hdd, iStart, iLen, lppe);
435 return TRUE;
436}
437
438/***********************************************************************
439 * DrawDibSetPalette [MSVFW32.@]
440 */
442{
443 WINE_HDD *whdd;
444
445 TRACE("(%p, %p)\n", hdd, hpal);
446
447 whdd = MSVIDEO_GetHddPtr(hdd);
448 if (!whdd) return FALSE;
449
450 whdd->hpal = hpal;
451
452 if (whdd->begun)
453 {
454 SelectPalette(whdd->hdc, hpal, 0);
455 RealizePalette(whdd->hdc);
456 }
457
458 return TRUE;
459}
460
461/***********************************************************************
462 * DrawDibGetBuffer [MSVFW32.@]
463 */
465{
466 FIXME("(%p, %p, 0x%08x, 0x%08x), stub\n", hdd, lpbi, dwSize, dwFlags);
467 return NULL;
468}
469
470/***********************************************************************
471 * DrawDibGetPalette [MSVFW32.@]
472 */
474{
475 WINE_HDD *whdd;
476
477 TRACE("(%p)\n", hdd);
478
479 whdd = MSVIDEO_GetHddPtr(hdd);
480 if (!whdd) return FALSE;
481
482 return whdd->hpal;
483}
484
485/***********************************************************************
486 * DrawDibRealize [MSVFW32.@]
487 */
489{
490 WINE_HDD *whdd;
491 UINT ret = 0;
492
493 FIXME("(%p, %p, %d), stub\n", hdd, hdc, fBackground);
494
495 whdd = MSVIDEO_GetHddPtr(hdd);
496 if (!whdd) return FALSE;
497
498 if (!whdd->begun)
499 {
500 ret = 0;
501 goto out;
502 }
503
504 if (!whdd->hpal)
506
507 SelectPalette(hdc, whdd->hpal, fBackground);
509
510 out:
511 TRACE("=> %u\n", ret);
512 return ret;
513}
514
515/***********************************************************************
516 * DrawDibTime [MSVFW32.@]
517 */
519{
520 FIXME("(%p, %p) stub\n", hdd, lpddtime);
521 return FALSE;
522}
523
524/***********************************************************************
525 * DrawDibProfileDisplay [MSVFW32.@]
526 */
528{
529 FIXME("(%p) stub\n", lpbi);
530
531 return PD_CAN_DRAW_DIB;
532}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal)
Definition: drawdib.c:441
static int num_colours(const BITMAPINFOHEADER *lpbi)
Definition: drawdib.c:56
BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc, INT xDst, INT yDst, INT dxDst, INT dyDst, LPBITMAPINFOHEADER lpbi, LPVOID lpBits, INT xSrc, INT ySrc, INT dxSrc, INT dySrc, UINT wFlags)
Definition: drawdib.c:308
BOOL VFWAPI DrawDibTime(HDRAWDIB hdd, LPDRAWDIBTIME lpddtime)
Definition: drawdib.c:518
BOOL VFWAPI DrawDibClose(HDRAWDIB hdd)
Definition: drawdib.c:101
static WINE_HDD * MSVIDEO_GetHddPtr(HDRAWDIB hd)
Definition: drawdib.c:67
LPVOID VFWAPI DrawDibGetBuffer(HDRAWDIB hdd, LPBITMAPINFOHEADER lpbi, DWORD dwSize, DWORD dwFlags)
Definition: drawdib.c:464
#define CHANGED(x)
DWORD VFWAPI DrawDibProfileDisplay(LPBITMAPINFOHEADER lpbi)
Definition: drawdib.c:527
struct tagWINE_HDD WINE_HDD
static WINE_HDD * HDD_FirstHdd
Definition: drawdib.c:65
BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd, HDC hdc, INT dxDst, INT dyDst, LPBITMAPINFOHEADER lpbi, INT dxSrc, INT dySrc, UINT wFlags)
Definition: drawdib.c:175
BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd)
Definition: drawdib.c:129
BOOL VFWAPI DrawDibChangePalette(HDRAWDIB hdd, int iStart, int iLen, LPPALETTEENTRY lppe)
Definition: drawdib.c:432
BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate)
Definition: drawdib.c:416
HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd)
Definition: drawdib.c:473
HDRAWDIB VFWAPI DrawDibOpen(void)
Definition: drawdib.c:80
UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground)
Definition: drawdib.c:488
BOOL VFWAPI DrawDibStop(HDRAWDIB hdd)
Definition: drawdib.c:424
static UINT_PTR HDD_HandleRef
Definition: drawdib.c:75
ULONG RGBQUAD
Definition: precomp.h:59
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
pKey DeleteObject()
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ICTYPE_VIDEO
Definition: mmreg.h:531
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)
Definition: msvideo_main.c:441
DWORD VFWAPIV ICDecompress(HIC hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiFormat, LPVOID lpData, LPBITMAPINFOHEADER lpbi, LPVOID lpBits)
Definition: msvideo_main.c:827
LRESULT WINAPI ICClose(HIC hic)
unsigned int UINT
Definition: ndis.h:50
int rate
Definition: pcmconverter.c:97
static FILE * out
Definition: regtests2xml.c:44
#define TRACE(s)
Definition: solgame.cpp:4
LONG biYPelsPerMeter
Definition: amvideo.idl:38
DWORD biCompression
Definition: amvideo.idl:35
DWORD biClrImportant
Definition: amvideo.idl:40
LONG biXPelsPerMeter
Definition: amvideo.idl:37
DWORD biSizeImage
Definition: amvideo.idl:36
LPBITMAPINFOHEADER lpbiOut
Definition: drawdib.c:46
HDC hMemDC
Definition: drawdib.c:48
HBITMAP hDib
Definition: drawdib.c:50
BOOL begun
Definition: drawdib.c:45
HBITMAP hOldDib
Definition: drawdib.c:49
HIC hic
Definition: drawdib.c:47
HDC hdc
Definition: drawdib.c:38
LPVOID lpvbits
Definition: drawdib.c:51
INT dyDst
Definition: drawdib.c:40
INT dySrc
Definition: drawdib.c:43
INT dxSrc
Definition: drawdib.c:42
struct tagWINE_HDD * next
Definition: drawdib.c:53
HPALETTE hpal
Definition: drawdib.c:44
HDRAWDIB hSelf
Definition: drawdib.c:52
INT dxDst
Definition: drawdib.c:39
LPBITMAPINFOHEADER lpbi
Definition: drawdib.c:41
int32_t INT
Definition: typedefs.h:58
#define DDF_SAME_HDC
Definition: vfw.h:2058
#define ICMODE_DECOMPRESS
Definition: vfw.h:269
#define ICERR_OK
Definition: vfw.h:50
HANDLE HDRAWDIB
Definition: vfw.h:33
#define VFWAPI
Definition: vfw.h:26
#define DDF_BUFFER
Definition: vfw.h:2062
#define DDF_BACKGROUNDPAL
Definition: vfw.h:2065
#define ICERR_UNSUPPORTED
Definition: vfw.h:56
#define DDF_SAME_DRAW
Definition: vfw.h:2059
#define ICDecompressBegin(hic, lpbiInput, lpbiOutput)
Definition: vfw.h:371
#define DDF_NOTKEYFRAME
Definition: vfw.h:2066
#define DDF_UPDATE
Definition: vfw.h:2057
#define ICDECOMPRESS_NOTKEYFRAME
Definition: vfw.h:331
#define ICDecompressGetFormat(hic, lpbiInput, lpbiOutput)
Definition: vfw.h:383
#define ICDecompressEnd(hic)
Definition: vfw.h:404
#define PD_CAN_DRAW_DIB
Definition: vfw.h:2104
#define DDF_DONTDRAW
Definition: vfw.h:2060
int ret
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:245
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define DIB_RGB_COLORS
Definition: wingdi.h:367
UINT WINAPI RealizePalette(_In_ HDC)
Definition: palette.c:138
HPALETTE WINAPI SelectPalette(_In_ HDC, _In_ HPALETTE, _In_ BOOL)
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
BOOL WINAPI StretchBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
#define SRCCOPY
Definition: wingdi.h:333
_In_ UINT iStart
Definition: wingdi.h:3620
BOOL WINAPI DeleteDC(_In_ HDC)
HPALETTE WINAPI CreateHalftonePalette(_In_opt_ HDC)
char * LPSTR
Definition: xmlstorage.h:182