ReactOS 0.4.16-dev-2274-gc61d98f
cursoricon.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS user32.dll
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: cursor and icons implementation
5 * COPYRIGHT: Copyright Jérôme Gardou <jerome.gardou@reactos.org>
6 * Copyright 2022-2025 Doug Lyons <douglyons@douglyons.com>
7 * Copyright 2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
8 */
9
10#include <user32.h>
11#include "png.h"
12
15//WINE_DECLARE_DEBUG_CHANNEL(resource);
16
17#include <pshpack1.h>
19{
24 union
25 {
26 WORD wPlanes; /* For icons */
27 WORD xHotspot; /* For cursors */
28 };
29 union
30 {
31 WORD wBitCount; /* For icons */
32 WORD yHotspot; /* For cursors */
33 };
37
38typedef struct _CURSORICONFILEDIR
39{
45#include <poppack.h>
46
47#define PNG_CHECK_SIG_SIZE 8 /* Check signature size */
48
49/* libpng helpers */
50typedef struct _PNG_READER_STATE
51{
53 size_t bufSize;
54 size_t currentPos;
56
57/* This function is used for reading png data from memory */
58static VOID
62 _In_ size_t length)
63{
65 if ((state->currentPos + length) > state->bufSize)
66 {
67 ERR("png read error\n");
68 png_error(png_ptr, "read error in ReadMemoryPng");
69 return;
70 }
71 RtlCopyMemory(data, state->buffer + state->currentPos, length);
72 state->currentPos += length;
73}
74
75/* libpng.dll is delay-loaded. If no libpng.dll exists, we have to avoid exception */
76static BOOL
78{
79 static BOOL bLibPngFound = -1;
80 if (bLibPngFound == -1)
81 {
83 bLibPngFound = !!hLibPng;
84 FreeLibrary(hLibPng);
85 }
86 return bLibPngFound;
87}
88
89static int get_dib_image_size(int width, int height, int depth);
90
91/* Convert PNG raw data to BMP icon data */
92static PBYTE
94 _In_ PBYTE pngBits,
95 _In_ DWORD fileSize,
96 _Out_ PDWORD pBmpIconSize)
97{
98 TRACE("pngBits %p fileSize %d\n", pngBits, fileSize);
99
100 if (!LibPngExists())
101 {
102 ERR("No libpng.dll\n");
103 return NULL;
104 }
105
106 if (!pngBits || fileSize < PNG_CHECK_SIG_SIZE || !png_check_sig(pngBits, PNG_CHECK_SIG_SIZE))
107 return NULL;
108
109 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
110 if (!png_ptr)
111 {
112 ERR("png_create_read_struct error\n");
113 return NULL;
114 }
115
116 png_infop info_ptr = png_create_info_struct(png_ptr);
117 if (!info_ptr)
118 {
119 ERR("png_create_info_struct error\n");
120 png_destroy_read_struct(&png_ptr, NULL, NULL);
121 return NULL;
122 }
123
124 /* Set our own read_function */
125 PNG_READER_STATE readerState = { pngBits, fileSize, PNG_CHECK_SIG_SIZE };
126 png_set_read_fn(png_ptr, &readerState, ReadMemoryPng);
127 png_set_sig_bytes(png_ptr, PNG_CHECK_SIG_SIZE);
128
129 /* Read png info */
130 png_read_info(png_ptr, info_ptr);
131
132 /* Add translation of some PNG formats and update info */
133 int colorType = png_get_color_type(png_ptr, info_ptr);
134 if (colorType == PNG_COLOR_TYPE_PALETTE)
135 png_set_palette_to_rgb(png_ptr);
136 else if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
137 png_set_gray_to_rgb(png_ptr);
138 png_set_scale_16(png_ptr); /* Convert 16-bit channels to 8-bit */
139 png_read_update_info(png_ptr, info_ptr);
140
141 /* Get updated png info */
143 int bitDepth;
144 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitDepth, &colorType, NULL, NULL, NULL);
145 TRACE("width %d, height %d, bitDepth %d, colorType %d\n",
146 width, height, bitDepth, colorType);
147
148 int channels = png_get_channels(png_ptr, info_ptr);
149 int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
150 int imageSize = height * rowbytes;
151 TRACE("rowbytes %d, channels %d, imageSize %d\n", rowbytes, channels, imageSize);
152
153 /* Allocate rows data */
154 png_bytepp rows = png_malloc(png_ptr, sizeof(png_bytep) * height);
155 if (!rows)
156 {
157 ERR("png_malloc failed\n");
158 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
159 return NULL;
160 }
161
162 for (int i = 0; i < (int)height; i++)
163 {
164 rows[i] = png_malloc(png_ptr, rowbytes);
165 if (!rows[i])
166 {
167 ERR("png_malloc failed\n");
168
169 /* Clean up */
170 while (--i >= 0)
171 png_free(png_ptr, rows[i]);
172 png_free(png_ptr, rows);
173 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
174
175 return NULL;
176 }
177 }
178
179 /* Read png image data */
180 png_set_rows(png_ptr, info_ptr, rows);
181 png_read_image(png_ptr, rows);
182 png_read_end(png_ptr, info_ptr);
183
184 /* After reading the image, you can deal with row pointers */
185 PBYTE imageBytes = HeapAlloc(GetProcessHeap(), 0, imageSize);
186 if (imageBytes)
187 {
188 PBYTE pb = imageBytes;
189 for (int i = height - 1; i >= 0; i--)
190 {
191 png_bytep row = rows[i];
192 for (int j = 0; j < channels * width; j += channels)
193 {
194 *pb++ = row[j + 2]; /* Red */
195 *pb++ = row[j + 1]; /* Green */
196 *pb++ = row[j + 0]; /* Blue */
197 if (channels == 4)
198 *pb++ = row[j + 3]; /* Alpha */
199 }
200 pb += (channels * width) % 4;
201 }
202 }
203
204 /* Clean up */
205 for (int i = 0; i < (int)height; i++)
206 png_free(png_ptr, rows[i]);
207 png_free(png_ptr, rows);
208 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
209
210 if (!imageBytes)
211 {
212 ERR("HeapAlloc failed\n");
213 return NULL;
214 }
215
216 /* BPP (Bits Per Pixel) */
217 WORD bpp = (WORD)(bitDepth * channels);
218
219 /* The byte size of mask bits */
220 DWORD maskSize = get_dib_image_size(width, height, 1);
221
222 /* Build BITMAPINFOHEADER */
223 BITMAPINFOHEADER info = { sizeof(info) };
224 info.biWidth = width;
225 info.biHeight = 2 * height;
226 info.biPlanes = 1;
227 info.biBitCount = bpp;
228 info.biCompression = BI_RGB;
229
230 /* Build CURSORICONFILEDIR */
231 CURSORICONFILEDIR cifd = { 0, 1, 1 };
232 cifd.idEntries[0].bWidth = (BYTE)width;
233 cifd.idEntries[0].bHeight = (BYTE)height;
234 cifd.idEntries[0].bColorCount = 0; /* No color palette */
235 cifd.idEntries[0].wPlanes = 1; /* Must be 1 */
236 cifd.idEntries[0].wBitCount = bpp;
237 cifd.idEntries[0].dwDIBSize = (DWORD)(sizeof(info) + imageSize + maskSize);
238 cifd.idEntries[0].dwDIBOffset = (DWORD)sizeof(cifd);
239
240 /* Allocate BMP icon data */
241 *pBmpIconSize = (DWORD)(sizeof(cifd) + sizeof(info) + imageSize + maskSize);
242 PBYTE pbBmpIcon = HeapAlloc(GetProcessHeap(), 0, *pBmpIconSize);
243 if (!pbBmpIcon)
244 {
245 ERR("HeapAlloc failed\n");
246 HeapFree(GetProcessHeap(), 0, imageBytes);
247 return NULL;
248 }
249
250 /* Store data to pbBmpIcon */
251 PBYTE pb = pbBmpIcon;
252 RtlCopyMemory(pb, &cifd, sizeof(cifd));
253 pb += sizeof(cifd);
254 RtlCopyMemory(pb, &info, sizeof(info));
255 pb += sizeof(info);
256 RtlCopyMemory(pb, imageBytes, imageSize);
257 pb += imageSize;
258 RtlFillMemory(pb, maskSize, 0xFF); /* Mask bits for AND operation */
259
260 HeapFree(GetProcessHeap(), 0, imageBytes);
261 return pbBmpIcon;
262}
263
264/* We only use Wide string functions */
265#undef MAKEINTRESOURCE
266#define MAKEINTRESOURCE MAKEINTRESOURCEW
267
268/************* USER32 INTERNAL FUNCTIONS **********/
269
271{
272 if (!gpsi->hIconSmWindows)
273 {
274 ERR("Loading System Cursors\n");
291 }
292}
293
294/* This callback routine is called directly after switching to gui mode */
296WINAPI
298 ULONG ArgumentLength)
299{
300 BOOL *DefaultCursor = (BOOL*)Arguments;
301 HCURSOR hCursor;
302
303 /* Load system cursors first */
305
306 if(*DefaultCursor)
307 {
308 /* set default cursor */
309 hCursor = LoadCursorW(0, IDC_ARROW);
310 SetCursor(hCursor);
311 }
312 else
313 {
314 /* FIXME load system cursor scheme */
315 SetCursor(0);
316 hCursor = LoadCursorW(0, IDC_ARROW);
317 SetCursor(hCursor);
318 }
319
320 return(ZwCallbackReturn(&hCursor, sizeof(HCURSOR), STATUS_SUCCESS));
321}
322
324{
325 return NtUserGetIconSize(hIcon, 0, &size->cx, &size->cy);
326}
327
329{
331 return NULL;
332}
333
334/************* IMPLEMENTATION HELPERS ******************/
335
336static const WCHAR DISPLAYW[] = L"DISPLAY";
337
338static void *map_fileW( LPCWSTR name, LPDWORD filesize )
339{
340 HANDLE hFile, hMapping;
341 LPVOID ptr = NULL;
342
346 {
347 hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
348 if (hMapping)
349 {
350 ptr = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
351 CloseHandle( hMapping );
352 if (filesize)
353 *filesize = GetFileSize( hFile, NULL );
354 }
356 }
357 return ptr;
358}
359
360static int get_dib_image_size( int width, int height, int depth )
361{
362 return (((width * depth + 31) / 8) & ~3) * abs( height );
363}
364
366{
367 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
368 {
369 const RGBTRIPLE *rgb = ((const BITMAPCOREINFO*)info)->bmciColors;
370
371 if (((const BITMAPCOREINFO*)info)->bmciHeader.bcBitCount != 1) return FALSE;
372
373 /* Check if the first color is black */
374 if (RGB(rgb[0].rgbtRed, rgb[0].rgbtGreen, rgb[0].rgbtBlue) ==
375 RGB(0, 0, 0))
376 {
377 /* Check if the second color is white */
378 return RGB(rgb[1].rgbtRed, rgb[1].rgbtGreen, rgb[1].rgbtBlue) ==
379 RGB(0xff, 0xff, 0xff);
380 }
381
382 /* Check if the first color is white */
383 if (RGB(rgb[0].rgbtRed, rgb[0].rgbtGreen, rgb[0].rgbtBlue) ==
384 RGB(0xff, 0xff, 0xff))
385 {
386 /* Check if the second color is black */
387 return (RGB(rgb[1].rgbtRed, rgb[1].rgbtGreen, rgb[1].rgbtBlue) ==
388 RGB(0, 0, 0));
389 }
390
391 return FALSE;
392 }
393 else /* assume BITMAPINFOHEADER */
394 {
395 const RGBQUAD *rgb = info->bmiColors;
396
397 if (info->bmiHeader.biBitCount != 1) return FALSE;
398
399 /* Check if the first color is black */
400 if (RGBA(rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue,
401 rgb[0].rgbReserved) == RGBA(0, 0, 0, 0))
402 {
403 /* Check if the second color is white */
404 return RGBA(rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue,
405 rgb[1].rgbReserved) == RGBA(0xff, 0xff, 0xff, 0);
406 }
407
408 /* Check if the first color is white */
409 if (RGBA(rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue,
410 rgb[0].rgbReserved) == RGBA(0xff, 0xff, 0xff, 0))
411 {
412 /* Check if the second color is black */
413 return (RGBA(rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue,
414 rgb[1].rgbReserved) == RGBA(0, 0, 0, 0));
415 }
416
417 return FALSE;
418 }
419}
420
421/* Return the size of the bitmap info structure including color table and
422 * the bytes required for 3 DWORDS if this is a BI_BITFIELDS bmp. */
423static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
424{
425 unsigned int colors, size, masks = 0;
426
427 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
428 {
429 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
430 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
431 return sizeof(BITMAPCOREHEADER) + colors *
432 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
433 }
434 else /* assume BITMAPINFOHEADER */
435 {
436 colors = info->bmiHeader.biClrUsed;
437 if (colors > 256) /* buffer overflow otherwise */
438 colors = 256;
439 if (!colors && (info->bmiHeader.biBitCount <= 8))
440 colors = 1 << info->bmiHeader.biBitCount;
441 /* Account for BI_BITFIELDS in BITMAPINFOHEADER(v1-v3) bmp's. The
442 * 'max' selection using biSize below will exclude v4 & v5's. */
443 if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
444 size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
445 /* Test for BI_BITFIELDS format and either 16 or 32 bpp.
446 * If so, account for the 3 DWORD masks (RGB Order).
447 * BITMAPCOREHEADER tested above has no 16 or 32 bpp types.
448 * See table "All of the possible pixel formats in a DIB"
449 * at https://en.wikipedia.org/wiki/BMP_file_format. */
450 if (info->bmiHeader.biSize >= sizeof(BITMAPV4HEADER) &&
451 info->bmiHeader.biCompression == BI_BITFIELDS &&
452 (info->bmiHeader.biBitCount == 16 || info->bmiHeader.biBitCount == 32))
453 {
454 size += 3 * sizeof(DWORD); // BI_BITFIELDS
455 }
456 return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
457 }
458}
459
462{
463 #define CR 13
464 #define LF 10
465 #define EOFM 26 // DOS End Of File Marker
466 #define HighBitDetect 0x89 // Byte with high bit set to test if not 7-bit
467 /* wine's definition */
468 static const BYTE png_sig_pattern[] = { HighBitDetect, 'P', 'N', 'G', CR, LF, EOFM, LF };
469 if (header->biSize == sizeof(BITMAPCOREHEADER))
470 {
471 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
472 *width = core->bcWidth;
473 *height = core->bcHeight;
474 *bpp = core->bcBitCount;
475 *compr = 0;
476 return 0;
477 }
478 else if (header->biSize == sizeof(BITMAPINFOHEADER) ||
479 header->biSize == sizeof(BITMAPV4HEADER) ||
480 header->biSize == sizeof(BITMAPV5HEADER))
481 {
482 *width = header->biWidth;
483 *height = header->biHeight;
484 *bpp = header->biBitCount;
485 *compr = header->biCompression;
486 return 1;
487 }
488 if (memcmp(&header->biSize, png_sig_pattern, sizeof(png_sig_pattern)) == 0)
489 {
490 TRACE("We have a PNG icon\n");
491 /* for PNG format details see https://en.wikipedia.org/wiki/PNG */
492 }
493 else
494 {
495 ERR("Unknown/wrong size for header of 0x%x\n", header->biSize );
496 }
497 return -1;
498}
499
500/* copy an icon bitmap, even when it can't be selected into a DC */
501/* helper for CreateIconIndirect */
502static void stretch_blt_icon(HDC hdc_dst, int dst_width, int dst_height, HBITMAP src)
503{
505 BITMAP bm;
506 HBITMAP hbmpPrev;
507
508 GetObjectW(src, sizeof(bm), &bm);
509
510 hbmpPrev = SelectObject(hdc, src);
511
512 if (!hbmpPrev) /* do it the hard way */
513 {
515 void *bits;
516
517 if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) return;
518 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
519 info->bmiHeader.biWidth = bm.bmWidth;
520 info->bmiHeader.biHeight = bm.bmHeight;
521 info->bmiHeader.biPlanes = GetDeviceCaps( hdc_dst, PLANES );
522 info->bmiHeader.biBitCount = GetDeviceCaps( hdc_dst, BITSPIXEL );
523 info->bmiHeader.biCompression = BI_RGB;
524 info->bmiHeader.biSizeImage = get_dib_image_size( bm.bmWidth, bm.bmHeight, info->bmiHeader.biBitCount );
525 info->bmiHeader.biXPelsPerMeter = 0;
526 info->bmiHeader.biYPelsPerMeter = 0;
527 info->bmiHeader.biClrUsed = 0;
528 info->bmiHeader.biClrImportant = 0;
529 bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage );
530 if (bits && GetDIBits( hdc, src, 0, bm.bmHeight, bits, info, DIB_RGB_COLORS ))
531 StretchDIBits( hdc_dst, 0, 0, dst_width, dst_height,
532 0, 0, bm.bmWidth, bm.bmHeight, bits, info, DIB_RGB_COLORS, SRCCOPY );
533
536 }
537 else
538 {
539 StretchBlt( hdc_dst, 0, 0, dst_width, dst_height, hdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY );
540 SelectObject(hdc, hbmpPrev);
541 }
542
543 DeleteDC( hdc );
544}
545
546/***********************************************************************
547 * bmi_has_alpha
548 */
549static BOOL bmi_has_alpha( const BITMAPINFO *info, const void *bits )
550{
551 int i;
552 BOOL has_alpha = FALSE;
553 const unsigned char *ptr = bits;
554
555 if (info->bmiHeader.biBitCount != 32) return FALSE;
556 for (i = 0; i < info->bmiHeader.biWidth * abs(info->bmiHeader.biHeight); i++, ptr += 4)
557 if ((has_alpha = (ptr[3] != 0))) break;
558 return has_alpha;
559}
560
561/***********************************************************************
562 * create_alpha_bitmap
563 *
564 * Create the alpha bitmap for a 32-bpp icon that has an alpha channel.
565 */
566static
570 _In_opt_ BITMAPINFO *src_info,
571 _In_opt_ const void *color_bits,
574{
576 HDC hdc = NULL, hdcScreen;
577 unsigned char *ptr;
578 void *bits = NULL;
579 ULONG size;
580
581 hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
582 if (!hdcScreen)
583 return NULL;
584 hdc = CreateCompatibleDC(hdcScreen);
585 if (!hdc)
586 {
587 DeleteDC(hdcScreen);
588 return NULL;
589 }
590
591 if (color)
592 {
593 BITMAP bm;
595
596 TRACE("Creating alpha bitmap from existing bitmap.\n");
597
598 if (!GetObjectW( color, sizeof(bm), &bm ))
599 goto done;
600 if (bm.bmBitsPixel != 32)
601 goto done;
602
604
605 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
606 if(!info)
607 goto done;
608 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
609 info->bmiHeader.biWidth = bm.bmWidth;
610 info->bmiHeader.biHeight = -bm.bmHeight;
611 info->bmiHeader.biPlanes = 1;
612 info->bmiHeader.biBitCount = 32;
613 info->bmiHeader.biCompression = BI_RGB;
614 info->bmiHeader.biSizeImage = size;
615 info->bmiHeader.biXPelsPerMeter = 0;
616 info->bmiHeader.biYPelsPerMeter = 0;
617 info->bmiHeader.biClrUsed = 0;
618 info->bmiHeader.biClrImportant = 0;
619
621 if(!bits)
622 {
624 goto done;
625 }
627 {
629 goto done;
630 }
631 if (!bmi_has_alpha( info, bits ))
632 {
634 goto done;
635 }
636
637 /* pre-multiply by alpha */
638 for (ptr = bits; ptr < ((BYTE*)bits + size); ptr += 4)
639 {
640 unsigned int alpha = ptr[3];
641 ptr[0] = (ptr[0] * alpha) / 255;
642 ptr[1] = (ptr[1] * alpha) / 255;
643 ptr[2] = (ptr[2] * alpha) / 255;
644 }
645
646 /* Directly create a 32-bits DDB (thanks to undocumented CreateDIBitmap flag). */
648
650 }
651 else
652 {
653 WORD bpp;
654 DWORD compr;
655 LONG orig_width, orig_height;
656
657 TRACE("Creating alpha bitmap from bitmap info.\n");
658
659 if(!bmi_has_alpha(src_info, color_bits))
660 goto done;
661
662 if(!DIB_GetBitmapInfo(&src_info->bmiHeader, &orig_width, &orig_height, &bpp, &compr))
663 goto done;
664 if(bpp != 32)
665 goto done;
666
667 size = get_dib_image_size(orig_width, orig_height, bpp);
669 if(!bits)
670 goto done;
671 CopyMemory(bits, color_bits, size);
672 /* pre-multiply by alpha */
673 for (ptr = bits; ptr < ((BYTE*)bits + size); ptr += 4)
674 {
675 unsigned int alpha = ptr[3];
676 ptr[0] = (ptr[0] * alpha) / 255;
677 ptr[1] = (ptr[1] * alpha) / 255;
678 ptr[2] = (ptr[2] * alpha) / 255;
679 }
680
681 /* Create the bitmap. Set the bitmap info to have the right width and height */
682 if(src_info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
683 {
684 ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcWidth = width;
685 ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcHeight = height;
686 }
687 else
688 {
689 src_info->bmiHeader.biWidth = width;
690 src_info->bmiHeader.biHeight = height;
691 }
692 /* Directly create a 32-bits DDB (thanks to undocumented CreateDIBitmap flag). */
693 alpha = CreateDIBitmap(hdcScreen, NULL, 2, NULL, src_info, DIB_RGB_COLORS);
694 /* Restore values */
695 if(src_info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
696 {
697 ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcWidth = orig_width;
698 ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcHeight = orig_height;
699 }
700 else
701 {
702 src_info->bmiHeader.biWidth = orig_width;
703 src_info->bmiHeader.biHeight = orig_height;
704 }
705 if(!alpha)
706 goto done;
708 if(!hbmpOld)
709 {
711 alpha = NULL;
712 goto done;
713 }
714 if(!StretchDIBits( hdc, 0, 0, width, height,
715 0, 0, orig_width, orig_height,
716 bits, src_info, DIB_RGB_COLORS, SRCCOPY ))
717 {
719 hbmpOld = NULL;
721 alpha = NULL;
722 }
723 else
724 {
726 }
727 }
728
729done:
730 DeleteDC(hdcScreen);
731 DeleteDC( hdc );
732 if(bits) HeapFree(GetProcessHeap(), 0, bits);
733
734 TRACE("Returning 0x%08x.\n", alpha);
735 return alpha;
736}
737
742 _In_ int cxDesired,
743 _In_ int cyDesired,
744 _In_ BOOL bIcon,
745 _In_ DWORD fuLoad
746)
747{
748 CURSORICONDIR* fakeDir;
749 CURSORICONDIRENTRY* fakeEntry;
750 WORD i;
752
753 /* Check our file is what it claims to be */
754 if ( dwFileSize < sizeof(*dir) )
755 return NULL;
756
757 if (dwFileSize < FIELD_OFFSET(CURSORICONFILEDIR, idEntries[dir->idCount]))
758 return NULL;
759
760 /*
761 * Cute little hack:
762 * We allocate a buffer, fake it as if it was a pointer to a resource in a module,
763 * pass it to LookupIconIdFromDirectoryEx and get back the index we have to use
764 */
765 fakeDir = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(CURSORICONDIR, idEntries[dir->idCount]));
766 if(!fakeDir)
767 {
769 return NULL;
770 }
771 fakeDir->idReserved = 0;
772 fakeDir->idType = dir->idType;
773 fakeDir->idCount = dir->idCount;
774 for(i = 0; i<dir->idCount; i++)
775 {
776 fakeEntry = &fakeDir->idEntries[i];
777 entry = &dir->idEntries[i];
778 /* Take this as an occasion to perform a size check */
779 if ((entry->dwDIBOffset > dwFileSize)
780 || ((entry->dwDIBOffset + entry->dwDIBSize) > dwFileSize))
781 {
782 ERR("Corrupted icon file?.\n");
783 HeapFree(GetProcessHeap(), 0, fakeDir);
784 return NULL;
785 }
786 /* File icon/cursors are not like resource ones */
787 if(bIcon)
788 {
789 fakeEntry->ResInfo.icon.bWidth = entry->bWidth;
790 fakeEntry->ResInfo.icon.bHeight = entry->bHeight;
791 fakeEntry->ResInfo.icon.bColorCount = 0;
792 fakeEntry->ResInfo.icon.bReserved = 0;
793 }
794 else
795 {
796 fakeEntry->ResInfo.cursor.wWidth = entry->bWidth;
797 fakeEntry->ResInfo.cursor.wHeight = entry->bHeight;
798 }
799 /* Let's assume there's always one plane */
800 fakeEntry->wPlanes = 1;
801 /* We must get the bitcount from the BITMAPINFOHEADER itself */
802 if (((BITMAPINFOHEADER *)((char *)dir + entry->dwDIBOffset))->biSize == sizeof(BITMAPCOREHEADER))
803 fakeEntry->wBitCount = ((BITMAPCOREHEADER *)((char *)dir + entry->dwDIBOffset))->bcBitCount;
804 else
805 fakeEntry->wBitCount = ((BITMAPINFOHEADER *)((char *)dir + entry->dwDIBOffset))->biBitCount;
806 fakeEntry->dwBytesInRes = entry->dwDIBSize;
807 fakeEntry->wResId = i + 1;
808 }
809
810 /* Now call LookupIconIdFromResourceEx */
811 i = LookupIconIdFromDirectoryEx((PBYTE)fakeDir, bIcon, cxDesired, cyDesired, fuLoad & LR_MONOCHROME);
812 /* We don't need this anymore */
813 HeapFree(GetProcessHeap(), 0, fakeDir);
814 if(i == 0)
815 {
816 WARN("Unable to get a fit entry index.\n");
817 return NULL;
818 }
819
820 /* We found it */
821 return &dir->idEntries[i-1];
822}
823
824DWORD
826 _In_ const LPBYTE dir,
828 _In_ int cxDesired,
829 _In_ int cyDesired,
830 _In_ BOOL bIcon,
831 _In_ DWORD fuLoad,
832 _Out_ POINT *ptHotSpot
833)
834{
836
837 entry = get_best_icon_file_entry((CURSORICONFILEDIR *) dir, dwFileSize, cxDesired, cyDesired, bIcon, fuLoad);
838
839 if(ptHotSpot)
840 {
841 ptHotSpot->x = entry->xHotspot;
842 ptHotSpot->y = entry->yHotspot;
843 }
844
845 if(entry)
846 return entry->dwDIBOffset;
847
848 return 0;
849}
850
851
852
853/************* IMPLEMENTATION CORE ****************/
854
857 _In_ const BITMAPINFO *pbmi
858)
859{
861 BOOL monochrome = is_dib_monochrome(pbmi);
863 WORD bpp;
864 DWORD compr;
865 int ibmpType;
866 HDC hdc, hdcScreen;
867 BITMAPINFO* pbmiCopy;
869 BOOL bResult = FALSE;
870 const VOID *pvColor, *pvMask;
871
872 ibmpType = DIB_GetBitmapInfo(&pbmi->bmiHeader, &width, &height, &bpp, &compr);
873 /* Invalid data */
874 if(ibmpType < 0)
875 return FALSE;
876
877 /* No compression for icons */
878 if(compr != BI_RGB)
879 return FALSE;
880
881 /* If no dimensions were set, use the one from the icon */
882 if(!pdata->cx) pdata->cx = width;
883 if(!pdata->cy) pdata->cy = height < 0 ? -height/2 : height/2;
884
885 /* Fix the hotspot coords */
886 if(pdata->rt == (USHORT)((ULONG_PTR)RT_CURSOR))
887 {
888 if(pdata->cx != width)
889 pdata->xHotspot = (pdata->xHotspot * pdata->cx) / width;
890 if(pdata->cy != height/2)
891 pdata->yHotspot = (pdata->yHotspot * pdata->cy * 2) / height;
892 }
893 else
894 {
895 pdata->xHotspot = pdata->cx/2;
896 pdata->yHotspot = pdata->cy/2;
897 }
898
899 hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
900 if(!hdcScreen)
901 return FALSE;
902 hdc = CreateCompatibleDC(hdcScreen);
903 if(!hdc)
904 {
905 DeleteDC(hdcScreen);
906 return FALSE;
907 }
908
909 pbmiCopy = HeapAlloc(GetProcessHeap(), 0, max(ubmiSize, FIELD_OFFSET(BITMAPINFO, bmiColors[3])));
910 if(!pbmiCopy)
911 goto done;
912 RtlCopyMemory(pbmiCopy, pbmi, ubmiSize);
913
914 /* In an icon/cursor, the BITMAPINFO holds twice the height */
915 if(pbmiCopy->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
916 ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcHeight /= 2;
917 else
918 pbmiCopy->bmiHeader.biHeight /= 2;
919 height /= 2;
920
921 pvColor = (const char*)pbmi + ubmiSize;
922 pvMask = (const char*)pvColor +
924
925 /* Set XOR bits */
926 if(monochrome)
927 {
928 /* Create the 1bpp bitmap which will contain everything */
929 pdata->hbmColor = NULL;
930 pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy * 2, 1, 1, NULL);
931 if(!pdata->hbmMask)
932 goto done;
933 hbmpOld = SelectObject(hdc, pdata->hbmMask);
934 if(!hbmpOld)
935 goto done;
936
937 if(!StretchDIBits(hdc, 0, pdata->cy, pdata->cx, pdata->cy,
938 0, 0, width, height,
939 pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
940 goto done;
941 pdata->bpp = 1;
942 }
943 else
944 {
945 /* Create the bitmap. It has to be compatible with the screen surface */
946 pdata->hbmColor = CreateCompatibleBitmap(hdcScreen, pdata->cx, pdata->cy);
947 if(!pdata->hbmColor)
948 goto done;
949 /* Create the 1bpp mask bitmap */
950 pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy, 1, 1, NULL);
951 if(!pdata->hbmMask)
952 goto done;
953 hbmpOld = SelectObject(hdc, pdata->hbmColor);
954 if(!hbmpOld)
955 goto done;
956 if(!StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy,
957 0, 0, width, height,
958 pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
959 goto done;
960 pdata->bpp = GetDeviceCaps(hdcScreen, BITSPIXEL);
961 pdata->hbmAlpha = create_alpha_bitmap(NULL, pbmiCopy, pvColor, pdata->cx, pdata->cy);
962
963 /* Now convert the info to monochrome for the mask bits */
964 if (pbmiCopy->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))
965 {
966 RGBQUAD *rgb = pbmiCopy->bmiColors;
967
968 pbmiCopy->bmiHeader.biClrUsed = pbmiCopy->bmiHeader.biClrImportant = 2;
969 rgb[0].rgbBlue = rgb[0].rgbGreen = rgb[0].rgbRed = 0x00;
970 rgb[1].rgbBlue = rgb[1].rgbGreen = rgb[1].rgbRed = 0xff;
971 rgb[0].rgbReserved = rgb[1].rgbReserved = 0;
972 pbmiCopy->bmiHeader.biBitCount = 1;
973 }
974 else
975 {
976 RGBTRIPLE *rgb = (RGBTRIPLE *)(((BITMAPCOREHEADER *)pbmiCopy) + 1);
977
978 rgb[0].rgbtBlue = rgb[0].rgbtGreen = rgb[0].rgbtRed = 0x00;
979 rgb[1].rgbtBlue = rgb[1].rgbtGreen = rgb[1].rgbtRed = 0xff;
980 ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcBitCount = 1;
981 }
982 }
983 /* Set the mask bits */
984 if(!SelectObject(hdc, pdata->hbmMask))
985 goto done;
986 bResult = StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy,
987 0, 0, width, height,
988 pvMask, pbmiCopy, DIB_RGB_COLORS, SRCCOPY) != 0;
989
990done:
991 DeleteDC(hdcScreen);
993 DeleteDC(hdc);
994 if(pbmiCopy) HeapFree(GetProcessHeap(), 0, pbmiCopy);
995 /* Clean up in case of failure */
996 if(!bResult)
997 {
998 if(pdata->hbmMask) DeleteObject(pdata->hbmMask);
999 if(pdata->hbmColor) DeleteObject(pdata->hbmColor);
1000 if(pdata->hbmAlpha) DeleteObject(pdata->hbmAlpha);
1001 }
1002 return bResult;
1003}
1004
1006 _Out_ CURSORDATA* pCursorData,
1007 _In_ ICONINFO* pIconInfo
1008)
1009{
1010 BITMAP bm;
1011
1012 ZeroMemory(pCursorData, sizeof(*pCursorData));
1013 if(pIconInfo->hbmColor)
1014 {
1015 /* We must convert the color bitmap to screen format */
1016 HDC hdcScreen, hdcMem;
1017 HBITMAP hbmpPrev;
1018
1019 /* The mask dictates its dimensions */
1020 if (!GetObject(pIconInfo->hbmMask, sizeof(bm), &bm))
1021 return FALSE;
1022 hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
1023 if(!hdcScreen)
1024 return FALSE;
1025 hdcMem = CreateCompatibleDC(hdcScreen);
1026 if(!hdcMem)
1027 {
1028 DeleteDC(hdcScreen);
1029 return FALSE;
1030 }
1031 pCursorData->hbmColor = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight);
1032 DeleteDC(hdcScreen);
1033 if (!pCursorData->hbmColor)
1034 {
1036 return FALSE;
1037 }
1038 hbmpPrev = SelectObject(hdcMem, pCursorData->hbmColor);
1039 if (!hbmpPrev)
1040 {
1042 DeleteObject(pCursorData->hbmColor);
1043 return FALSE;
1044 }
1045 stretch_blt_icon( hdcMem, bm.bmWidth, bm.bmHeight, pIconInfo->hbmColor);
1046 SelectObject(hdcMem, hbmpPrev);
1048 }
1049 pCursorData->hbmMask = CopyImage(pIconInfo->hbmMask, IMAGE_BITMAP, 0, 0, LR_MONOCHROME);
1050 if(!pCursorData->hbmMask)
1051 return FALSE;
1052
1053 /* Now, fill some information */
1054 pCursorData->rt = (USHORT)((ULONG_PTR)(pIconInfo->fIcon ? RT_ICON : RT_CURSOR));
1055 if(pCursorData->hbmColor)
1056 {
1057 GetObject(pCursorData->hbmColor, sizeof(bm), &bm);
1058 pCursorData->bpp = bm.bmBitsPixel;
1059 pCursorData->cx = bm.bmWidth;
1060 pCursorData->cy = bm.bmHeight;
1061 if(pCursorData->bpp == 32)
1062 pCursorData->hbmAlpha = create_alpha_bitmap(pCursorData->hbmColor, NULL, NULL, 0, 0);
1063 }
1064 else
1065 {
1066 GetObject(pCursorData->hbmMask, sizeof(bm), &bm);
1067 pCursorData->bpp = 1;
1068 pCursorData->cx = bm.bmWidth;
1069 pCursorData->cy = bm.bmHeight/2;
1070 }
1071
1072 if(pIconInfo->fIcon)
1073 {
1074 pCursorData->xHotspot = pCursorData->cx/2;
1075 pCursorData->yHotspot = pCursorData->cy/2;
1076 }
1077 else
1078 {
1079 pCursorData->xHotspot = pIconInfo->xHotspot;
1080 pCursorData->yHotspot = pIconInfo->yHotspot;
1081 }
1082
1083 return TRUE;
1084}
1085
1086
1087#define RIFF_FOURCC( c0, c1, c2, c3 ) \
1088 ( (DWORD)(BYTE)(c0) | ( (DWORD)(BYTE)(c1) << 8 ) | \
1089 ( (DWORD)(BYTE)(c2) << 16 ) | ( (DWORD)(BYTE)(c3) << 24 ) )
1090
1091#define ANI_RIFF_ID RIFF_FOURCC('R', 'I', 'F', 'F')
1092#define ANI_LIST_ID RIFF_FOURCC('L', 'I', 'S', 'T')
1093#define ANI_ACON_ID RIFF_FOURCC('A', 'C', 'O', 'N')
1094#define ANI_anih_ID RIFF_FOURCC('a', 'n', 'i', 'h')
1095#define ANI_seq__ID RIFF_FOURCC('s', 'e', 'q', ' ')
1096#define ANI_fram_ID RIFF_FOURCC('f', 'r', 'a', 'm')
1097#define ANI_rate_ID RIFF_FOURCC('r', 'a', 't', 'e')
1098
1099#define ANI_FLAG_ICON 0x1
1100#define ANI_FLAG_SEQUENCE 0x2
1101
1102#include <pshpack1.h>
1103typedef struct {
1104 DWORD header_size;
1105 DWORD num_frames;
1106 DWORD num_steps;
1107 DWORD width;
1108 DWORD height;
1109 DWORD bpp;
1110 DWORD num_planes;
1111 DWORD display_rate;
1112 DWORD flags;
1113} ani_header;
1114
1115typedef struct {
1117 const unsigned char *data;
1118} riff_chunk_t;
1119#include <poppack.h>
1120
1121static void dump_ani_header( const ani_header *header )
1122{
1123 TRACE(" header size: %d\n", header->header_size);
1124 TRACE(" frames: %d\n", header->num_frames);
1125 TRACE(" steps: %d\n", header->num_steps);
1126 TRACE(" width: %d\n", header->width);
1127 TRACE(" height: %d\n", header->height);
1128 TRACE(" bpp: %d\n", header->bpp);
1129 TRACE(" planes: %d\n", header->num_planes);
1130 TRACE(" display rate: %d\n", header->display_rate);
1131 TRACE(" flags: 0x%08x\n", header->flags);
1132}
1133
1134/* Find an animated cursor chunk, given its type and ID */
1135static void riff_find_chunk( DWORD chunk_id, DWORD chunk_type, const riff_chunk_t *parent_chunk, riff_chunk_t *chunk )
1136{
1137 const unsigned char *ptr = parent_chunk->data;
1138 const unsigned char *end = parent_chunk->data + (parent_chunk->data_size - (2 * sizeof(DWORD)));
1139
1140 if (chunk_type == ANI_LIST_ID || chunk_type == ANI_RIFF_ID) end -= sizeof(DWORD);
1141
1142 while (ptr < end)
1143 {
1144 if ((!chunk_type && *(const DWORD *)ptr == chunk_id )
1145 || (chunk_type && *(const DWORD *)ptr == chunk_type && *((const DWORD *)ptr + 2) == chunk_id ))
1146 {
1147 ptr += sizeof(DWORD);
1148 chunk->data_size = (*(const DWORD *)ptr + 1) & ~1;
1149 ptr += sizeof(DWORD);
1150 if (chunk_type == ANI_LIST_ID || chunk_type == ANI_RIFF_ID) ptr += sizeof(DWORD);
1151 chunk->data = ptr;
1152
1153 return;
1154 }
1155
1156 ptr += sizeof(DWORD);
1157 ptr += (*(const DWORD *)ptr + 1) & ~1;
1158 ptr += sizeof(DWORD);
1159 }
1160}
1161
1163 _Inout_ CURSORDATA* pCurData,
1164 _In_ const BYTE *pData,
1165 _In_ DWORD dwDataSize,
1166 _In_ DWORD fuLoad
1167)
1168{
1169 UINT i;
1170 const ani_header *pHeader;
1171 riff_chunk_t root_chunk = { dwDataSize, pData };
1172 riff_chunk_t ACON_chunk = {0};
1173 riff_chunk_t anih_chunk = {0};
1174 riff_chunk_t fram_chunk = {0};
1175 riff_chunk_t rate_chunk = {0};
1176 riff_chunk_t seq_chunk = {0};
1177 const unsigned char *icon_chunk;
1178 const unsigned char *icon_data;
1179
1180 /* Find the root chunk */
1181 riff_find_chunk( ANI_ACON_ID, ANI_RIFF_ID, &root_chunk, &ACON_chunk );
1182 if (!ACON_chunk.data)
1183 {
1184 ERR("Failed to get root chunk.\n");
1185 return FALSE;
1186 }
1187
1188 /* Find the header chunk */
1189 riff_find_chunk( ANI_anih_ID, 0, &ACON_chunk, &anih_chunk );
1190 if (!ACON_chunk.data)
1191 {
1192 ERR("Failed to get header chunk.\n");
1193 return FALSE;
1194 }
1195 pHeader = (ani_header*)anih_chunk.data;
1197
1198 /* Set up the master data */
1199 pCurData->CURSORF_flags |= CURSORF_ACON;
1200 pCurData->cpcur = pHeader->num_frames;
1201 pCurData->cicur = pHeader->num_steps;
1202 pCurData->iicur = pHeader->display_rate;
1203
1204 /* Get the sequences */
1205 if (pHeader->flags & ANI_FLAG_SEQUENCE)
1206 {
1207 riff_find_chunk( ANI_seq__ID, 0, &ACON_chunk, &seq_chunk );
1208 if (!seq_chunk.data)
1209 {
1210 ERR("No sequence data although the flag is set!\n");
1211 return FALSE;
1212 }
1213 }
1214
1215 /* Get the frame rates */
1216 riff_find_chunk( ANI_rate_ID, 0, &ACON_chunk, &rate_chunk );
1217 if (rate_chunk.data)
1218 pCurData->ajifRate = (INT*)rate_chunk.data;
1219
1220 /* Get the frames chunk */
1221 riff_find_chunk( ANI_fram_ID, ANI_LIST_ID, &ACON_chunk, &fram_chunk );
1222 if (!fram_chunk.data)
1223 {
1224 ERR("Failed to get icon list.\n");
1225 return 0;
1226 }
1227 icon_chunk = fram_chunk.data;
1228 icon_data = fram_chunk.data + (2 * sizeof(DWORD));
1229
1230 if(pHeader->num_frames > 1)
1231 {
1232 /* Allocate frame descriptors, step indices and rates */
1233 pCurData->aspcur = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1234 pHeader->num_frames * sizeof(CURSORDATA) + pHeader->num_steps * (sizeof(DWORD) + sizeof(INT)));
1235 if(!pCurData->aspcur)
1236 {
1238 return FALSE;
1239 }
1240 pCurData->aicur = (DWORD*)(pCurData->aspcur + pHeader->num_frames);
1241 pCurData->ajifRate = (INT*)(pCurData->aicur + pHeader->num_steps);
1242 }
1243
1244 for(i=0; i < pHeader->num_frames; i++)
1245 {
1246 CURSORDATA* pFrameData;
1247 const DWORD chunk_size = *(const DWORD *)(icon_chunk + sizeof(DWORD));
1248 const BITMAPINFO* pbmi;
1249
1250 if(pHeader->num_frames > 1)
1251 pFrameData = &pCurData->aspcur[i];
1252 else
1253 pFrameData = pCurData;
1254
1255 pFrameData->rt = pCurData->rt;
1256
1257 if (pHeader->flags & ANI_FLAG_ICON)
1258 {
1259 /* The chunks describe an icon file */
1261 (const CURSORICONFILEDIR *) icon_data,
1262 chunk_size,
1263 pCurData->cx,
1264 pCurData->cy,
1265 TRUE,
1266 fuLoad);
1267 if(!pDirEntry)
1268 {
1269 ERR("Unable to find the right file entry for frame %d.\n", i);
1270 goto error;
1271 }
1272 pFrameData->xHotspot = pDirEntry->xHotspot;
1273 pFrameData->yHotspot = pDirEntry->yHotspot;
1274 if(!pHeader->width || !pHeader->height)
1275 {
1276 pFrameData->cx = pDirEntry->bWidth;
1277 pFrameData->cy = pDirEntry->bHeight;
1278 }
1279 else
1280 {
1281 pFrameData->cx = pHeader->width;
1282 pFrameData->cy = pHeader->height;
1283 }
1284 pbmi = (const BITMAPINFO *) (icon_data + pDirEntry->dwDIBOffset);
1285 }
1286 else
1287 {
1288 /* The chunks just describe bitmaps */
1289 pbmi = (const BITMAPINFO *)icon_data;
1290 pFrameData->xHotspot = pFrameData->yHotspot = 0;
1291 }
1292
1293 /* Do the real work */
1295
1296 if(pHeader->num_frames > 1)
1297 pFrameData->CURSORF_flags |= CURSORF_ACONFRAME;
1298 else
1299 pFrameData->CURSORF_flags &= ~CURSORF_ACON;
1300
1301
1302 /* Next frame */
1303 icon_chunk += chunk_size + (2 * sizeof(DWORD));
1304 icon_data = icon_chunk + (2 * sizeof(DWORD));
1305 }
1306
1307 if(pHeader->num_frames <= 1)
1308 return TRUE;
1309
1310 if(rate_chunk.data)
1311 CopyMemory(pCurData->ajifRate, rate_chunk.data, pHeader->num_steps * sizeof(INT));
1312 else
1313 {
1314 for(i=0; i < pHeader->num_steps; i++)
1315 pCurData->ajifRate[i] = pHeader->display_rate;
1316 }
1317
1318 if (pHeader->flags & ANI_FLAG_SEQUENCE)
1319 {
1320 CopyMemory(pCurData->aicur, seq_chunk.data, pHeader->num_steps * sizeof(DWORD));
1321 }
1322 else
1323 {
1324 for(i=0; i < pHeader->num_steps; i++)
1325 pCurData->aicur[i] = i;
1326 }
1327
1328 return TRUE;
1329
1330error:
1331 HeapFree(GetProcessHeap(), 0, pCurData->aspcur);
1332 ZeroMemory(pCurData, sizeof(CURSORDATA));
1333 return FALSE;
1334}
1335
1336
1337static
1338HBITMAP
1341 _In_ LPCWSTR lpszName,
1342 _In_ int cxDesired,
1343 _In_ int cyDesired,
1344 _In_ UINT fuLoad
1345)
1346{
1347 const BITMAPINFO* pbmi;
1348 BITMAPINFO* pbmiScaled = NULL;
1349 BITMAPINFO* pbmiCopy = NULL;
1350 const VOID* pvMapping = NULL;
1351 DWORD dwOffset = 0;
1352 HGLOBAL hgRsrc = NULL;
1353 int iBMISize;
1354 PVOID pvBits;
1355 HDC hdcScreen = NULL;
1356 HDC hdc = NULL;
1357 HBITMAP hbmpOld, hbmpRet = NULL;
1358 LONG width, height;
1359 WORD bpp;
1360 DWORD compr, ResSize = 0;
1361
1362 /* Map the bitmap info */
1363 if(fuLoad & LR_LOADFROMFILE)
1364 {
1365 const BITMAPFILEHEADER* pbmfh;
1366
1367 pvMapping = map_fileW(lpszName, NULL);
1368 if(!pvMapping)
1369 return NULL;
1370 pbmfh = pvMapping;
1371 if (pbmfh->bfType != 0x4d42 /* 'BM' */)
1372 {
1373 WARN("Invalid/unsupported bitmap format!\n");
1374 goto end;
1375 }
1376 pbmi = (const BITMAPINFO*)(pbmfh + 1);
1377
1378 /* Get the image bits */
1379 if(pbmfh->bfOffBits)
1380 dwOffset = pbmfh->bfOffBits - sizeof(BITMAPFILEHEADER);
1381 }
1382 else
1383 {
1384 HRSRC hrsrc;
1385
1386 /* Caller wants an OEM bitmap */
1387 if(!hinst)
1389 hrsrc = FindResourceW(hinst, lpszName, RT_BITMAP);
1390 if(!hrsrc)
1391 return NULL;
1392 hgRsrc = LoadResource(hinst, hrsrc);
1393 if(!hgRsrc)
1394 return NULL;
1395 pbmi = LockResource(hgRsrc);
1396 if(!pbmi)
1397 return NULL;
1398 ResSize = SizeofResource(hinst, hrsrc);
1399 }
1400
1402 {
1403 SIZE_T totalSize = pbmi->bmiHeader.biSize + (3 * sizeof(DWORD)) +
1405 if (pbmi->bmiHeader.biSizeImage != 0 && totalSize != ResSize)
1406 WARN("Possibly bad resource size provided\n");
1407 }
1408
1409 /* Fix up values */
1410 if(DIB_GetBitmapInfo(&pbmi->bmiHeader, &width, &height, &bpp, &compr) == -1)
1411 goto end;
1412 if((width > 65535) || (height > 65535))
1413 goto end;
1414 if(cxDesired == 0)
1415 cxDesired = width;
1416 if(cyDesired == 0)
1417 cyDesired = height;
1418 else if(height < 0)
1419 cyDesired = -cyDesired;
1420
1422
1423 /* Get a pointer to the image data */
1424 pvBits = (char*)pbmi + (dwOffset ? dwOffset : iBMISize);
1425
1426 /* Create a copy of the info describing the bitmap in the file */
1427 pbmiCopy = HeapAlloc(GetProcessHeap(), 0, iBMISize);
1428 if(!pbmiCopy)
1429 goto end;
1430 CopyMemory(pbmiCopy, pbmi, iBMISize);
1431
1432 TRACE("Size Image %d, Size Header %d, ResSize %d\n",
1433 pbmiCopy->bmiHeader.biSizeImage, pbmiCopy->bmiHeader.biSize, ResSize);
1434
1435 /* HACK: If this is a binutils' windres.exe compiled 16 or 32 bpp bitmap
1436 * using BI_BITFIELDS, then a bug causes it to fail to include
1437 * the bytes for the bitfields. So, we have to substract out the
1438 * size of the bitfields previously included from bitmap_info_size. */
1439 if (compr == BI_BITFIELDS && (bpp == 16 || bpp == 32) &&
1440 pbmiCopy->bmiHeader.biSizeImage + pbmiCopy->bmiHeader.biSize == ResSize)
1441 {
1442 /* GCC pointer to the image data has 12 less bytes than MSVC */
1443 pvBits = (char*)pvBits - 12;
1444 WARN("Found GCC Resource Compiled 16-bpp or 32-bpp error\n");
1445 }
1446
1447 /* Fix it up, if needed */
1448 if(fuLoad & (LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS))
1449 {
1450 WORD bpp, incr, numColors;
1451 char* pbmiColors;
1452 RGBTRIPLE* ptr;
1453 COLORREF crWindow, cr3DShadow, cr3DFace, cr3DLight;
1454 BYTE pixel = *((BYTE*)pvBits);
1455 UINT i;
1456
1457 if(pbmiCopy->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1458 {
1459 bpp = ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcBitCount;
1460 numColors = 1 << bpp;
1461 /* BITMAPCOREINFO holds RGBTRIPLEs */
1462 incr = 3;
1463 }
1464 else
1465 {
1466 bpp = pbmiCopy->bmiHeader.biBitCount;
1467 /* BITMAPINFOHEADER holds RGBQUADs */
1468 incr = 4;
1469 numColors = pbmiCopy->bmiHeader.biClrUsed;
1470 if(numColors > 256) numColors = 256;
1471 if (!numColors && (bpp <= 8)) numColors = 1 << bpp;
1472 }
1473
1474 if(bpp > 8)
1475 goto create_bitmap;
1476
1477 pbmiColors = (char*)pbmiCopy + pbmiCopy->bmiHeader.biSize;
1478
1479 /* Get the relevant colors */
1480 crWindow = GetSysColor(COLOR_WINDOW);
1481 cr3DShadow = GetSysColor(COLOR_3DSHADOW);
1482 cr3DFace = GetSysColor(COLOR_3DFACE);
1483 cr3DLight = GetSysColor(COLOR_3DLIGHT);
1484
1485 /* Fix the transparent palette entry */
1486 if(fuLoad & LR_LOADTRANSPARENT)
1487 {
1488 switch(bpp)
1489 {
1490 case 1: pixel >>= 7; break;
1491 case 4: pixel >>= 4; break;
1492 case 8: break;
1493 default:
1494 FIXME("Unhandled bit depth %d.\n", bpp);
1495 goto create_bitmap;
1496 }
1497
1498 if(pixel >= numColors)
1499 {
1500 ERR("Wrong pixel passed in.\n");
1501 goto create_bitmap;
1502 }
1503
1504 /* If both flags are set, we must use COLOR_3DFACE */
1505 if(fuLoad & LR_LOADMAP3DCOLORS) crWindow = cr3DFace;
1506
1507 /* Define the color */
1508 ptr = (RGBTRIPLE*)(pbmiColors + pixel*incr);
1509 ptr->rgbtBlue = GetBValue(crWindow);
1510 ptr->rgbtGreen = GetGValue(crWindow);
1511 ptr->rgbtRed = GetRValue(crWindow);
1512 goto create_bitmap;
1513 }
1514
1515 /* If we are here, then LR_LOADMAP3DCOLORS is set without LR_TRANSPARENT */
1516 for(i = 0; i<numColors; i++)
1517 {
1518 ptr = (RGBTRIPLE*)(pbmiColors + i*incr);
1519 if((ptr->rgbtBlue == ptr->rgbtRed) && (ptr->rgbtBlue == ptr->rgbtGreen))
1520 {
1521 if(ptr->rgbtBlue == 128)
1522 {
1523 ptr->rgbtBlue = GetBValue(cr3DShadow);
1524 ptr->rgbtGreen = GetGValue(cr3DShadow);
1525 ptr->rgbtRed = GetRValue(cr3DShadow);
1526 }
1527 if(ptr->rgbtBlue == 192)
1528 {
1529 ptr->rgbtBlue = GetBValue(cr3DFace);
1530 ptr->rgbtGreen = GetGValue(cr3DFace);
1531 ptr->rgbtRed = GetRValue(cr3DFace);
1532 }
1533 if(ptr->rgbtBlue == 223)
1534 {
1535 ptr->rgbtBlue = GetBValue(cr3DLight);
1536 ptr->rgbtGreen = GetGValue(cr3DLight);
1537 ptr->rgbtRed = GetRValue(cr3DLight);
1538 }
1539 }
1540 }
1541 }
1542
1544 if(fuLoad & LR_CREATEDIBSECTION)
1545 {
1546 /* Allocate the BMI describing the new bitmap */
1547 pbmiScaled = HeapAlloc(GetProcessHeap(), 0, iBMISize);
1548 if(!pbmiScaled)
1549 goto end;
1550 CopyMemory(pbmiScaled, pbmiCopy, iBMISize);
1551
1552 /* Fix it up */
1553 if(pbmiScaled->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1554 {
1555 BITMAPCOREHEADER* pbmch = (BITMAPCOREHEADER*)&pbmiScaled->bmiHeader;
1556 pbmch->bcWidth = cxDesired;
1557 pbmch->bcHeight = cyDesired;
1558 }
1559 else
1560 {
1561 pbmiScaled->bmiHeader.biWidth = cxDesired;
1562 pbmiScaled->bmiHeader.biHeight = cyDesired;
1563 /* No compression for DIB sections */
1564 pbmiScaled->bmiHeader.biCompression = BI_RGB;
1565 }
1566 }
1567
1568 /* Top-down image */
1569 if(cyDesired < 0) cyDesired = -cyDesired;
1570
1571 /* We need a device context */
1572 hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
1573 if(!hdcScreen)
1574 goto end;
1575 hdc = CreateCompatibleDC(hdcScreen);
1576 if(!hdc)
1577 goto end;
1578
1579 /* Now create the bitmap */
1580 if(fuLoad & LR_CREATEDIBSECTION)
1581 hbmpRet = CreateDIBSection(hdc, pbmiScaled, DIB_RGB_COLORS, NULL, 0, 0);
1582 else
1583 {
1584 if(is_dib_monochrome(pbmiCopy) || (fuLoad & LR_MONOCHROME))
1585 hbmpRet = CreateBitmap(cxDesired, cyDesired, 1, 1, NULL);
1586 else
1587 hbmpRet = CreateCompatibleBitmap(hdcScreen, cxDesired, cyDesired);
1588 }
1589
1590 if(!hbmpRet)
1591 goto end;
1592
1593 hbmpOld = SelectObject(hdc, hbmpRet);
1594 if(!hbmpOld)
1595 goto end;
1596 if(!StretchDIBits(hdc, 0, 0, cxDesired, cyDesired,
1597 0, 0, width, height,
1598 pvBits, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
1599 {
1600 ERR("StretchDIBits failed!.\n");
1602 DeleteObject(hbmpRet);
1603 hbmpRet = NULL;
1604 goto end;
1605 }
1606
1608
1609end:
1610 if(hdcScreen)
1611 DeleteDC(hdcScreen);
1612 if(hdc)
1613 DeleteDC(hdc);
1614 if(pbmiScaled)
1615 HeapFree(GetProcessHeap(), 0, pbmiScaled);
1616 if(pbmiCopy)
1617 HeapFree(GetProcessHeap(), 0, pbmiCopy);
1618 if (pvMapping)
1619 UnmapViewOfFile( pvMapping );
1620 if(hgRsrc)
1621 FreeResource(hgRsrc);
1622
1623 return hbmpRet;
1624}
1625
1626
1627static
1628HANDLE
1630 _In_ LPCWSTR lpszName,
1631 _In_ int cxDesired,
1632 _In_ int cyDesired,
1633 _In_ UINT fuLoad,
1634 _In_ BOOL bIcon
1635)
1636{
1638 const CURSORICONFILEDIR *dir;
1639 DWORD filesize = 0, BmpIconSize;
1640 PBYTE bits, pbBmpIcon = NULL;
1641 HANDLE hCurIcon = NULL;
1642 CURSORDATA cursorData = { 0 };
1643
1644 TRACE("loading %s\n", debugstr_w( lpszName ));
1645
1646 bits = map_fileW( lpszName, &filesize );
1647 if (!bits)
1648 return NULL;
1649
1650 /* Check for .ani. */
1651 if (memcmp( bits, "RIFF", 4 ) == 0)
1652 {
1654 goto end;
1655 }
1656
1658 entry = get_best_icon_file_entry(dir, filesize, cxDesired, cyDesired, bIcon, fuLoad);
1659 if(!entry)
1660 goto end;
1661
1662 /* Fix dimensions */
1663 if(!cxDesired) cxDesired = entry->bWidth;
1664 if(!cyDesired) cyDesired = entry->bHeight;
1665 /* A bit of preparation */
1666 if(!bIcon)
1667 {
1668 cursorData.xHotspot = entry->xHotspot;
1669 cursorData.yHotspot = entry->yHotspot;
1670 }
1671 cursorData.rt = LOWORD(bIcon ? RT_ICON : RT_CURSOR);
1672
1673 /* Try to load BMP icon */
1674 if (!CURSORICON_GetCursorDataFromBMI(&cursorData, (PBITMAPINFO)(&bits[entry->dwDIBOffset])))
1675 {
1676 /* Convert PNG raw data to BMP icon if the icon was PNG icon */
1677 PBYTE pngBits = &bits[entry->dwDIBOffset];
1678 pbBmpIcon = CURSORICON_ConvertPngToBmpIcon(pngBits, filesize, &BmpIconSize);
1679 if (!pbBmpIcon)
1680 goto end; /* Not PNG icon or failed */
1681
1682 /* Find icon entry from BMP icon */
1683 dir = (CURSORICONFILEDIR *)pbBmpIcon;
1684 entry = &dir->idEntries[0]; /* Only one entry */
1685
1686 /* A bit of preparation */
1687 ZeroMemory(&cursorData, sizeof(cursorData));
1688 cursorData.rt = LOWORD(bIcon ? RT_ICON : RT_CURSOR);
1689
1690 /* Can we load this BMP icon? */
1691 if (!CURSORICON_GetCursorDataFromBMI(&cursorData, (PBITMAPINFO)(&pbBmpIcon[entry->dwDIBOffset])))
1692 {
1693 ERR("Failing file: '%S'.\n", lpszName);
1694 goto end;
1695 }
1696
1697 TRACE("Processing PNG/Vista icon: '%S'\n", lpszName);
1698 }
1699
1701 if(!hCurIcon)
1702 goto end;
1703
1704 /* Tell win32k */
1705 if(!NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData))
1706 {
1707 NtUserDestroyCursor(hCurIcon, TRUE);
1708 hCurIcon = NULL;
1709 }
1710
1711end:
1712 if (!hCurIcon)
1713 {
1714 if (cursorData.hbmMask) DeleteObject(cursorData.hbmMask);
1715 if (cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
1716 if (cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
1717 }
1718 HeapFree(GetProcessHeap(), 0, pbBmpIcon);
1720 return hCurIcon;
1721}
1722
1723static
1724HANDLE
1727 _In_ LPCWSTR lpszName,
1728 _In_ int cxDesired,
1729 _In_ int cyDesired,
1730 _In_ UINT fuLoad,
1731 _In_ BOOL bIcon
1732)
1733{
1734 HRSRC hrsrc;
1735 HANDLE handle, hCurIcon = NULL;
1737 WORD wResId;
1738 LPBYTE bits;
1739 CURSORDATA cursorData;
1740 BOOL bStatus;
1741 UNICODE_STRING ustrRsrc;
1742 UNICODE_STRING ustrModule = {0, 0, NULL};
1743
1744 /* Fix width/height */
1745 if(fuLoad & LR_DEFAULTSIZE)
1746 {
1747 if(!cxDesired) cxDesired = GetSystemMetrics(bIcon ? SM_CXICON : SM_CXCURSOR);
1748 if(!cyDesired) cyDesired = GetSystemMetrics(bIcon ? SM_CYICON : SM_CYCURSOR);
1749 }
1750
1751 if(fuLoad & LR_LOADFROMFILE)
1752 {
1753 return CURSORICON_LoadFromFileW(lpszName, cxDesired, cyDesired, fuLoad, bIcon);
1754 }
1755
1756 /* Check if caller wants OEM icons */
1757 if(!hinst)
1758 {
1759 #ifndef IDI_SHIELD
1760 #define IDI_SHIELD MAKEINTRESOURCE(32518)
1761 #endif
1762
1764
1765 /* Map IDI to resource id */
1766 if (bIcon && lpszName >= IDI_APPLICATION && lpszName <= IDI_SHIELD)
1767 {
1768 SIZE_T id = 100 + (SIZE_T)lpszName - (SIZE_T)IDI_APPLICATION;
1769 if ((id | 2) == 103)
1770 id ^= 2; /* Must swap IDI_ERROR and IDI_WARNING */
1771 lpszName = MAKEINTRESOURCEW(id);
1772 }
1773 }
1774
1775 if(lpszName)
1776 {
1777 /* Prepare the resource name string */
1778 if(IS_INTRESOURCE(lpszName))
1779 {
1780 ustrRsrc.Buffer = (LPWSTR)lpszName;
1781 ustrRsrc.Length = 0;
1782 ustrRsrc.MaximumLength = 0;
1783 }
1784 else
1785 RtlInitUnicodeString(&ustrRsrc, lpszName);
1786 }
1787
1789 {
1790 /* We don't have a real module for GetModuleFileName, construct a fake name instead.
1791 * GetIconInfoEx reveals the name used by Windows. */
1792 LPCWSTR fakeNameFmt = sizeof(void*) > 4 ? L"\x01%016IX" : L"\x01%08IX";
1793 ustrModule.MaximumLength = 18 * sizeof(WCHAR);
1794 ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength);
1795 if (!ustrModule.Buffer)
1796 {
1798 return NULL;
1799 }
1800 ustrModule.Length = (USHORT)wsprintfW(ustrModule.Buffer, fakeNameFmt, hinst) * sizeof(WCHAR);
1801 }
1802 else if(hinst)
1803 {
1805 /* Get the module name string */
1806 while (TRUE)
1807 {
1808 DWORD ret;
1809 ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
1810 if (!ustrModule.Buffer)
1811 {
1813 return NULL;
1814 }
1815 ret = GetModuleFileNameW(hinst, ustrModule.Buffer, size);
1816 if(ret == 0)
1817 {
1818 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1819 return NULL;
1820 }
1821
1822 /* This API is completely broken... */
1823 if (ret == size)
1824 {
1825 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1826 size *= 2;
1827 continue;
1828 }
1829
1830 ustrModule.Buffer[ret] = UNICODE_NULL;
1831 ustrModule.Length = (USHORT)(ret * sizeof(WCHAR));
1832 ustrModule.MaximumLength = (USHORT)(size * sizeof(WCHAR));
1833 break;
1834 }
1835 }
1836
1837 if(fuLoad & LR_SHARED)
1838 {
1840
1841 TRACE("Checking for an LR_SHARED cursor/icon.\n");
1842 /* Ask win32k */
1843 param.bIcon = bIcon;
1844 param.cx = cxDesired;
1845 param.cy = cyDesired;
1846 hCurIcon = NtUserFindExistingCursorIcon(&ustrModule, &ustrRsrc, &param);
1847 if(hCurIcon)
1848 {
1849 /* Woohoo, got it! */
1850 TRACE("MATCH! %p\n",hCurIcon);
1851 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1852 return hCurIcon;
1853 }
1854 }
1855
1856 /* Find resource ID */
1857 hrsrc = FindResourceW(
1858 hinst,
1859 lpszName,
1860 bIcon ? RT_GROUP_ICON : RT_GROUP_CURSOR);
1861
1862 /* We let FindResource, LoadResource, etc. call SetLastError */
1863 if(!hrsrc)
1864 goto done;
1865
1866 handle = LoadResource(hinst, hrsrc);
1867 if(!handle)
1868 goto done;
1869
1871 if(!dir)
1872 goto done;
1873
1874 wResId = LookupIconIdFromDirectoryEx((PBYTE)dir, bIcon, cxDesired, cyDesired, fuLoad);
1876
1877 /* Get the relevant resource pointer */
1878 hrsrc = FindResourceW(
1879 hinst,
1880 MAKEINTRESOURCEW(wResId),
1881 bIcon ? RT_ICON : RT_CURSOR);
1882 if(!hrsrc)
1883 goto done;
1884
1885 handle = LoadResource(hinst, hrsrc);
1886 if(!handle)
1887 goto done;
1888
1890 if(!bits)
1891 {
1893 goto done;
1894 }
1895
1896 ZeroMemory(&cursorData, sizeof(cursorData));
1897
1898 /* This is from resource */
1900
1901 if(dir->idType == 2)
1902 {
1903 /* idType == 2 for cursor resources */
1904 SHORT* ptr = (SHORT*)bits;
1905 cursorData.xHotspot = ptr[0];
1906 cursorData.yHotspot = ptr[1];
1907 bits += 2*sizeof(SHORT);
1908 }
1909 cursorData.cx = cxDesired;
1910 cursorData.cy = cyDesired;
1911 cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR));
1912
1913 /* Get the bitmaps */
1915 &cursorData,
1916 (BITMAPINFO*)bits);
1917
1919
1920 if(!bStatus)
1921 goto done;
1922
1923 /* Create the handle */
1925 if(!hCurIcon)
1926 {
1927 goto end_error;
1928 }
1929
1930 if(fuLoad & LR_SHARED)
1931 {
1932 cursorData.CURSORF_flags |= CURSORF_LRSHARED;
1933 }
1934
1935 /* Tell win32k */
1936 bStatus = NtUserSetCursorIconData(hCurIcon, hinst ? &ustrModule : NULL, lpszName ? &ustrRsrc : NULL, &cursorData);
1937
1938 if(!bStatus)
1939 {
1940 NtUserDestroyCursor(hCurIcon, TRUE);
1941 goto end_error;
1942 }
1943
1944done:
1945 if(ustrModule.Buffer)
1946 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1947 return hCurIcon;
1948
1949end_error:
1950 if(ustrModule.Buffer)
1951 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1952 DeleteObject(cursorData.hbmMask);
1953 if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
1954 if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
1955
1956 return NULL;
1957}
1958
1959static
1960HBITMAP
1962 _In_ HBITMAP hnd,
1963 _In_ int desiredx,
1964 _In_ int desiredy,
1966)
1967{
1968 HBITMAP res = NULL;
1969 DIBSECTION ds;
1970 int objSize;
1971 BITMAPINFO * bi;
1972
1973 objSize = GetObjectW( hnd, sizeof(ds), &ds );
1974 if (!objSize) return 0;
1975 if ((desiredx < 0) || (desiredy < 0)) return 0;
1976
1978 {
1979 FIXME("The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
1980 }
1981
1982 if (flags & LR_COPYRETURNORG)
1983 {
1984 FIXME("The flag LR_COPYRETURNORG is not implemented for bitmaps\n");
1985 }
1986
1987 if (desiredx == 0) desiredx = ds.dsBm.bmWidth;
1988 if (desiredy == 0) desiredy = ds.dsBm.bmHeight;
1989
1990 /* Allocate memory for a BITMAPINFOHEADER structure and a
1991 color table. The maximum number of colors in a color table
1992 is 256 which corresponds to a bitmap with depth 8.
1993 Bitmaps with higher depths don't have color tables. */
1994 bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1995 if (!bi) return 0;
1996
1997 bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
1998 bi->bmiHeader.biPlanes = ds.dsBm.bmPlanes;
1999 bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
2001
2003 {
2004 /* Create a DIB section. LR_MONOCHROME is ignored */
2005 void * bits;
2007
2008 if (objSize == sizeof(DIBSECTION))
2009 {
2010 /* The source bitmap is a DIB.
2011 Get its attributes to create an exact copy */
2012 memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
2013 }
2014
2015 bi->bmiHeader.biWidth = desiredx;
2016 bi->bmiHeader.biHeight = desiredy;
2017
2018 /* Get the color table or the color masks */
2019 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
2020
2022 DeleteDC(dc);
2023 }
2024 else
2025 {
2026 /* Create a device-dependent bitmap */
2027
2028 BOOL monochrome = (flags & LR_MONOCHROME);
2029
2030 if (objSize == sizeof(DIBSECTION))
2031 {
2032 /* The source bitmap is a DIB section.
2033 Get its attributes */
2035 bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
2036 bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
2037 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
2038 DeleteDC(dc);
2039
2040 if (!monochrome && ds.dsBm.bmBitsPixel == 1)
2041 {
2042 /* Look if the colors of the DIB are black and white */
2043
2044 monochrome =
2045 (bi->bmiColors[0].rgbRed == 0xff
2046 && bi->bmiColors[0].rgbGreen == 0xff
2047 && bi->bmiColors[0].rgbBlue == 0xff
2048 && bi->bmiColors[0].rgbReserved == 0
2049 && bi->bmiColors[1].rgbRed == 0
2050 && bi->bmiColors[1].rgbGreen == 0
2051 && bi->bmiColors[1].rgbBlue == 0
2052 && bi->bmiColors[1].rgbReserved == 0)
2053 ||
2054 (bi->bmiColors[0].rgbRed == 0
2055 && bi->bmiColors[0].rgbGreen == 0
2056 && bi->bmiColors[0].rgbBlue == 0
2057 && bi->bmiColors[0].rgbReserved == 0
2058 && bi->bmiColors[1].rgbRed == 0xff
2059 && bi->bmiColors[1].rgbGreen == 0xff
2060 && bi->bmiColors[1].rgbBlue == 0xff
2061 && bi->bmiColors[1].rgbReserved == 0);
2062 }
2063 }
2064 else if (!monochrome)
2065 {
2066 monochrome = ds.dsBm.bmBitsPixel == 1;
2067 }
2068
2069 if (monochrome)
2070 {
2071 res = CreateBitmap(desiredx, desiredy, 1, 1, NULL);
2072 }
2073 else
2074 {
2075 HDC screenDC = GetDC(NULL);
2076 res = CreateCompatibleBitmap(screenDC, desiredx, desiredy);
2077 ReleaseDC(NULL, screenDC);
2078 }
2079 }
2080
2081 if (res)
2082 {
2083 /* Only copy the bitmap if it's a DIB section or if it's
2084 compatible to the screen */
2085 BOOL copyContents;
2086
2087 if (objSize == sizeof(DIBSECTION))
2088 {
2089 copyContents = TRUE;
2090 }
2091 else
2092 {
2093 HDC screenDC = GetDC(NULL);
2094 int screen_depth = GetDeviceCaps(screenDC, BITSPIXEL);
2095 ReleaseDC(NULL, screenDC);
2096
2097 copyContents = (ds.dsBm.bmBitsPixel == 1 || ds.dsBm.bmBitsPixel == screen_depth);
2098 }
2099
2100 if (copyContents)
2101 {
2102 /* The source bitmap may already be selected in a device context,
2103 use GetDIBits/StretchDIBits and not StretchBlt */
2104
2105 HDC dc;
2106 void * bits;
2107
2109
2110 bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
2111 bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
2112 bi->bmiHeader.biSizeImage = 0;
2113 bi->bmiHeader.biClrUsed = 0;
2114 bi->bmiHeader.biClrImportant = 0;
2115
2116 /* Fill in biSizeImage */
2117 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
2119
2120 if (bits)
2121 {
2122 HBITMAP oldBmp;
2123
2124 /* Get the image bits of the source bitmap */
2125 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
2126
2127 /* Copy it to the destination bitmap */
2128 oldBmp = SelectObject(dc, res);
2129 StretchDIBits(dc, 0, 0, desiredx, desiredy,
2130 0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight,
2132 SelectObject(dc, oldBmp);
2133
2135 }
2136
2137 DeleteDC(dc);
2138 }
2139
2140 if (flags & LR_COPYDELETEORG)
2141 {
2142 DeleteObject(hnd);
2143 }
2144 }
2145 HeapFree(GetProcessHeap(), 0, bi);
2146 return res;
2147}
2148
2149static
2150HICON
2152 _In_ HICON hicon,
2153 _In_ BOOL bIcon,
2154 _In_ int cxDesired,
2155 _In_ int cyDesired,
2156 _In_ UINT fuFlags
2157)
2158{
2159 HICON ret = NULL;
2160 ICONINFO ii;
2161 CURSORDATA CursorData;
2162
2163 if (fuFlags & LR_COPYFROMRESOURCE)
2164 {
2165 /* Get the icon module/resource names */
2166 UNICODE_STRING ustrModule;
2167 UNICODE_STRING ustrRsrc;
2169
2170 ustrModule.MaximumLength = 0;
2171 ustrRsrc.MaximumLength = 0;
2172
2173 /* Get the buffer size */
2174 if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
2175 {
2176 return NULL;
2177 }
2178
2179 ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength);
2180 if (!ustrModule.Buffer)
2181 {
2183 return NULL;
2184 }
2185
2186 if (ustrRsrc.MaximumLength)
2187 {
2188 ustrRsrc.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength);
2189 if (!ustrRsrc.Buffer)
2190 {
2191 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
2193 return NULL;
2194 }
2195 }
2196
2197 if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
2198 {
2199 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
2200 if (!IS_INTRESOURCE(ustrRsrc.Buffer))
2201 HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer);
2202 return NULL;
2203 }
2204
2205 /* NULL-terminate our strings */
2206 ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = UNICODE_NULL;
2207 if (!IS_INTRESOURCE(ustrRsrc.Buffer))
2208 ustrRsrc.Buffer[ustrRsrc.Length/sizeof(WCHAR)] = UNICODE_NULL;
2209
2210 TRACE("Got module %wZ, resource %p (%S).\n", &ustrModule,
2211 ustrRsrc.Buffer, IS_INTRESOURCE(ustrRsrc.Buffer) ? L"" : ustrRsrc.Buffer);
2212
2213 /* Get the module handle or load the module */
2214 hModule = LoadLibraryExW(ustrModule.Buffer, NULL, /* NT6+: LOAD_LIBRARY_AS_IMAGE_RESOURCE | */ LOAD_LIBRARY_AS_DATAFILE);
2215 if (!hModule)
2216 {
2218 ERR("Unable to load/use module '%wZ' in process %lu, error %lu.\n", &ustrModule, GetCurrentProcessId(), err);
2220 goto leave;
2221 }
2222
2223 /* Call the relevant function */
2225 hModule,
2226 ustrRsrc.Buffer,
2227 cxDesired,
2228 cyDesired,
2229 fuFlags & (LR_DEFAULTSIZE | LR_SHARED),
2230 bIcon);
2231
2233
2234 /* If we're here, that means that the passed icon is shared. Don't destroy it, even if LR_COPYDELETEORG is specified */
2235 leave:
2236 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
2237 if (!IS_INTRESOURCE(ustrRsrc.Buffer))
2238 HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer);
2239
2240 TRACE("Returning 0x%08x.\n", ret);
2241
2242 return ret;
2243 }
2244
2245 /* This is a regular copy */
2246 if (fuFlags & ~(LR_COPYDELETEORG | LR_SHARED))
2247 FIXME("Unimplemented flags: 0x%08x\n", fuFlags);
2248
2249 if (!GetIconInfo(hicon, &ii))
2250 {
2251 ERR("GetIconInfo failed.\n");
2252 return NULL;
2253 }
2254
2255 /* This is CreateIconIndirect with the LR_SHARED coat added */
2256 if (!CURSORICON_GetCursorDataFromIconInfo(&CursorData, &ii))
2257 goto Leave;
2258
2259 if (fuFlags & LR_SHARED)
2260 CursorData.CURSORF_flags |= CURSORF_LRSHARED;
2261
2263 if (!ret)
2264 goto Leave;
2265
2266 if (!NtUserSetCursorIconData(ret, NULL, NULL, &CursorData))
2267 {
2269 goto Leave;
2270 }
2271
2272Leave:
2274 if (ii.hbmColor) DeleteObject(ii.hbmColor);
2275
2276 if (ret && (fuFlags & LR_COPYDELETEORG))
2277 DestroyIcon(hicon);
2278
2279 return ret;
2280}
2281
2284{
2286 HANDLE Result;
2287 Common = (PCOPYIMAGE_CALLBACK_ARGUMENTS) Arguments;
2288
2289 Result = CopyImage(Common->hImage,
2290 Common->uType,
2291 Common->cxDesired,
2292 Common->cyDesired,
2293 Common->fuFlags);
2294
2295 return ZwCallbackReturn(&Result, sizeof(HANDLE), STATUS_SUCCESS);
2296}
2297
2298
2299/************* PUBLIC FUNCTIONS *******************/
2300
2301#define COPYIMAGE_VALID_FLAGS ( \
2302 LR_SHARED | LR_COPYFROMRESOURCE | LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS | 0x800 | \
2303 LR_VGACOLOR | LR_LOADREALSIZE | LR_DEFAULTSIZE | LR_LOADTRANSPARENT | LR_LOADFROMFILE | \
2304 LR_COPYDELETEORG | LR_COPYRETURNORG | LR_COLOR | LR_MONOCHROME \
2305)
2306
2308 _In_ HANDLE hImage,
2309 _In_ UINT uType,
2310 _In_ int cxDesired,
2311 _In_ int cyDesired,
2312 _In_ UINT fuFlags
2313)
2314{
2315 TRACE("hImage=%p, uType=%u, cxDesired=%d, cyDesired=%d, fuFlags=%x\n",
2316 hImage, uType, cxDesired, cyDesired, fuFlags);
2317
2318 if (fuFlags & ~COPYIMAGE_VALID_FLAGS)
2319 {
2321 return NULL;
2322 }
2323
2324 switch(uType)
2325 {
2326 case IMAGE_BITMAP:
2327 if (!hImage)
2328 {
2330 break;
2331 }
2332 return BITMAP_CopyImage(hImage, cxDesired, cyDesired, fuFlags);
2333 case IMAGE_CURSOR:
2334 case IMAGE_ICON:
2335 {
2336 HANDLE handle;
2337 if (!hImage)
2338 {
2340 break;
2341 }
2342 handle = CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, cxDesired, cyDesired, fuFlags);
2343 if (!handle && (fuFlags & LR_COPYFROMRESOURCE))
2344 {
2345 /* Test if the hImage is the same size as what we want by getting
2346 * its BITMAP and comparing its dimensions to the desired size. */
2347 BITMAP bm;
2348
2349 ICONINFO iconinfo = { 0 };
2350 if (!GetIconInfo(hImage, &iconinfo))
2351 {
2352 ERR("GetIconInfo Failed. hImage %p\n", hImage);
2353 return NULL;
2354 }
2355 if (!GetObject(iconinfo.hbmColor, sizeof(bm), &bm))
2356 {
2357 ERR("GetObject Failed. iconinfo %p\n", iconinfo);
2358 return NULL;
2359 }
2360
2361 DeleteObject(iconinfo.hbmMask);
2362 DeleteObject(iconinfo.hbmColor);
2363
2364 /* If the images are the same size remove LF_COPYFROMRESOURCE and try again */
2365 if (cxDesired == bm.bmWidth && cyDesired == bm.bmHeight)
2366 {
2367 handle = CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, cxDesired,
2368 cyDesired, (fuFlags & ~LR_COPYFROMRESOURCE));
2369 }
2370 }
2371 return handle;
2372 }
2373 default:
2375 break;
2376 }
2377 return NULL;
2378}
2379
2382)
2383{
2384 return CURSORICON_CopyImage(hIcon, FALSE, 0, 0, 0);
2385}
2386
2388 _In_ HDC hDC,
2389 _In_ int X,
2390 _In_ int Y,
2392)
2393{
2394 return DrawIconEx(hDC, X, Y, hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
2395}
2396
2398 _In_ HDC hdc,
2399 _In_ int xLeft,
2400 _In_ int yTop,
2402 _In_ int cxWidth,
2403 _In_ int cyWidth,
2404 _In_ UINT istepIfAniCur,
2405 _In_opt_ HBRUSH hbrFlickerFreeDraw,
2406 _In_ UINT diFlags
2407)
2408{
2409 return NtUserDrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth,
2410 istepIfAniCur, hbrFlickerFreeDraw, diFlags,
2411 0, 0);
2412}
2413
2416 _Out_ PICONINFO piconinfo
2417)
2418{
2419 return NtUserGetIconInfo(hIcon, piconinfo, NULL, NULL, NULL, FALSE);
2420}
2421
2424)
2425{
2427}
2428
2431 _In_ LPCSTR lpIconName
2432)
2433{
2434 TRACE("%p, %s\n", hInstance, debugstr_a(lpIconName));
2435
2436 return LoadImageA(hInstance,
2437 lpIconName,
2438 IMAGE_ICON,
2439 0,
2440 0,
2442}
2443
2446 _In_ LPCWSTR lpIconName
2447)
2448{
2449 TRACE("%p, %s\n", hInstance, debugstr_w(lpIconName));
2450
2451 return LoadImageW(hInstance,
2452 lpIconName,
2453 IMAGE_ICON,
2454 0,
2455 0,
2457}
2458
2461 _In_ LPCSTR lpCursorName
2462)
2463{
2464 TRACE("%p, %s\n", hInstance, debugstr_a(lpCursorName));
2465
2466 return LoadImageA(hInstance,
2467 lpCursorName,
2469 0,
2470 0,
2472}
2473
2476 _In_ LPCWSTR lpCursorName
2477)
2478{
2479 TRACE("%p, %s\n", hInstance, debugstr_w(lpCursorName));
2480
2481 return LoadImageW(hInstance,
2482 lpCursorName,
2484 0,
2485 0,
2487}
2488
2491)
2492{
2493 TRACE("%s\n", debugstr_a(lpFileName));
2494
2495 return LoadImageA(NULL,
2496 lpFileName,
2498 0,
2499 0,
2501}
2502
2505)
2506{
2507 TRACE("%s\n", debugstr_w(lpFileName));
2508
2509 return LoadImageW(NULL,
2510 lpFileName,
2512 0,
2513 0,
2515}
2516
2519 _In_ LPCSTR lpBitmapName
2520)
2521{
2522 TRACE("%p, %s\n", hInstance, debugstr_a(lpBitmapName));
2523
2524 return LoadImageA(hInstance,
2525 lpBitmapName,
2527 0,
2528 0,
2529 0);
2530}
2531
2534 _In_ LPCWSTR lpBitmapName
2535)
2536{
2537 TRACE("%p, %s\n", hInstance, debugstr_w(lpBitmapName));
2538
2539 return LoadImageW(hInstance,
2540 lpBitmapName,
2542 0,
2543 0,
2544 0);
2545}
2546
2549 _In_ LPCSTR lpszName,
2550 _In_ UINT uType,
2551 _In_ int cxDesired,
2552 _In_ int cyDesired,
2553 _In_ UINT fuLoad
2554)
2555{
2556 HANDLE res;
2557 LPWSTR u_name;
2558 DWORD len;
2559
2560 if (IS_INTRESOURCE(lpszName))
2561 return LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired, cyDesired, fuLoad);
2562
2563 len = MultiByteToWideChar( CP_ACP, 0, lpszName, -1, NULL, 0 );
2564 u_name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2565 MultiByteToWideChar( CP_ACP, 0, lpszName, -1, u_name, len );
2566
2567 res = LoadImageW(hinst, u_name, uType, cxDesired, cyDesired, fuLoad);
2568 HeapFree(GetProcessHeap(), 0, u_name);
2569 return res;
2570}
2571
2574 _In_ LPCWSTR lpszName,
2575 _In_ UINT uType,
2576 _In_ int cxDesired,
2577 _In_ int cyDesired,
2578 _In_ UINT fuLoad
2579)
2580{
2581 TRACE("hinst 0x%p, name %s, uType 0x%08x, cxDesired %d, cyDesired %d, fuLoad 0x%08x.\n",
2582 hinst, debugstr_w(lpszName), uType, cxDesired, cyDesired, fuLoad);
2583 /* Redirect to each implementation */
2584 switch(uType)
2585 {
2586 case IMAGE_BITMAP:
2587 return BITMAP_LoadImageW(hinst, lpszName, cxDesired, cyDesired, fuLoad);
2588 case IMAGE_CURSOR:
2589 case IMAGE_ICON:
2590 return CURSORICON_LoadImageW(hinst, lpszName, cxDesired, cyDesired, fuLoad, uType == IMAGE_ICON);
2591 default:
2593 break;
2594 }
2595 return NULL;
2596}
2597
2599 _In_ PBYTE presbits,
2600 _In_ BOOL fIcon
2601)
2602{
2603 return LookupIconIdFromDirectoryEx( presbits, fIcon,
2606}
2607
2609 _In_ PBYTE presbits,
2610 _In_ BOOL fIcon,
2611 _In_ int cxDesired,
2612 _In_ int cyDesired,
2614)
2615{
2616 WORD bppDesired;
2617 CURSORICONDIR* dir = (CURSORICONDIR*)presbits;
2619 int i, numMatch = 0, iIndex = -1;
2620 WORD width, height, BitCount = 0;
2621 BOOL notPaletted = FALSE;
2622 ULONG bestScore = 0xFFFFFFFF, score;
2623
2624 TRACE("%p, %x, %i, %i, %x.\n", presbits, fIcon, cxDesired, cyDesired, Flags);
2625
2626 if(!(dir && !dir->idReserved && (dir->idType & 3)))
2627 {
2628 WARN("Invalid resource.\n");
2629 return 0;
2630 }
2631
2632 if(Flags & LR_MONOCHROME)
2633 bppDesired = 1;
2634 else
2635 {
2636 HDC icScreen;
2637 icScreen = CreateICW(DISPLAYW, NULL, NULL, NULL);
2638 if(!icScreen)
2639 return FALSE;
2640
2641 bppDesired = GetDeviceCaps(icScreen, BITSPIXEL);
2642 DeleteDC(icScreen);
2643 }
2644
2645 if(!cxDesired)
2646 cxDesired = Flags & LR_DEFAULTSIZE ? GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR) : 256;
2647 if(!cyDesired)
2648 cyDesired = Flags & LR_DEFAULTSIZE ? GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR) : 256;
2649
2650 /* Find the best match for the desired size */
2651 for(i = 0; i < dir->idCount; i++)
2652 {
2653 entry = &dir->idEntries[i];
2654 width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2655 /* Height is twice as big in cursor resources */
2656 height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2657 /* 0 represents 256 */
2658 if(!width) width = 256;
2659 if(!height) height = 256;
2660 /* Calculate the "score" (lower is better) */
2661 score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2662 if( score > bestScore)
2663 continue;
2664 /* Bigger than requested lowers the score */
2665 if(width > cxDesired)
2666 score -= width - cxDesired;
2667 if(height > cyDesired)
2668 score -= height - cyDesired;
2669 if(score > bestScore)
2670 continue;
2671 if(score == bestScore)
2672 {
2673 if(entry->wBitCount > BitCount)
2674 BitCount = entry->wBitCount;
2675 numMatch++;
2676 continue;
2677 }
2678 iIndex = i;
2679 numMatch = 1;
2680 bestScore = score;
2681 BitCount = entry->wBitCount;
2682 }
2683
2684 if(numMatch == 1)
2685 {
2686 /* Only one entry fits the asked dimensions */
2687 return dir->idEntries[iIndex].wResId;
2688 }
2689
2690 /* Avoid paletted icons on non-paletted device */
2691 if (bppDesired > 8 && BitCount > 8)
2692 notPaletted = TRUE;
2693
2694 BitCount = 0;
2695 iIndex = -1;
2696 /* Now find the entry with the best depth */
2697 for(i = 0; i < dir->idCount; i++)
2698 {
2699 entry = &dir->idEntries[i];
2700 width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2701 height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2702 /* 0 represents 256 */
2703 if(!width) width = 256;
2704 if(!height) height = 256;
2705 /* Check if this is the best match we had */
2706 score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2707 if(width > cxDesired)
2708 score -= width - cxDesired;
2709 if(height > cyDesired)
2710 score -= height - cyDesired;
2711 if(score != bestScore)
2712 continue;
2713 /* Exact match? */
2714 if(entry->wBitCount == bppDesired)
2715 return entry->wResId;
2716 /* We take the highest possible but smaller than the display depth */
2717 if((entry->wBitCount > BitCount) && (entry->wBitCount < bppDesired))
2718 {
2719 /* Avoid paletted icons on non paletted devices */
2720 if ((entry->wBitCount <= 8) && notPaletted)
2721 continue;
2722 iIndex = i;
2723 BitCount = entry->wBitCount;
2724 }
2725 }
2726
2727 if(iIndex >= 0)
2728 return dir->idEntries[iIndex].wResId;
2729
2730 /* No inferior or equal depth available. Get the smallest bigger one */
2731 BitCount = 0xFFFF;
2732 iIndex = -1;
2733 for(i = 0; i < dir->idCount; i++)
2734 {
2735 entry = &dir->idEntries[i];
2736 width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2737 height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2738 /* 0 represents 256 */
2739 if(!width) width = 256;
2740 if(!height) height = 256;
2741 /* Check if this is the best match we had */
2742 score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2743 if(width > cxDesired)
2744 score -= width - cxDesired;
2745 if(height > cyDesired)
2746 score -= height - cyDesired;
2747 if(score != bestScore)
2748 continue;
2749 /* Check the bit depth */
2750 if(entry->wBitCount < BitCount)
2751 {
2752 if((entry->wBitCount <= 8) && notPaletted)
2753 continue;
2754 iIndex = i;
2755 BitCount = entry->wBitCount;
2756 }
2757 }
2758 if (iIndex >= 0)
2759 return dir->idEntries[iIndex].wResId;
2760
2761 return 0;
2762}
2763
2766 _In_ int nWidth,
2767 _In_ int nHeight,
2768 _In_ BYTE cPlanes,
2769 _In_ BYTE cBitsPixel,
2770 _In_ const BYTE *lpbANDbits,
2771 _In_ const BYTE *lpbXORbits
2772)
2773{
2774 ICONINFO iinfo;
2775 HICON hIcon;
2776
2777 TRACE_(icon)("%dx%d, planes %d, bpp %d, xor %p, and %p\n",
2778 nWidth, nHeight, cPlanes, cBitsPixel, lpbXORbits, lpbANDbits);
2779
2780 iinfo.fIcon = TRUE;
2781 iinfo.xHotspot = nWidth / 2;
2782 iinfo.yHotspot = nHeight / 2;
2783 if (cPlanes * cBitsPixel > 1)
2784 {
2785 iinfo.hbmColor = CreateBitmap( nWidth, nHeight, cPlanes, cBitsPixel, lpbXORbits );
2786 iinfo.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, lpbANDbits );
2787 }
2788 else
2789 {
2790 iinfo.hbmMask = CreateBitmap( nWidth, nHeight * 2, 1, 1, lpbANDbits );
2791 iinfo.hbmColor = NULL;
2792 }
2793
2794 hIcon = CreateIconIndirect( &iinfo );
2795
2796 DeleteObject( iinfo.hbmMask );
2797 if (iinfo.hbmColor) DeleteObject( iinfo.hbmColor );
2798
2799 return hIcon;
2800}
2801
2803 _In_ PBYTE presbits,
2804 _In_ DWORD dwResSize,
2805 _In_ BOOL fIcon,
2806 _In_ DWORD dwVer
2807)
2808{
2809 return CreateIconFromResourceEx( presbits, dwResSize, fIcon, dwVer, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
2810}
2811
2813 _In_ PBYTE pbIconBits,
2814 _In_ DWORD cbIconBits,
2815 _In_ BOOL fIcon,
2817 _In_ int cxDesired,
2818 _In_ int cyDesired,
2820)
2821{
2822 CURSORDATA cursorData;
2823 HICON hIcon;
2824 BOOL isAnimated;
2825 PBYTE pbBmpIcon = NULL;
2826 DWORD BmpIconSize;
2827
2828 TRACE("%p, %lu, %lu, %lu, %i, %i, %lu.\n", pbIconBits, cbIconBits, fIcon, dwVersion, cxDesired, cyDesired, uFlags);
2829
2830 if (!pbIconBits || cbIconBits < 2 * sizeof(DWORD))
2831 {
2832 ERR("Invalid IconBits array\n");
2833 return NULL;
2834 }
2835
2837 {
2838 if(!cxDesired) cxDesired = GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR);
2839 if(!cyDesired) cyDesired = GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR);
2840 }
2841
2842 ZeroMemory(&cursorData, sizeof(cursorData));
2843 cursorData.cx = cxDesired;
2844 cursorData.cy = cyDesired;
2845 cursorData.rt = LOWORD(fIcon ? RT_ICON : RT_CURSOR);
2846
2847 /* Convert to win32k-ready data */
2848 if(!memcmp(pbIconBits, "RIFF", 4))
2849 {
2850 if(!CURSORICON_GetCursorDataFromANI(&cursorData, pbIconBits, cbIconBits, uFlags))
2851 {
2852 ERR("Could not get cursor data from .ani.\n");
2853 return NULL;
2854 }
2855 isAnimated = !!(cursorData.CURSORF_flags & CURSORF_ACON);
2856 }
2857 else
2858 {
2859 /* It is possible to pass Icon Directories to this API */
2860 int wResId = LookupIconIdFromDirectoryEx(pbIconBits, fIcon, cxDesired, cyDesired, uFlags);
2861 HANDLE ResHandle = NULL;
2862#ifdef __REACTOS__
2863 if (wResId && (pbIconBits[4] != sizeof(BITMAPINFOHEADER)))
2864#else
2865 if(wResId)
2866#endif
2867 {
2869 HRSRC hrsrc;
2870 CURSORICONDIR* pCurIconDir = (CURSORICONDIR*)pbIconBits;
2871
2872 TRACE("Pointer points to a directory structure.\n");
2873
2874 /* So this is a pointer to an icon directory structure. Find the module */
2875 if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
2876 (LPCWSTR)pbIconBits,
2877 &hinst))
2878 {
2879 return NULL;
2880 }
2881
2882 /* Check we were given the right type of resource */
2883 if((fIcon && pCurIconDir->idType == 2) || (!fIcon && pCurIconDir->idType == 1))
2884 {
2885 WARN("Got a %s directory pointer, but called for a %s\n", fIcon ? "cursor" : "icon", fIcon ? "icon" : "cursor");
2886 return NULL;
2887 }
2888
2889 /* Get the relevant resource pointer */
2890 hrsrc = FindResourceW(
2891 hinst,
2892 MAKEINTRESOURCEW(wResId),
2893 fIcon ? RT_ICON : RT_CURSOR);
2894 if (!hrsrc)
2895 return NULL;
2896
2897 ResHandle = LoadResource(hinst, hrsrc);
2898 if (!ResHandle)
2899 return NULL;
2900
2901 pbIconBits = LockResource(ResHandle);
2902 if (!pbIconBits)
2903 {
2904 FreeResource(ResHandle);
2905 return NULL;
2906 }
2907 }
2908 if(!fIcon)
2909 {
2910 WORD* pt = (WORD*)pbIconBits;
2911 cursorData.xHotspot = *pt++;
2912 cursorData.yHotspot = *pt++;
2913 pbIconBits = (PBYTE)pt;
2914 }
2915
2916 isAnimated = FALSE;
2917
2918 /* Try to load BMP icon */
2919 if (!CURSORICON_GetCursorDataFromBMI(&cursorData, (PBITMAPINFO)pbIconBits))
2920 {
2921 /* Convert PNG raw data to BMP icon if the icon was PNG icon */
2922 pbBmpIcon = CURSORICON_ConvertPngToBmpIcon(pbIconBits, cbIconBits, &BmpIconSize);
2923 if (!pbBmpIcon)
2924 return NULL; /* Not PNG icon or failed */
2925
2926 /* Find icon entry from BMP icon */
2927 CURSORICONFILEDIR *dir = (CURSORICONFILEDIR *)pbBmpIcon;
2928 CURSORICONFILEDIRENTRY *entry = &dir->idEntries[0]; /* Only one entry */
2929
2930 /* A bit of preparation */
2931 RtlZeroMemory(&cursorData, sizeof(cursorData));
2932 cursorData.rt = LOWORD(fIcon ? RT_ICON : RT_CURSOR);
2933
2934 /* Can we load this BMP icon? */
2935 if (!CURSORICON_GetCursorDataFromBMI(&cursorData, (PBITMAPINFO)&pbBmpIcon[entry->dwDIBOffset]))
2936 {
2937 ERR("Couldn't get cursor/icon data\n");
2938 goto end_error;
2939 }
2940 }
2941 }
2942
2943 if (uFlags & LR_SHARED)
2944 cursorData.CURSORF_flags |= CURSORF_LRSHARED;
2945
2946 hIcon = NtUserxCreateEmptyCurObject(isAnimated);
2947 if (!hIcon)
2948 goto end_error;
2949
2950 if(!NtUserSetCursorIconData(hIcon, NULL, NULL, &cursorData))
2951 {
2952 ERR("NtUserSetCursorIconData failed.\n");
2954 goto end_error;
2955 }
2956
2957 if(isAnimated)
2958 HeapFree(GetProcessHeap(), 0, cursorData.aspcur);
2959
2960 HeapFree(GetProcessHeap(), 0, pbBmpIcon);
2961 return hIcon;
2962
2963 /* Clean up */
2964end_error:
2965 HeapFree(GetProcessHeap(), 0, pbBmpIcon);
2966 if(isAnimated)
2967 HeapFree(GetProcessHeap(), 0, cursorData.aspcur);
2968 if (cursorData.hbmMask) DeleteObject(cursorData.hbmMask);
2969 if (cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
2970 if (cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
2971
2972 return NULL;
2973}
2974
2976 _In_ PICONINFO piconinfo
2977)
2978{
2979 /* As simple as creating a handle, and let win32k deal with the bitmaps */
2980 HICON hiconRet;
2981 CURSORDATA cursorData;
2982
2983 TRACE("%p.\n", piconinfo);
2984
2985 ZeroMemory(&cursorData, sizeof(cursorData));
2986
2987 if(!CURSORICON_GetCursorDataFromIconInfo(&cursorData, piconinfo))
2988 return NULL;
2989
2991 if(!hiconRet)
2992 goto end_error;
2993
2994 if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, &cursorData))
2995 {
2996 NtUserDestroyCursor(hiconRet, FALSE);
2997 goto end_error;
2998 }
2999
3000 TRACE("Returning 0x%08x.\n", hiconRet);
3001
3002 return hiconRet;
3003
3004end_error:
3005 /* Clean up */
3006 DeleteObject(cursorData.hbmMask);
3007 if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
3008 if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
3009
3010 return NULL;
3011}
3012
3015 _In_ int xHotSpot,
3016 _In_ int yHotSpot,
3017 _In_ int nWidth,
3018 _In_ int nHeight,
3019 _In_ const VOID *pvANDPlane,
3020 _In_ const VOID *pvXORPlane
3021)
3022{
3023 ICONINFO info;
3024 HCURSOR hCursor;
3025
3026 TRACE_(cursor)("%dx%d spot=%d,%d xor=%p and=%p\n",
3027 nWidth, nHeight, xHotSpot, yHotSpot, pvXORPlane, pvANDPlane);
3028
3029 info.fIcon = FALSE;
3030 info.xHotspot = xHotSpot;
3031 info.yHotspot = yHotSpot;
3032 info.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, pvANDPlane );
3033 info.hbmColor = CreateBitmap( nWidth, nHeight, 1, 1, pvXORPlane );
3034 hCursor = CreateIconIndirect( &info );
3035 DeleteObject( info.hbmMask );
3036 DeleteObject( info.hbmColor );
3037 return hCursor;
3038}
3039
3041 _In_ HCURSOR hcur,
3042 _In_ DWORD id
3043)
3044{
3045 if (hcur == NULL)
3046 {
3048 if (hcur == NULL)
3049 {
3050 return FALSE;
3051 }
3052 }
3053 return NtUserSetSystemCursor(hcur,id);
3054}
3055
3057 _In_ int X,
3058 _In_ int Y
3059)
3060{
3061 return NtUserxSetCursorPos(X,Y);
3062}
3063
3065 _Out_ LPPOINT lpPoint
3066)
3067{
3068 return NtUserxGetCursorPos(lpPoint);
3069}
3070
3072 _In_ BOOL bShow
3073)
3074{
3075 return NtUserxShowCursor(bShow);
3076}
3077
3079{
3081}
3082
3084 _In_ HCURSOR hCursor
3085)
3086{
3087 return NtUserDestroyCursor(hCursor, FALSE);
3088}
3089
3090HCURSOR
3091WINAPI
3092GetCursorFrameInfo(HCURSOR hCursor, DWORD reserved, DWORD istep, PINT rate_jiffies, DWORD *num_steps)
3093{
3094 return NtUserGetCursorFrameInfo(hCursor, istep, rate_jiffies, num_steps);
3095}
static HDC hDC
Definition: 3dtext.c:33
static int state
Definition: maze.c:121
unsigned int dir
Definition: maze.c:112
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
#define leave
Definition: btrfs_drv.h:138
HINSTANCE hInstance
Definition: charmap.c:19
HDC dc
Definition: cylfrac.c:34
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
DWORD bpp
Definition: surface.c:185
#define Y(I)
UINT uFlags
Definition: api.c:59
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define PAGE_READONLY
Definition: compat.h:138
#define UnmapViewOfFile
Definition: compat.h:746
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define TRACE_(x)
Definition: compat.h:76
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:744
#define FreeLibrary(x)
Definition: compat.h:748
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CreateFileW
Definition: compat.h:741
#define FILE_MAP_READ
Definition: compat.h:776
#define WINE_DECLARE_DEBUG_CHANNEL(x)
Definition: compat.h:45
#define MapViewOfFile
Definition: compat.h:745
#define MultiByteToWideChar
Definition: compat.h:110
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const BYTE png_sig_pattern[]
Definition: image.c:4818
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
BOOL WINAPI FreeResource(HGLOBAL handle)
Definition: res.c:559
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
#define IS_INTRESOURCE(x)
Definition: loader.c:613
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define pt(x, y)
Definition: drawing.c:79
#define BI_RGB
Definition: precomp.h:44
#define RGB(r, g, b)
Definition: precomp.h:67
#define GetBValue(quad)
Definition: precomp.h:71
#define GetGValue(quad)
Definition: precomp.h:70
ULONG RGBQUAD
Definition: precomp.h:47
#define GetRValue(quad)
Definition: precomp.h:69
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
r reserved
Definition: btrfs.c:3006
HINSTANCE hInst
Definition: dxdiag.c:13
#define abs(i)
Definition: fconv.c:206
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
pKey DeleteObject()
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei imageSize
Definition: gl.h:1950
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLsizeiptr size
Definition: glext.h:5919
GLuint color
Definition: glext.h:6243
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
FxContextHeader * pHeader
Definition: handleapi.cpp:604
#define ds
Definition: i386-dis.c:443
const char cursor[]
Definition: icontest.c:13
PSERVERINFO gpsi
Definition: imm.c:18
#define CURSORF_LRSHARED
Definition: ntuser.h:1201
@ THREADSTATE_GETCURSOR
Definition: ntuser.h:2495
#define CURSORF_FROMRESOURCE
Definition: ntuser.h:1199
DWORD_PTR NTAPI NtUserGetThreadState(DWORD Routine)
Definition: misc.c:240
#define CURSORF_ACONFRAME
Definition: ntuser.h:1204
#define CURSORF_ACON
Definition: ntuser.h:1202
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:603
#define bits
Definition: infblock.c:15
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define LDR_IS_RESOURCE(handle)
Definition: ldrtypes.h:109
HANDLE hbmpOld
Definition: magnifier.c:54
#define ZeroMemory
Definition: minwinbase.h:31
#define CopyMemory
Definition: minwinbase.h:29
int * PINT
Definition: minwindef.h:150
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define BI_BITFIELDS
Definition: mmreg.h:507
#define FILE_FLAG_RANDOM_ACCESS
Definition: disk.h:44
static PVOID ptr
Definition: dispmode.c:27
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HINSTANCE hinst
Definition: edit.c:551
static HDC
Definition: imagelist.c:88
static HICON
Definition: imagelist.c:80
static const BYTE masks[8]
Definition: dib.c:2760
#define PNG_COLOR_TYPE_GRAY_ALPHA
Definition: image.c:5167
#define PNG_COLOR_TYPE_GRAY
Definition: image.c:5164
#define PNG_COLOR_TYPE_PALETTE
Definition: image.c:5166
static PROTOCOLDATA * pdata
Definition: protocol.c:158
static HBITMAP create_bitmap(void)
Definition: clipboard.c:530
#define ANI_FLAG_SEQUENCE
Definition: cursoricon.c:70
#define ANI_fram_ID
Definition: cursoricon.c:65
#define ANI_RIFF_ID
Definition: cursoricon.c:60
#define ANI_LIST_ID
Definition: cursoricon.c:61
#define ANI_ACON_ID
Definition: cursoricon.c:62
#define ANI_FLAG_ICON
Definition: cursoricon.c:69
#define ANI_anih_ID
Definition: cursoricon.c:63
static DWORD DWORD istep
Definition: cursoricon.c:1638
#define ANI_seq__ID
Definition: cursoricon.c:64
#define ANI_rate_ID
Definition: cursoricon.c:67
DWORD dwFileSize
Definition: more.c:40
HICON hIcon
Definition: msconfig.c:44
_In_ HANDLE hFile
Definition: mswsock.h:90
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI NTSTATUS NTAPI ZwCallbackReturn(_In_ PVOID Result, _In_ ULONG ResultLength, _In_ NTSTATUS Status)
HMODULE hModule
Definition: netsh.c:17
_In_ DWORD dwVersion
Definition: netsh.h:85
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define DWORD
Definition: nt_native.h:44
#define UNICODE_NULL
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2033
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO pbmi
Definition: ntgdi.h:2780
EXTINLINE BOOL NtUserxSetCursorPos(INT x, INT y)
Definition: ntwrapper.h:676
EXTINLINE BOOL NtUserxGetCursorPos(POINT *lpPoint)
Definition: ntwrapper.h:811
EXTINLINE HICON NtUserxCreateEmptyCurObject(DWORD_PTR Param)
Definition: ntwrapper.h:616
EXTINLINE INT NtUserxShowCursor(BOOL bShow)
Definition: ntwrapper.h:606
#define LOWORD(l)
Definition: pedump.c:82
#define RT_BITMAP
Definition: pedump.c:364
BYTE * PBYTE
Definition: pedump.c:66
DWORD * PDWORD
Definition: pedump.c:68
#define RT_ICON
Definition: pedump.c:365
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
#define RT_GROUP_CURSOR
Definition: pedump.c:374
unsigned short USHORT
Definition: pedump.c:61
#define RT_GROUP_ICON
Definition: pedump.c:375
#define RT_CURSOR
Definition: pedump.c:363
png_voidp PNGAPI png_get_io_ptr(png_const_structrp png_ptr)
Definition: png.c:686
png_structrp png_ptr
Definition: png.h:1080
png_uint_32
Definition: png.h:1936
#define png_check_sig(sig, n)
Definition: png.h:916
#define PNG_LIBPNG_VER_STRING
Definition: png.h:281
png_const_structrp png_const_inforp info_ptr
Definition: png.h:1937
png_byte * png_bytep
Definition: pngconf.h:579
png_byte ** png_bytepp
Definition: pngconf.h:606
int This channels
Definition: rdpsnd_libao.c:37
#define err(...)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE(s)
Definition: solgame.cpp:4
union CURSORICONDIRENTRY::@5417 ResInfo
ICONRESDIR icon
Definition: ntusrtyp.h:88
DWORD dwBytesInRes
Definition: ntusrtyp.h:93
CURSORRESDIR cursor
Definition: ntusrtyp.h:89
WORD idReserved
Definition: ntusrtyp.h:99
CURSORICONDIRENTRY idEntries[1]
Definition: ntusrtyp.h:102
WORD idCount
Definition: ntusrtyp.h:101
CURSORICONFILEDIRENTRY idEntries[1]
Definition: olepicture.c:100
WORD wWidth
Definition: ntusrtyp.h:69
WORD wHeight
Definition: ntusrtyp.h:70
BYTE bReserved
Definition: ntusrtyp.h:64
BYTE bColorCount
Definition: ntusrtyp.h:63
BYTE bHeight
Definition: ntusrtyp.h:62
BYTE bWidth
Definition: ntusrtyp.h:61
CURSORICONFILEDIRENTRY idEntries[1]
Definition: cursoricon.c:43
DWORD yHotspot
Definition: winuser.h:3227
BOOL fIcon
Definition: winuser.h:3225
DWORD xHotspot
Definition: winuser.h:3226
HBITMAP hbmColor
Definition: winuser.h:3229
HBITMAP hbmMask
Definition: winuser.h:3228
png_bytep buffer
Definition: cursoricon.c:52
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: name.c:39
const unsigned char * data
Definition: cursoricon.c:1117
DWORD data_size
Definition: cursoricon.c:1116
ULONG biClrImportant
Definition: precomp.h:40
USHORT biBitCount
Definition: precomp.h:34
ULONG biCompression
Definition: precomp.h:35
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1922
RGBQUAD bmiColors[1]
Definition: wingdi.h:1923
LONG bmHeight
Definition: wingdi.h:1869
LONG bmWidth
Definition: wingdi.h:1868
WORD bmBitsPixel
Definition: wingdi.h:1872
HBITMAP hbmMask
Definition: ntuser.h:1182
ULONG CURSORF_flags
Definition: ntuser.h:1179
ULONG cy
Definition: ntuser.h:1189
ULONG cx
Definition: ntuser.h:1188
HBITMAP hbmColor
Definition: ntuser.h:1183
HBITMAP hbmAlpha
Definition: ntuser.h:1184
SHORT xHotspot
Definition: ntuser.h:1180
USHORT rt
Definition: ntuser.h:1177
struct tagCURSORDATA * aspcur
Definition: ntuser.h:1192
SHORT yHotspot
Definition: ntuser.h:1181
UCHAR rgbReserved
Definition: bootanim.c:106
UCHAR rgbBlue
Definition: bootanim.c:103
UCHAR rgbRed
Definition: bootanim.c:105
UCHAR rgbGreen
Definition: bootanim.c:104
BYTE rgbtBlue
Definition: wingdi.h:1884
#define max(a, b)
Definition: svc.c:63
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
HINSTANCE User32Instance
Definition: dllmain.c:27
static int __cdecl compr(const void *a, const void *b)
Definition: bidi.c:641
HDC hdcMem
Definition: welcome.c:104
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:245
struct _COPYIMAGE_CALLBACK_ARGUMENTS * PCOPYIMAGE_CALLBACK_ARGUMENTS
BOOL APIENTRY NtUserDrawIconEx(HDC hdc, int xLeft, int yTop, HICON hIcon, int cxWidth, int cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags, BOOL bMetaHDC, PVOID pDIXData)
Definition: cursoricon.c:2086
BOOL APIENTRY NtUserGetIconSize(HANDLE hCurIcon, UINT istepIfAniCur, PLONG plcx, PLONG plcy)
Definition: cursoricon.c:590
HICON NTAPI NtUserFindExistingCursorIcon(_In_ PUNICODE_STRING pustrModule, _In_ PUNICODE_STRING pustrRsrc, _In_ FINDEXISTINGCURICONPARAM *param)
Definition: cursoricon.c:863
BOOL APIENTRY NtUserDestroyCursor(_In_ HANDLE hCurIcon, _In_ BOOL bForce)
Definition: cursoricon.c:795
__kernel_entry BOOL APIENTRY NtUserSetCursorIconData(_In_ HCURSOR hcursor, _In_opt_ PUNICODE_STRING pustrModule, _In_opt_ PUNICODE_STRING pustrRsrc, _In_ const CURSORDATA *pCursorData)
Definition: cursoricon.c:1512
BOOL APIENTRY NtUserSetSystemCursor(HCURSOR hcur, DWORD id)
Definition: cursoricon.c:2203
HCURSOR NTAPI NtUserGetCursorFrameInfo(HCURSOR hCursor, DWORD istep, INT *rate_jiffies, DWORD *num_steps)
Definition: cursoricon.c:2133
static int bitmap_info_size(const BITMAPINFO *info, WORD coloruse)
Definition: cursoricon.c:423
HCURSOR WINAPI CreateCursor(_In_opt_ HINSTANCE hInst, _In_ int xHotSpot, _In_ int yHotSpot, _In_ int nWidth, _In_ int nHeight, _In_ const VOID *pvANDPlane, _In_ const VOID *pvXORPlane)
Definition: cursoricon.c:3013
#define IDI_SHIELD
HBITMAP WINAPI LoadBitmapW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpBitmapName)
Definition: cursoricon.c:2532
HANDLE WINAPI LoadImageW(_In_opt_ HINSTANCE hinst, _In_ LPCWSTR lpszName, _In_ UINT uType, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuLoad)
Definition: cursoricon.c:2572
#define EOFM
HCURSOR WINAPI LoadCursorFromFileW(_In_ LPCWSTR lpFileName)
Definition: cursoricon.c:2503
static BOOL CURSORICON_GetCursorDataFromIconInfo(_Out_ CURSORDATA *pCursorData, _In_ ICONINFO *pIconInfo)
Definition: cursoricon.c:1005
BOOL WINAPI GetCursorPos(_Out_ LPPOINT lpPoint)
Definition: cursoricon.c:3064
static BOOL CURSORICON_GetCursorDataFromBMI(_Inout_ CURSORDATA *pdata, _In_ const BITMAPINFO *pbmi)
Definition: cursoricon.c:855
#define LF
static void * map_fileW(LPCWSTR name, LPDWORD filesize)
Definition: cursoricon.c:338
BOOL WINAPI SetSystemCursor(_In_ HCURSOR hcur, _In_ DWORD id)
Definition: cursoricon.c:3040
BOOL get_icon_size(HICON hIcon, SIZE *size)
Definition: cursoricon.c:323
static void riff_find_chunk(DWORD chunk_id, DWORD chunk_type, const riff_chunk_t *parent_chunk, riff_chunk_t *chunk)
Definition: cursoricon.c:1135
HCURSOR WINAPI LoadCursorFromFileA(_In_ LPCSTR lpFileName)
Definition: cursoricon.c:2489
HCURSOR CursorIconToCursor(HICON hIcon, BOOL SemiTransparent)
Definition: cursoricon.c:328
NTSTATUS WINAPI User32SetupDefaultCursors(PVOID Arguments, ULONG ArgumentLength)
Definition: cursoricon.c:297
DWORD get_best_icon_file_offset(_In_ const LPBYTE dir, _In_ DWORD dwFileSize, _In_ int cxDesired, _In_ int cyDesired, _In_ BOOL bIcon, _In_ DWORD fuLoad, _Out_ POINT *ptHotSpot)
Definition: cursoricon.c:825
static int get_dib_image_size(int width, int height, int depth)
Definition: cursoricon.c:360
int WINAPI LookupIconIdFromDirectory(_In_ PBYTE presbits, _In_ BOOL fIcon)
Definition: cursoricon.c:2598
#define COPYIMAGE_VALID_FLAGS
Definition: cursoricon.c:2301
static BOOL bmi_has_alpha(const BITMAPINFO *info, const void *bits)
Definition: cursoricon.c:549
HICON WINAPI CreateIconFromResourceEx(_In_ PBYTE pbIconBits, _In_ DWORD cbIconBits, _In_ BOOL fIcon, _In_ DWORD dwVersion, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT uFlags)
Definition: cursoricon.c:2812
static BOOL CURSORICON_GetCursorDataFromANI(_Inout_ CURSORDATA *pCurData, _In_ const BYTE *pData, _In_ DWORD dwDataSize, _In_ DWORD fuLoad)
Definition: cursoricon.c:1162
#define PNG_CHECK_SIG_SIZE
Definition: cursoricon.c:47
BOOL WINAPI SetCursorPos(_In_ int X, _In_ int Y)
Definition: cursoricon.c:3056
#define CR
static void stretch_blt_icon(HDC hdc_dst, int dst_width, int dst_height, HBITMAP src)
Definition: cursoricon.c:502
static HANDLE CURSORICON_LoadImageW(_In_opt_ HINSTANCE hinst, _In_ LPCWSTR lpszName, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuLoad, _In_ BOOL bIcon)
Definition: cursoricon.c:1725
static HBITMAP BITMAP_LoadImageW(_In_opt_ HINSTANCE hinst, _In_ LPCWSTR lpszName, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuLoad)
Definition: cursoricon.c:1339
static HBITMAP create_alpha_bitmap(_In_opt_ HBITMAP color, _In_opt_ BITMAPINFO *src_info, _In_opt_ const void *color_bits, _In_ LONG width, _In_ LONG height)
Definition: cursoricon.c:568
static PBYTE CURSORICON_ConvertPngToBmpIcon(_In_ PBYTE pngBits, _In_ DWORD fileSize, _Out_ PDWORD pBmpIconSize)
Definition: cursoricon.c:93
static BOOL is_dib_monochrome(const BITMAPINFO *info)
Definition: cursoricon.c:365
const CURSORICONFILEDIRENTRY * get_best_icon_file_entry(_In_ const CURSORICONFILEDIR *dir, _In_ DWORD dwFileSize, _In_ int cxDesired, _In_ int cyDesired, _In_ BOOL bIcon, _In_ DWORD fuLoad)
Definition: cursoricon.c:739
static BOOL LibPngExists(VOID)
Definition: cursoricon.c:77
static HBITMAP BITMAP_CopyImage(_In_ HBITMAP hnd, _In_ int desiredx, _In_ int desiredy, _In_ UINT flags)
Definition: cursoricon.c:1961
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpCursorName)
Definition: cursoricon.c:2474
static HANDLE CURSORICON_LoadFromFileW(_In_ LPCWSTR lpszName, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuLoad, _In_ BOOL bIcon)
Definition: cursoricon.c:1629
#define HighBitDetect
HCURSOR WINAPI GetCursorFrameInfo(HCURSOR hCursor, DWORD reserved, DWORD istep, PINT rate_jiffies, DWORD *num_steps)
Definition: cursoricon.c:3092
static int DIB_GetBitmapInfo(const BITMAPINFOHEADER *header, LONG *width, LONG *height, WORD *bpp, DWORD *compr)
Definition: cursoricon.c:460
HBITMAP WINAPI LoadBitmapA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpBitmapName)
Definition: cursoricon.c:2517
int WINAPI LookupIconIdFromDirectoryEx(_In_ PBYTE presbits, _In_ BOOL fIcon, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT Flags)
Definition: cursoricon.c:2608
NTSTATUS WINAPI User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: cursoricon.c:2283
static VOID ReadMemoryPng(_Inout_ png_structp png_ptr, _Out_ png_bytep data, _In_ size_t length)
Definition: cursoricon.c:59
struct _PNG_READER_STATE PNG_READER_STATE
VOID LoadSystemCursors(VOID)
Definition: cursoricon.c:270
static void dump_ani_header(const ani_header *header)
Definition: cursoricon.c:1121
static const WCHAR DISPLAYW[]
Definition: cursoricon.c:336
HICON WINAPI CopyIcon(_In_ HICON hIcon)
Definition: cursoricon.c:2380
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpIconName)
Definition: cursoricon.c:2444
static HICON CURSORICON_CopyImage(_In_ HICON hicon, _In_ BOOL bIcon, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuFlags)
Definition: cursoricon.c:2151
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ LPCSTR lpFileName
Definition: winbase.h:2824
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:338
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1156
_In_ ULONG _In_ ULONG rgb
Definition: winddi.h:3521
DWORD COLORREF
Definition: windef.h:100
HICON HCURSOR
Definition: windef.h:99
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_CURSOR_HANDLE
Definition: winerror.h:1228
#define DIB_RGB_COLORS
Definition: wingdi.h:367
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
struct tagBITMAPFILEHEADER BITMAPFILEHEADER
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define DI_COMPAT
Definition: wingdi.h:68
int WINAPI GetDIBits(_In_ HDC hdc, _In_ HBITMAP hbm, _In_ UINT start, _In_ UINT cLines, _Out_opt_ LPVOID lpvBits, _At_((LPBITMAPINFOHEADER) lpbmi, _Inout_) LPBITMAPINFO lpbmi, _In_ UINT usage)
HDC WINAPI CreateICW(_In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_opt_ const DEVMODEW *)
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
#define DI_NORMAL
Definition: wingdi.h:72
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
HCURSOR WINAPI GetCursor(void)
Definition: cursoricon.c:3078
#define PLANES
Definition: wingdi.h:721
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
#define BITSPIXEL
Definition: wingdi.h:720
#define RGBA(r, g, b, a)
Definition: wingdi.h:3387
#define CBM_INIT
Definition: wingdi.h:365
#define GetObject
Definition: wingdi.h:4914
BOOL WINAPI DeleteDC(_In_ HDC)
HBITMAP WINAPI CreateDIBitmap(_In_ HDC hdc, _In_opt_ const BITMAPINFOHEADER *pbmih, _In_ DWORD fdwInit, _In_opt_ const VOID *pvInit, _In_opt_ const BITMAPINFO *pbmi, _In_ UINT uUsage)
#define DI_DEFAULTSIZE
Definition: wingdi.h:69
int WINAPI StretchDIBits(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ const VOID *, _In_ const BITMAPINFO *, _In_ UINT, _In_ DWORD)
HDC WINAPI CreateDCW(_In_opt_ LPCWSTR pszDriver, _In_opt_ LPCWSTR pszDevice, _In_opt_ LPCWSTR psz, _In_opt_ const DEVMODEW *pdmInit)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HICON WINAPI CreateIconFromResource(_In_reads_bytes_(dwResSize) PBYTE presbits, _In_ DWORD dwResSize, _In_ BOOL fIcon, _In_ DWORD dwVer)
DWORD WINAPI GetSysColor(_In_ int)
#define IMAGE_BITMAP
Definition: winuser.h:211
#define LR_LOADTRANSPARENT
Definition: winuser.h:1104
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2975
BOOL WINAPI DestroyCursor(_In_ HCURSOR)
Definition: cursoricon.c:3083
#define COLOR_WINDOW
Definition: winuser.h:929
#define LR_LOADFROMFILE
Definition: winuser.h:1103
#define IMAGE_ICON
Definition: winuser.h:212
HICON WINAPI CreateIcon(_In_opt_ HINSTANCE, _In_ int, _In_ int, _In_ BYTE, _In_ BYTE, _In_ const BYTE *, _In_ const BYTE *)
Definition: cursoricon.c:2764
BOOL WINAPI GetIconInfo(_In_ HICON, _Out_ PICONINFO)
Definition: cursoricon.c:2414
#define IDC_SIZENESW
Definition: winuser.h:701
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
#define LR_COPYFROMRESOURCE
Definition: winuser.h:1110
#define LR_CREATEDIBSECTION
Definition: winuser.h:1109
BOOL WINAPI DrawIcon(_In_ HDC, _In_ int, _In_ int, _In_ HICON)
Definition: cursoricon.c:2387
#define IDC_NO
Definition: winuser.h:705
#define IDC_ARROW
Definition: winuser.h:695
#define LR_MONOCHROME
Definition: winuser.h:1099
int WINAPI ShowCursor(_In_ BOOL)
Definition: cursoricon.c:3071
#define IDC_SIZENWSE
Definition: winuser.h:700
#define COLOR_3DSHADOW
Definition: winuser.h:942
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
#define IDC_SIZEALL
Definition: winuser.h:704
#define LR_COPYRETURNORG
Definition: winuser.h:1101
#define IDC_UPARROW
Definition: winuser.h:699
HANDLE WINAPI CopyImage(_In_ HANDLE, _In_ UINT, _In_ int, _In_ int, _In_ UINT)
Definition: cursoricon.c:2307
#define IDI_APPLICATION
Definition: winuser.h:712
#define IDC_SIZENS
Definition: winuser.h:703
#define IDC_CROSS
Definition: winuser.h:698
#define SM_CYICON
Definition: winuser.h:984
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpIconName)
Definition: cursoricon.c:2429
#define IDC_HELP
Definition: winuser.h:708
#define IDC_APPSTARTING
Definition: winuser.h:707
BOOL WINAPI DrawIconEx(_In_ HDC, _In_ int, _In_ int, _In_ HICON, _In_ int, _In_ int, _In_ UINT, _In_opt_ HBRUSH, _In_ UINT)
Definition: cursoricon.c:2397
#define IDC_IBEAM
Definition: winuser.h:696
#define LR_COPYDELETEORG
Definition: winuser.h:1102
HDC WINAPI GetDC(_In_opt_ HWND)
#define LR_SHARED
Definition: winuser.h:1111
#define IMAGE_CURSOR
Definition: winuser.h:213
#define IDC_ICON
Definition: winuser.h:709
HANDLE WINAPI LoadImageA(_In_opt_ HINSTANCE hInst, _In_ LPCSTR name, _In_ UINT type, _In_ int cx, _In_ int cy, _In_ UINT fuLoad)
Definition: cursoricon.c:2547
#define IDC_WAIT
Definition: winuser.h:697
#define IDC_HAND
Definition: winuser.h:706
#define LR_DEFAULTSIZE
Definition: winuser.h:1105
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define SM_CYCURSOR
Definition: winuser.h:986
#define IDC_SIZE
Definition: winuser.h:710
#define LR_LOADMAP3DCOLORS
Definition: winuser.h:1108
#define SM_CXICON
Definition: winuser.h:983
#define IDC_SIZEWE
Definition: winuser.h:702
int WINAPI GetSystemMetrics(_In_ int)
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2459
#define COLOR_3DLIGHT
Definition: winuser.h:951
#define SM_CXCURSOR
Definition: winuser.h:985
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2422
#define COLOR_3DFACE
Definition: winuser.h:940
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
unsigned char BYTE
Definition: xxhash.c:193