ReactOS 0.4.16-dev-976-g18fc5a1
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->rgbtRed == 0) && (rgb->rgbtGreen == 0) && (rgb->rgbtBlue == 0))
375 {
376 rgb++;
377
378 /* Check if the second color is white */
379 return ((rgb->rgbtRed == 0xff) && (rgb->rgbtGreen == 0xff)
380 && (rgb->rgbtBlue == 0xff));
381 }
382 else return FALSE;
383 }
384 else /* assume BITMAPINFOHEADER */
385 {
386 const RGBQUAD *rgb = info->bmiColors;
387
388 if (info->bmiHeader.biBitCount != 1) return FALSE;
389
390 /* Check if the first color is black */
391 if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) &&
392 (rgb->rgbBlue == 0) && (rgb->rgbReserved == 0))
393 {
394 rgb++;
395
396 /* Check if the second color is white */
397 return ((rgb->rgbRed == 0xff) && (rgb->rgbGreen == 0xff)
398 && (rgb->rgbBlue == 0xff) && (rgb->rgbReserved == 0));
399 }
400 else return FALSE;
401 }
402}
403
404/* Return the size of the bitmap info structure including color table and
405 * the bytes required for 3 DWORDS if this is a BI_BITFIELDS bmp. */
406static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
407{
408 unsigned int colors, size, masks = 0;
409
410 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
411 {
412 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
413 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
414 return sizeof(BITMAPCOREHEADER) + colors *
415 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
416 }
417 else /* assume BITMAPINFOHEADER */
418 {
419 colors = info->bmiHeader.biClrUsed;
420 if (colors > 256) /* buffer overflow otherwise */
421 colors = 256;
422 if (!colors && (info->bmiHeader.biBitCount <= 8))
423 colors = 1 << info->bmiHeader.biBitCount;
424 /* Account for BI_BITFIELDS in BITMAPINFOHEADER(v1-v3) bmp's. The
425 * 'max' selection using biSize below will exclude v4 & v5's. */
426 if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
427 size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
428 /* Test for BI_BITFIELDS format and either 16 or 32 bpp.
429 * If so, account for the 3 DWORD masks (RGB Order).
430 * BITMAPCOREHEADER tested above has no 16 or 32 bpp types.
431 * See table "All of the possible pixel formats in a DIB"
432 * at https://en.wikipedia.org/wiki/BMP_file_format. */
433 if (info->bmiHeader.biSize >= sizeof(BITMAPV4HEADER) &&
434 info->bmiHeader.biCompression == BI_BITFIELDS &&
435 (info->bmiHeader.biBitCount == 16 || info->bmiHeader.biBitCount == 32))
436 {
437 size += 3 * sizeof(DWORD); // BI_BITFIELDS
438 }
439 return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
440 }
441}
442
445{
446 #define CR 13
447 #define LF 10
448 #define EOFM 26 // DOS End Of File Marker
449 #define HighBitDetect 0x89 // Byte with high bit set to test if not 7-bit
450 /* wine's definition */
451 static const BYTE png_sig_pattern[] = { HighBitDetect, 'P', 'N', 'G', CR, LF, EOFM, LF };
452 if (header->biSize == sizeof(BITMAPCOREHEADER))
453 {
454 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
455 *width = core->bcWidth;
456 *height = core->bcHeight;
457 *bpp = core->bcBitCount;
458 *compr = 0;
459 return 0;
460 }
461 else if (header->biSize == sizeof(BITMAPINFOHEADER) ||
462 header->biSize == sizeof(BITMAPV4HEADER) ||
463 header->biSize == sizeof(BITMAPV5HEADER))
464 {
465 *width = header->biWidth;
466 *height = header->biHeight;
467 *bpp = header->biBitCount;
468 *compr = header->biCompression;
469 return 1;
470 }
471 if (memcmp(&header->biSize, png_sig_pattern, sizeof(png_sig_pattern)) == 0)
472 {
473 TRACE("We have a PNG icon\n");
474 /* for PNG format details see https://en.wikipedia.org/wiki/PNG */
475 }
476 else
477 {
478 ERR("Unknown/wrong size for header of 0x%x\n", header->biSize );
479 }
480 return -1;
481}
482
483/* copy an icon bitmap, even when it can't be selected into a DC */
484/* helper for CreateIconIndirect */
485static void stretch_blt_icon(HDC hdc_dst, int dst_width, int dst_height, HBITMAP src)
486{
488 BITMAP bm;
489 HBITMAP hbmpPrev;
490
491 GetObjectW(src, sizeof(bm), &bm);
492
493 hbmpPrev = SelectObject(hdc, src);
494
495 if (!hbmpPrev) /* do it the hard way */
496 {
498 void *bits;
499
500 if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) return;
501 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
502 info->bmiHeader.biWidth = bm.bmWidth;
503 info->bmiHeader.biHeight = bm.bmHeight;
504 info->bmiHeader.biPlanes = GetDeviceCaps( hdc_dst, PLANES );
505 info->bmiHeader.biBitCount = GetDeviceCaps( hdc_dst, BITSPIXEL );
506 info->bmiHeader.biCompression = BI_RGB;
507 info->bmiHeader.biSizeImage = get_dib_image_size( bm.bmWidth, bm.bmHeight, info->bmiHeader.biBitCount );
508 info->bmiHeader.biXPelsPerMeter = 0;
509 info->bmiHeader.biYPelsPerMeter = 0;
510 info->bmiHeader.biClrUsed = 0;
511 info->bmiHeader.biClrImportant = 0;
512 bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage );
513 if (bits && GetDIBits( hdc, src, 0, bm.bmHeight, bits, info, DIB_RGB_COLORS ))
514 StretchDIBits( hdc_dst, 0, 0, dst_width, dst_height,
515 0, 0, bm.bmWidth, bm.bmHeight, bits, info, DIB_RGB_COLORS, SRCCOPY );
516
519 }
520 else
521 {
522 StretchBlt( hdc_dst, 0, 0, dst_width, dst_height, hdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY );
523 SelectObject(hdc, hbmpPrev);
524 }
525
526 DeleteDC( hdc );
527}
528
529/***********************************************************************
530 * bmi_has_alpha
531 */
532static BOOL bmi_has_alpha( const BITMAPINFO *info, const void *bits )
533{
534 int i;
535 BOOL has_alpha = FALSE;
536 const unsigned char *ptr = bits;
537
538 if (info->bmiHeader.biBitCount != 32) return FALSE;
539 for (i = 0; i < info->bmiHeader.biWidth * abs(info->bmiHeader.biHeight); i++, ptr += 4)
540 if ((has_alpha = (ptr[3] != 0))) break;
541 return has_alpha;
542}
543
544/***********************************************************************
545 * create_alpha_bitmap
546 *
547 * Create the alpha bitmap for a 32-bpp icon that has an alpha channel.
548 */
549static
553 _In_opt_ BITMAPINFO *src_info,
554 _In_opt_ const void *color_bits,
557{
559 HDC hdc = NULL, hdcScreen;
560 unsigned char *ptr;
561 void *bits = NULL;
562 ULONG size;
563
564 hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
565 if (!hdcScreen)
566 return NULL;
567 hdc = CreateCompatibleDC(hdcScreen);
568 if (!hdc)
569 {
570 DeleteDC(hdcScreen);
571 return NULL;
572 }
573
574 if (color)
575 {
576 BITMAP bm;
578
579 TRACE("Creating alpha bitmap from existing bitmap.\n");
580
581 if (!GetObjectW( color, sizeof(bm), &bm ))
582 goto done;
583 if (bm.bmBitsPixel != 32)
584 goto done;
585
586 size = get_dib_image_size(bm.bmWidth, bm.bmHeight, 32);
587
588 info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
589 if(!info)
590 goto done;
591 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
592 info->bmiHeader.biWidth = bm.bmWidth;
593 info->bmiHeader.biHeight = -bm.bmHeight;
594 info->bmiHeader.biPlanes = 1;
595 info->bmiHeader.biBitCount = 32;
596 info->bmiHeader.biCompression = BI_RGB;
597 info->bmiHeader.biSizeImage = size;
598 info->bmiHeader.biXPelsPerMeter = 0;
599 info->bmiHeader.biYPelsPerMeter = 0;
600 info->bmiHeader.biClrUsed = 0;
601 info->bmiHeader.biClrImportant = 0;
602
604 if(!bits)
605 {
607 goto done;
608 }
609 if(!GetDIBits( hdc, color, 0, bm.bmHeight, bits, info, DIB_RGB_COLORS ))
610 {
612 goto done;
613 }
614 if (!bmi_has_alpha( info, bits ))
615 {
617 goto done;
618 }
619
620 /* pre-multiply by alpha */
621 for (ptr = bits; ptr < ((BYTE*)bits + size); ptr += 4)
622 {
623 unsigned int alpha = ptr[3];
624 ptr[0] = (ptr[0] * alpha) / 255;
625 ptr[1] = (ptr[1] * alpha) / 255;
626 ptr[2] = (ptr[2] * alpha) / 255;
627 }
628
629 /* Directly create a 32-bits DDB (thanks to undocumented CreateDIBitmap flag). */
631
633 }
634 else
635 {
636 WORD bpp;
637 DWORD compr;
638 LONG orig_width, orig_height;
639
640 TRACE("Creating alpha bitmap from bitmap info.\n");
641
642 if(!bmi_has_alpha(src_info, color_bits))
643 goto done;
644
645 if(!DIB_GetBitmapInfo(&src_info->bmiHeader, &orig_width, &orig_height, &bpp, &compr))
646 goto done;
647 if(bpp != 32)
648 goto done;
649
650 size = get_dib_image_size(orig_width, orig_height, bpp);
652 if(!bits)
653 goto done;
654 CopyMemory(bits, color_bits, size);
655 /* pre-multiply by alpha */
656 for (ptr = bits; ptr < ((BYTE*)bits + size); ptr += 4)
657 {
658 unsigned int alpha = ptr[3];
659 ptr[0] = (ptr[0] * alpha) / 255;
660 ptr[1] = (ptr[1] * alpha) / 255;
661 ptr[2] = (ptr[2] * alpha) / 255;
662 }
663
664 /* Create the bitmap. Set the bitmap info to have the right width and height */
665 if(src_info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
666 {
667 ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcWidth = width;
668 ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcHeight = height;
669 }
670 else
671 {
672 src_info->bmiHeader.biWidth = width;
673 src_info->bmiHeader.biHeight = height;
674 }
675 /* Directly create a 32-bits DDB (thanks to undocumented CreateDIBitmap flag). */
676 alpha = CreateDIBitmap(hdcScreen, NULL, 2, NULL, src_info, DIB_RGB_COLORS);
677 /* Restore values */
678 if(src_info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
679 {
680 ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcWidth = orig_width;
681 ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcHeight = orig_height;
682 }
683 else
684 {
685 src_info->bmiHeader.biWidth = orig_width;
686 src_info->bmiHeader.biHeight = orig_height;
687 }
688 if(!alpha)
689 goto done;
691 if(!hbmpOld)
692 {
694 alpha = NULL;
695 goto done;
696 }
697 if(!StretchDIBits( hdc, 0, 0, width, height,
698 0, 0, orig_width, orig_height,
699 bits, src_info, DIB_RGB_COLORS, SRCCOPY ))
700 {
702 hbmpOld = NULL;
704 alpha = NULL;
705 }
706 else
707 {
709 }
710 }
711
712done:
713 DeleteDC(hdcScreen);
714 DeleteDC( hdc );
715 if(bits) HeapFree(GetProcessHeap(), 0, bits);
716
717 TRACE("Returning 0x%08x.\n", alpha);
718 return alpha;
719}
720
725 _In_ int cxDesired,
726 _In_ int cyDesired,
727 _In_ BOOL bIcon,
728 _In_ DWORD fuLoad
729)
730{
731 CURSORICONDIR* fakeDir;
732 CURSORICONDIRENTRY* fakeEntry;
733 WORD i;
735
736 /* Check our file is what it claims to be */
737 if ( dwFileSize < sizeof(*dir) )
738 return NULL;
739
740 if (dwFileSize < FIELD_OFFSET(CURSORICONFILEDIR, idEntries[dir->idCount]))
741 return NULL;
742
743 /*
744 * Cute little hack:
745 * We allocate a buffer, fake it as if it was a pointer to a resource in a module,
746 * pass it to LookupIconIdFromDirectoryEx and get back the index we have to use
747 */
748 fakeDir = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(CURSORICONDIR, idEntries[dir->idCount]));
749 if(!fakeDir)
750 {
752 return NULL;
753 }
754 fakeDir->idReserved = 0;
755 fakeDir->idType = dir->idType;
756 fakeDir->idCount = dir->idCount;
757 for(i = 0; i<dir->idCount; i++)
758 {
759 fakeEntry = &fakeDir->idEntries[i];
760 entry = &dir->idEntries[i];
761 /* Take this as an occasion to perform a size check */
762 if ((entry->dwDIBOffset > dwFileSize)
763 || ((entry->dwDIBOffset + entry->dwDIBSize) > dwFileSize))
764 {
765 ERR("Corrupted icon file?.\n");
766 HeapFree(GetProcessHeap(), 0, fakeDir);
767 return NULL;
768 }
769 /* File icon/cursors are not like resource ones */
770 if(bIcon)
771 {
772 fakeEntry->ResInfo.icon.bWidth = entry->bWidth;
773 fakeEntry->ResInfo.icon.bHeight = entry->bHeight;
774 fakeEntry->ResInfo.icon.bColorCount = 0;
775 fakeEntry->ResInfo.icon.bReserved = 0;
776 }
777 else
778 {
779 fakeEntry->ResInfo.cursor.wWidth = entry->bWidth;
780 fakeEntry->ResInfo.cursor.wHeight = entry->bHeight;
781 }
782 /* Let's assume there's always one plane */
783 fakeEntry->wPlanes = 1;
784 /* We must get the bitcount from the BITMAPINFOHEADER itself */
785 if (((BITMAPINFOHEADER *)((char *)dir + entry->dwDIBOffset))->biSize == sizeof(BITMAPCOREHEADER))
786 fakeEntry->wBitCount = ((BITMAPCOREHEADER *)((char *)dir + entry->dwDIBOffset))->bcBitCount;
787 else
788 fakeEntry->wBitCount = ((BITMAPINFOHEADER *)((char *)dir + entry->dwDIBOffset))->biBitCount;
789 fakeEntry->dwBytesInRes = entry->dwDIBSize;
790 fakeEntry->wResId = i + 1;
791 }
792
793 /* Now call LookupIconIdFromResourceEx */
794 i = LookupIconIdFromDirectoryEx((PBYTE)fakeDir, bIcon, cxDesired, cyDesired, fuLoad & LR_MONOCHROME);
795 /* We don't need this anymore */
796 HeapFree(GetProcessHeap(), 0, fakeDir);
797 if(i == 0)
798 {
799 WARN("Unable to get a fit entry index.\n");
800 return NULL;
801 }
802
803 /* We found it */
804 return &dir->idEntries[i-1];
805}
806
807DWORD
809 _In_ const LPBYTE dir,
811 _In_ int cxDesired,
812 _In_ int cyDesired,
813 _In_ BOOL bIcon,
814 _In_ DWORD fuLoad,
815 _Out_ POINT *ptHotSpot
816)
817{
819
820 entry = get_best_icon_file_entry((CURSORICONFILEDIR *) dir, dwFileSize, cxDesired, cyDesired, bIcon, fuLoad);
821
822 if(ptHotSpot)
823 {
824 ptHotSpot->x = entry->xHotspot;
825 ptHotSpot->y = entry->yHotspot;
826 }
827
828 if(entry)
829 return entry->dwDIBOffset;
830
831 return 0;
832}
833
834
835
836/************* IMPLEMENTATION CORE ****************/
837
840 _In_ const BITMAPINFO *pbmi
841)
842{
844 BOOL monochrome = is_dib_monochrome(pbmi);
846 WORD bpp;
847 DWORD compr;
848 int ibmpType;
849 HDC hdc, hdcScreen;
850 BITMAPINFO* pbmiCopy;
852 BOOL bResult = FALSE;
853 const VOID *pvColor, *pvMask;
854
855 ibmpType = DIB_GetBitmapInfo(&pbmi->bmiHeader, &width, &height, &bpp, &compr);
856 /* Invalid data */
857 if(ibmpType < 0)
858 return FALSE;
859
860 /* No compression for icons */
861 if(compr != BI_RGB)
862 return FALSE;
863
864 /* If no dimensions were set, use the one from the icon */
865 if(!pdata->cx) pdata->cx = width;
866 if(!pdata->cy) pdata->cy = height < 0 ? -height/2 : height/2;
867
868 /* Fix the hotspot coords */
869 if(pdata->rt == (USHORT)((ULONG_PTR)RT_CURSOR))
870 {
871 if(pdata->cx != width)
872 pdata->xHotspot = (pdata->xHotspot * pdata->cx) / width;
873 if(pdata->cy != height/2)
874 pdata->yHotspot = (pdata->yHotspot * pdata->cy * 2) / height;
875 }
876 else
877 {
878 pdata->xHotspot = pdata->cx/2;
879 pdata->yHotspot = pdata->cy/2;
880 }
881
882 hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
883 if(!hdcScreen)
884 return FALSE;
885 hdc = CreateCompatibleDC(hdcScreen);
886 if(!hdc)
887 {
888 DeleteDC(hdcScreen);
889 return FALSE;
890 }
891
892 pbmiCopy = HeapAlloc(GetProcessHeap(), 0, max(ubmiSize, FIELD_OFFSET(BITMAPINFO, bmiColors[3])));
893 if(!pbmiCopy)
894 goto done;
895 RtlCopyMemory(pbmiCopy, pbmi, ubmiSize);
896
897 /* In an icon/cursor, the BITMAPINFO holds twice the height */
898 if(pbmiCopy->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
899 ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcHeight /= 2;
900 else
901 pbmiCopy->bmiHeader.biHeight /= 2;
902 height /= 2;
903
904 pvColor = (const char*)pbmi + ubmiSize;
905 pvMask = (const char*)pvColor +
907
908 /* Set XOR bits */
909 if(monochrome)
910 {
911 /* Create the 1bpp bitmap which will contain everything */
912 pdata->hbmColor = NULL;
913 pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy * 2, 1, 1, NULL);
914 if(!pdata->hbmMask)
915 goto done;
916 hbmpOld = SelectObject(hdc, pdata->hbmMask);
917 if(!hbmpOld)
918 goto done;
919
920 if(!StretchDIBits(hdc, 0, pdata->cy, pdata->cx, pdata->cy,
921 0, 0, width, height,
922 pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
923 goto done;
924 pdata->bpp = 1;
925 }
926 else
927 {
928 /* Create the bitmap. It has to be compatible with the screen surface */
929 pdata->hbmColor = CreateCompatibleBitmap(hdcScreen, pdata->cx, pdata->cy);
930 if(!pdata->hbmColor)
931 goto done;
932 /* Create the 1bpp mask bitmap */
933 pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy, 1, 1, NULL);
934 if(!pdata->hbmMask)
935 goto done;
936 hbmpOld = SelectObject(hdc, pdata->hbmColor);
937 if(!hbmpOld)
938 goto done;
939 if(!StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy,
940 0, 0, width, height,
941 pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
942 goto done;
943 pdata->bpp = GetDeviceCaps(hdcScreen, BITSPIXEL);
944 pdata->hbmAlpha = create_alpha_bitmap(NULL, pbmiCopy, pvColor, pdata->cx, pdata->cy);
945
946 /* Now convert the info to monochrome for the mask bits */
947 if (pbmiCopy->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))
948 {
949 RGBQUAD *rgb = pbmiCopy->bmiColors;
950
951 pbmiCopy->bmiHeader.biClrUsed = pbmiCopy->bmiHeader.biClrImportant = 2;
952 rgb[0].rgbBlue = rgb[0].rgbGreen = rgb[0].rgbRed = 0x00;
953 rgb[1].rgbBlue = rgb[1].rgbGreen = rgb[1].rgbRed = 0xff;
954 rgb[0].rgbReserved = rgb[1].rgbReserved = 0;
955 pbmiCopy->bmiHeader.biBitCount = 1;
956 }
957 else
958 {
959 RGBTRIPLE *rgb = (RGBTRIPLE *)(((BITMAPCOREHEADER *)pbmiCopy) + 1);
960
961 rgb[0].rgbtBlue = rgb[0].rgbtGreen = rgb[0].rgbtRed = 0x00;
962 rgb[1].rgbtBlue = rgb[1].rgbtGreen = rgb[1].rgbtRed = 0xff;
963 ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcBitCount = 1;
964 }
965 }
966 /* Set the mask bits */
967 if(!SelectObject(hdc, pdata->hbmMask))
968 goto done;
969 bResult = StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy,
970 0, 0, width, height,
971 pvMask, pbmiCopy, DIB_RGB_COLORS, SRCCOPY) != 0;
972
973done:
974 DeleteDC(hdcScreen);
976 DeleteDC(hdc);
977 if(pbmiCopy) HeapFree(GetProcessHeap(), 0, pbmiCopy);
978 /* Clean up in case of failure */
979 if(!bResult)
980 {
981 if(pdata->hbmMask) DeleteObject(pdata->hbmMask);
982 if(pdata->hbmColor) DeleteObject(pdata->hbmColor);
983 if(pdata->hbmAlpha) DeleteObject(pdata->hbmAlpha);
984 }
985 return bResult;
986}
987
989 _Out_ CURSORDATA* pCursorData,
990 _In_ ICONINFO* pIconInfo
991)
992{
993 BITMAP bm;
994
995 ZeroMemory(pCursorData, sizeof(*pCursorData));
996 if(pIconInfo->hbmColor)
997 {
998 /* We must convert the color bitmap to screen format */
999 HDC hdcScreen, hdcMem;
1000 HBITMAP hbmpPrev;
1001
1002 /* The mask dictates its dimensions */
1003 if (!GetObject(pIconInfo->hbmMask, sizeof(bm), &bm))
1004 return FALSE;
1005 hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
1006 if(!hdcScreen)
1007 return FALSE;
1008 hdcMem = CreateCompatibleDC(hdcScreen);
1009 if(!hdcMem)
1010 {
1011 DeleteDC(hdcScreen);
1012 return FALSE;
1013 }
1014 pCursorData->hbmColor = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight);
1015 DeleteDC(hdcScreen);
1016 if (!pCursorData->hbmColor)
1017 {
1019 return FALSE;
1020 }
1021 hbmpPrev = SelectObject(hdcMem, pCursorData->hbmColor);
1022 if (!hbmpPrev)
1023 {
1025 DeleteObject(pCursorData->hbmColor);
1026 return FALSE;
1027 }
1028 stretch_blt_icon( hdcMem, bm.bmWidth, bm.bmHeight, pIconInfo->hbmColor);
1029 SelectObject(hdcMem, hbmpPrev);
1031 }
1032 pCursorData->hbmMask = CopyImage(pIconInfo->hbmMask, IMAGE_BITMAP, 0, 0, LR_MONOCHROME);
1033 if(!pCursorData->hbmMask)
1034 return FALSE;
1035
1036 /* Now, fill some information */
1037 pCursorData->rt = (USHORT)((ULONG_PTR)(pIconInfo->fIcon ? RT_ICON : RT_CURSOR));
1038 if(pCursorData->hbmColor)
1039 {
1040 GetObject(pCursorData->hbmColor, sizeof(bm), &bm);
1041 pCursorData->bpp = bm.bmBitsPixel;
1042 pCursorData->cx = bm.bmWidth;
1043 pCursorData->cy = bm.bmHeight;
1044 if(pCursorData->bpp == 32)
1045 pCursorData->hbmAlpha = create_alpha_bitmap(pCursorData->hbmColor, NULL, NULL, 0, 0);
1046 }
1047 else
1048 {
1049 GetObject(pCursorData->hbmMask, sizeof(bm), &bm);
1050 pCursorData->bpp = 1;
1051 pCursorData->cx = bm.bmWidth;
1052 pCursorData->cy = bm.bmHeight/2;
1053 }
1054
1055 if(pIconInfo->fIcon)
1056 {
1057 pCursorData->xHotspot = pCursorData->cx/2;
1058 pCursorData->yHotspot = pCursorData->cy/2;
1059 }
1060 else
1061 {
1062 pCursorData->xHotspot = pIconInfo->xHotspot;
1063 pCursorData->yHotspot = pIconInfo->yHotspot;
1064 }
1065
1066 return TRUE;
1067}
1068
1069
1070#define RIFF_FOURCC( c0, c1, c2, c3 ) \
1071 ( (DWORD)(BYTE)(c0) | ( (DWORD)(BYTE)(c1) << 8 ) | \
1072 ( (DWORD)(BYTE)(c2) << 16 ) | ( (DWORD)(BYTE)(c3) << 24 ) )
1073
1074#define ANI_RIFF_ID RIFF_FOURCC('R', 'I', 'F', 'F')
1075#define ANI_LIST_ID RIFF_FOURCC('L', 'I', 'S', 'T')
1076#define ANI_ACON_ID RIFF_FOURCC('A', 'C', 'O', 'N')
1077#define ANI_anih_ID RIFF_FOURCC('a', 'n', 'i', 'h')
1078#define ANI_seq__ID RIFF_FOURCC('s', 'e', 'q', ' ')
1079#define ANI_fram_ID RIFF_FOURCC('f', 'r', 'a', 'm')
1080#define ANI_rate_ID RIFF_FOURCC('r', 'a', 't', 'e')
1081
1082#define ANI_FLAG_ICON 0x1
1083#define ANI_FLAG_SEQUENCE 0x2
1084
1085#include <pshpack1.h>
1086typedef struct {
1087 DWORD header_size;
1088 DWORD num_frames;
1089 DWORD num_steps;
1090 DWORD width;
1091 DWORD height;
1092 DWORD bpp;
1093 DWORD num_planes;
1094 DWORD display_rate;
1095 DWORD flags;
1096} ani_header;
1097
1098typedef struct {
1100 const unsigned char *data;
1101} riff_chunk_t;
1102#include <poppack.h>
1103
1104static void dump_ani_header( const ani_header *header )
1105{
1106 TRACE(" header size: %d\n", header->header_size);
1107 TRACE(" frames: %d\n", header->num_frames);
1108 TRACE(" steps: %d\n", header->num_steps);
1109 TRACE(" width: %d\n", header->width);
1110 TRACE(" height: %d\n", header->height);
1111 TRACE(" bpp: %d\n", header->bpp);
1112 TRACE(" planes: %d\n", header->num_planes);
1113 TRACE(" display rate: %d\n", header->display_rate);
1114 TRACE(" flags: 0x%08x\n", header->flags);
1115}
1116
1117/* Find an animated cursor chunk, given its type and ID */
1118static void riff_find_chunk( DWORD chunk_id, DWORD chunk_type, const riff_chunk_t *parent_chunk, riff_chunk_t *chunk )
1119{
1120 const unsigned char *ptr = parent_chunk->data;
1121 const unsigned char *end = parent_chunk->data + (parent_chunk->data_size - (2 * sizeof(DWORD)));
1122
1123 if (chunk_type == ANI_LIST_ID || chunk_type == ANI_RIFF_ID) end -= sizeof(DWORD);
1124
1125 while (ptr < end)
1126 {
1127 if ((!chunk_type && *(const DWORD *)ptr == chunk_id )
1128 || (chunk_type && *(const DWORD *)ptr == chunk_type && *((const DWORD *)ptr + 2) == chunk_id ))
1129 {
1130 ptr += sizeof(DWORD);
1131 chunk->data_size = (*(const DWORD *)ptr + 1) & ~1;
1132 ptr += sizeof(DWORD);
1133 if (chunk_type == ANI_LIST_ID || chunk_type == ANI_RIFF_ID) ptr += sizeof(DWORD);
1134 chunk->data = ptr;
1135
1136 return;
1137 }
1138
1139 ptr += sizeof(DWORD);
1140 ptr += (*(const DWORD *)ptr + 1) & ~1;
1141 ptr += sizeof(DWORD);
1142 }
1143}
1144
1146 _Inout_ CURSORDATA* pCurData,
1147 _In_ const BYTE *pData,
1148 _In_ DWORD dwDataSize,
1149 _In_ DWORD fuLoad
1150)
1151{
1152 UINT i;
1153 const ani_header *pHeader;
1154 riff_chunk_t root_chunk = { dwDataSize, pData };
1155 riff_chunk_t ACON_chunk = {0};
1156 riff_chunk_t anih_chunk = {0};
1157 riff_chunk_t fram_chunk = {0};
1158 riff_chunk_t rate_chunk = {0};
1159 riff_chunk_t seq_chunk = {0};
1160 const unsigned char *icon_chunk;
1161 const unsigned char *icon_data;
1162
1163 /* Find the root chunk */
1164 riff_find_chunk( ANI_ACON_ID, ANI_RIFF_ID, &root_chunk, &ACON_chunk );
1165 if (!ACON_chunk.data)
1166 {
1167 ERR("Failed to get root chunk.\n");
1168 return FALSE;
1169 }
1170
1171 /* Find the header chunk */
1172 riff_find_chunk( ANI_anih_ID, 0, &ACON_chunk, &anih_chunk );
1173 if (!ACON_chunk.data)
1174 {
1175 ERR("Failed to get header chunk.\n");
1176 return FALSE;
1177 }
1178 pHeader = (ani_header*)anih_chunk.data;
1180
1181 /* Set up the master data */
1182 pCurData->CURSORF_flags |= CURSORF_ACON;
1183 pCurData->cpcur = pHeader->num_frames;
1184 pCurData->cicur = pHeader->num_steps;
1185 pCurData->iicur = pHeader->display_rate;
1186
1187 /* Get the sequences */
1188 if (pHeader->flags & ANI_FLAG_SEQUENCE)
1189 {
1190 riff_find_chunk( ANI_seq__ID, 0, &ACON_chunk, &seq_chunk );
1191 if (!seq_chunk.data)
1192 {
1193 ERR("No sequence data although the flag is set!\n");
1194 return FALSE;
1195 }
1196 }
1197
1198 /* Get the frame rates */
1199 riff_find_chunk( ANI_rate_ID, 0, &ACON_chunk, &rate_chunk );
1200 if (rate_chunk.data)
1201 pCurData->ajifRate = (INT*)rate_chunk.data;
1202
1203 /* Get the frames chunk */
1204 riff_find_chunk( ANI_fram_ID, ANI_LIST_ID, &ACON_chunk, &fram_chunk );
1205 if (!fram_chunk.data)
1206 {
1207 ERR("Failed to get icon list.\n");
1208 return 0;
1209 }
1210 icon_chunk = fram_chunk.data;
1211 icon_data = fram_chunk.data + (2 * sizeof(DWORD));
1212
1213 if(pHeader->num_frames > 1)
1214 {
1215 /* Allocate frame descriptors, step indices and rates */
1216 pCurData->aspcur = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1217 pHeader->num_frames * sizeof(CURSORDATA) + pHeader->num_steps * (sizeof(DWORD) + sizeof(INT)));
1218 if(!pCurData->aspcur)
1219 {
1221 return FALSE;
1222 }
1223 pCurData->aicur = (DWORD*)(pCurData->aspcur + pHeader->num_frames);
1224 pCurData->ajifRate = (INT*)(pCurData->aicur + pHeader->num_steps);
1225 }
1226
1227 for(i=0; i < pHeader->num_frames; i++)
1228 {
1229 CURSORDATA* pFrameData;
1230 const DWORD chunk_size = *(const DWORD *)(icon_chunk + sizeof(DWORD));
1231 const BITMAPINFO* pbmi;
1232
1233 if(pHeader->num_frames > 1)
1234 pFrameData = &pCurData->aspcur[i];
1235 else
1236 pFrameData = pCurData;
1237
1238 pFrameData->rt = pCurData->rt;
1239
1240 if (pHeader->flags & ANI_FLAG_ICON)
1241 {
1242 /* The chunks describe an icon file */
1244 (const CURSORICONFILEDIR *) icon_data,
1245 chunk_size,
1246 pCurData->cx,
1247 pCurData->cy,
1248 TRUE,
1249 fuLoad);
1250 if(!pDirEntry)
1251 {
1252 ERR("Unable to find the right file entry for frame %d.\n", i);
1253 goto error;
1254 }
1255 pFrameData->xHotspot = pDirEntry->xHotspot;
1256 pFrameData->yHotspot = pDirEntry->yHotspot;
1257 if(!pHeader->width || !pHeader->height)
1258 {
1259 pFrameData->cx = pDirEntry->bWidth;
1260 pFrameData->cy = pDirEntry->bHeight;
1261 }
1262 else
1263 {
1264 pFrameData->cx = pHeader->width;
1265 pFrameData->cy = pHeader->height;
1266 }
1267 pbmi = (const BITMAPINFO *) (icon_data + pDirEntry->dwDIBOffset);
1268 }
1269 else
1270 {
1271 /* The chunks just describe bitmaps */
1272 pbmi = (const BITMAPINFO *)icon_data;
1273 pFrameData->xHotspot = pFrameData->yHotspot = 0;
1274 }
1275
1276 /* Do the real work */
1278
1279 if(pHeader->num_frames > 1)
1280 pFrameData->CURSORF_flags |= CURSORF_ACONFRAME;
1281 else
1282 pFrameData->CURSORF_flags &= ~CURSORF_ACON;
1283
1284
1285 /* Next frame */
1286 icon_chunk += chunk_size + (2 * sizeof(DWORD));
1287 icon_data = icon_chunk + (2 * sizeof(DWORD));
1288 }
1289
1290 if(pHeader->num_frames <= 1)
1291 return TRUE;
1292
1293 if(rate_chunk.data)
1294 CopyMemory(pCurData->ajifRate, rate_chunk.data, pHeader->num_steps * sizeof(INT));
1295 else
1296 {
1297 for(i=0; i < pHeader->num_steps; i++)
1298 pCurData->ajifRate[i] = pHeader->display_rate;
1299 }
1300
1301 if (pHeader->flags & ANI_FLAG_SEQUENCE)
1302 {
1303 CopyMemory(pCurData->aicur, seq_chunk.data, pHeader->num_steps * sizeof(DWORD));
1304 }
1305 else
1306 {
1307 for(i=0; i < pHeader->num_steps; i++)
1308 pCurData->aicur[i] = i;
1309 }
1310
1311 return TRUE;
1312
1313error:
1314 HeapFree(GetProcessHeap(), 0, pCurData->aspcur);
1315 ZeroMemory(pCurData, sizeof(CURSORDATA));
1316 return FALSE;
1317}
1318
1319
1320static
1321HBITMAP
1324 _In_ LPCWSTR lpszName,
1325 _In_ int cxDesired,
1326 _In_ int cyDesired,
1327 _In_ UINT fuLoad
1328)
1329{
1330 const BITMAPINFO* pbmi;
1331 BITMAPINFO* pbmiScaled = NULL;
1332 BITMAPINFO* pbmiCopy = NULL;
1333 const VOID* pvMapping = NULL;
1334 DWORD dwOffset = 0;
1335 HGLOBAL hgRsrc = NULL;
1336 int iBMISize;
1337 PVOID pvBits;
1338 HDC hdcScreen = NULL;
1339 HDC hdc = NULL;
1340 HBITMAP hbmpOld, hbmpRet = NULL;
1341 LONG width, height;
1342 WORD bpp;
1343 DWORD compr, ResSize = 0;
1344
1345 /* Map the bitmap info */
1346 if(fuLoad & LR_LOADFROMFILE)
1347 {
1348 const BITMAPFILEHEADER* pbmfh;
1349
1350 pvMapping = map_fileW(lpszName, NULL);
1351 if(!pvMapping)
1352 return NULL;
1353 pbmfh = pvMapping;
1354 if (pbmfh->bfType != 0x4d42 /* 'BM' */)
1355 {
1356 WARN("Invalid/unsupported bitmap format!\n");
1357 goto end;
1358 }
1359 pbmi = (const BITMAPINFO*)(pbmfh + 1);
1360
1361 /* Get the image bits */
1362 if(pbmfh->bfOffBits)
1363 dwOffset = pbmfh->bfOffBits - sizeof(BITMAPFILEHEADER);
1364 }
1365 else
1366 {
1367 HRSRC hrsrc;
1368
1369 /* Caller wants an OEM bitmap */
1370 if(!hinst)
1372 hrsrc = FindResourceW(hinst, lpszName, RT_BITMAP);
1373 if(!hrsrc)
1374 return NULL;
1375 hgRsrc = LoadResource(hinst, hrsrc);
1376 if(!hgRsrc)
1377 return NULL;
1378 pbmi = LockResource(hgRsrc);
1379 if(!pbmi)
1380 return NULL;
1381 ResSize = SizeofResource(hinst, hrsrc);
1382 }
1383
1385 {
1386 SIZE_T totalSize = pbmi->bmiHeader.biSize + (3 * sizeof(DWORD)) +
1388 if (pbmi->bmiHeader.biSizeImage != 0 && totalSize != ResSize)
1389 WARN("Possibly bad resource size provided\n");
1390 }
1391
1392 /* Fix up values */
1393 if(DIB_GetBitmapInfo(&pbmi->bmiHeader, &width, &height, &bpp, &compr) == -1)
1394 goto end;
1395 if((width > 65535) || (height > 65535))
1396 goto end;
1397 if(cxDesired == 0)
1398 cxDesired = width;
1399 if(cyDesired == 0)
1400 cyDesired = height;
1401 else if(height < 0)
1402 cyDesired = -cyDesired;
1403
1405
1406 /* Get a pointer to the image data */
1407 pvBits = (char*)pbmi + (dwOffset ? dwOffset : iBMISize);
1408
1409 /* Create a copy of the info describing the bitmap in the file */
1410 pbmiCopy = HeapAlloc(GetProcessHeap(), 0, iBMISize);
1411 if(!pbmiCopy)
1412 goto end;
1413 CopyMemory(pbmiCopy, pbmi, iBMISize);
1414
1415 TRACE("Size Image %d, Size Header %d, ResSize %d\n",
1416 pbmiCopy->bmiHeader.biSizeImage, pbmiCopy->bmiHeader.biSize, ResSize);
1417
1418 /* HACK: If this is a binutils' windres.exe compiled 16 or 32 bpp bitmap
1419 * using BI_BITFIELDS, then a bug causes it to fail to include
1420 * the bytes for the bitfields. So, we have to substract out the
1421 * size of the bitfields previously included from bitmap_info_size. */
1422 if (compr == BI_BITFIELDS && (bpp == 16 || bpp == 32) &&
1423 pbmiCopy->bmiHeader.biSizeImage + pbmiCopy->bmiHeader.biSize == ResSize)
1424 {
1425 /* GCC pointer to the image data has 12 less bytes than MSVC */
1426 pvBits = (char*)pvBits - 12;
1427 WARN("Found GCC Resource Compiled 16-bpp or 32-bpp error\n");
1428 }
1429
1430 /* Fix it up, if needed */
1431 if(fuLoad & (LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS))
1432 {
1433 WORD bpp, incr, numColors;
1434 char* pbmiColors;
1435 RGBTRIPLE* ptr;
1436 COLORREF crWindow, cr3DShadow, cr3DFace, cr3DLight;
1437 BYTE pixel = *((BYTE*)pvBits);
1438 UINT i;
1439
1440 if(pbmiCopy->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1441 {
1442 bpp = ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcBitCount;
1443 numColors = 1 << bpp;
1444 /* BITMAPCOREINFO holds RGBTRIPLEs */
1445 incr = 3;
1446 }
1447 else
1448 {
1449 bpp = pbmiCopy->bmiHeader.biBitCount;
1450 /* BITMAPINFOHEADER holds RGBQUADs */
1451 incr = 4;
1452 numColors = pbmiCopy->bmiHeader.biClrUsed;
1453 if(numColors > 256) numColors = 256;
1454 if (!numColors && (bpp <= 8)) numColors = 1 << bpp;
1455 }
1456
1457 if(bpp > 8)
1458 goto create_bitmap;
1459
1460 pbmiColors = (char*)pbmiCopy + pbmiCopy->bmiHeader.biSize;
1461
1462 /* Get the relevant colors */
1463 crWindow = GetSysColor(COLOR_WINDOW);
1464 cr3DShadow = GetSysColor(COLOR_3DSHADOW);
1465 cr3DFace = GetSysColor(COLOR_3DFACE);
1466 cr3DLight = GetSysColor(COLOR_3DLIGHT);
1467
1468 /* Fix the transparent palette entry */
1469 if(fuLoad & LR_LOADTRANSPARENT)
1470 {
1471 switch(bpp)
1472 {
1473 case 1: pixel >>= 7; break;
1474 case 4: pixel >>= 4; break;
1475 case 8: break;
1476 default:
1477 FIXME("Unhandled bit depth %d.\n", bpp);
1478 goto create_bitmap;
1479 }
1480
1481 if(pixel >= numColors)
1482 {
1483 ERR("Wrong pixel passed in.\n");
1484 goto create_bitmap;
1485 }
1486
1487 /* If both flags are set, we must use COLOR_3DFACE */
1488 if(fuLoad & LR_LOADMAP3DCOLORS) crWindow = cr3DFace;
1489
1490 /* Define the color */
1491 ptr = (RGBTRIPLE*)(pbmiColors + pixel*incr);
1492 ptr->rgbtBlue = GetBValue(crWindow);
1493 ptr->rgbtGreen = GetGValue(crWindow);
1494 ptr->rgbtRed = GetRValue(crWindow);
1495 goto create_bitmap;
1496 }
1497
1498 /* If we are here, then LR_LOADMAP3DCOLORS is set without LR_TRANSPARENT */
1499 for(i = 0; i<numColors; i++)
1500 {
1501 ptr = (RGBTRIPLE*)(pbmiColors + i*incr);
1502 if((ptr->rgbtBlue == ptr->rgbtRed) && (ptr->rgbtBlue == ptr->rgbtGreen))
1503 {
1504 if(ptr->rgbtBlue == 128)
1505 {
1506 ptr->rgbtBlue = GetBValue(cr3DShadow);
1507 ptr->rgbtGreen = GetGValue(cr3DShadow);
1508 ptr->rgbtRed = GetRValue(cr3DShadow);
1509 }
1510 if(ptr->rgbtBlue == 192)
1511 {
1512 ptr->rgbtBlue = GetBValue(cr3DFace);
1513 ptr->rgbtGreen = GetGValue(cr3DFace);
1514 ptr->rgbtRed = GetRValue(cr3DFace);
1515 }
1516 if(ptr->rgbtBlue == 223)
1517 {
1518 ptr->rgbtBlue = GetBValue(cr3DLight);
1519 ptr->rgbtGreen = GetGValue(cr3DLight);
1520 ptr->rgbtRed = GetRValue(cr3DLight);
1521 }
1522 }
1523 }
1524 }
1525
1527 if(fuLoad & LR_CREATEDIBSECTION)
1528 {
1529 /* Allocate the BMI describing the new bitmap */
1530 pbmiScaled = HeapAlloc(GetProcessHeap(), 0, iBMISize);
1531 if(!pbmiScaled)
1532 goto end;
1533 CopyMemory(pbmiScaled, pbmiCopy, iBMISize);
1534
1535 /* Fix it up */
1536 if(pbmiScaled->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1537 {
1538 BITMAPCOREHEADER* pbmch = (BITMAPCOREHEADER*)&pbmiScaled->bmiHeader;
1539 pbmch->bcWidth = cxDesired;
1540 pbmch->bcHeight = cyDesired;
1541 }
1542 else
1543 {
1544 pbmiScaled->bmiHeader.biWidth = cxDesired;
1545 pbmiScaled->bmiHeader.biHeight = cyDesired;
1546 /* No compression for DIB sections */
1547 pbmiScaled->bmiHeader.biCompression = BI_RGB;
1548 }
1549 }
1550
1551 /* Top-down image */
1552 if(cyDesired < 0) cyDesired = -cyDesired;
1553
1554 /* We need a device context */
1555 hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
1556 if(!hdcScreen)
1557 goto end;
1558 hdc = CreateCompatibleDC(hdcScreen);
1559 if(!hdc)
1560 goto end;
1561
1562 /* Now create the bitmap */
1563 if(fuLoad & LR_CREATEDIBSECTION)
1564 hbmpRet = CreateDIBSection(hdc, pbmiScaled, DIB_RGB_COLORS, NULL, 0, 0);
1565 else
1566 {
1567 if(is_dib_monochrome(pbmiCopy) || (fuLoad & LR_MONOCHROME))
1568 hbmpRet = CreateBitmap(cxDesired, cyDesired, 1, 1, NULL);
1569 else
1570 hbmpRet = CreateCompatibleBitmap(hdcScreen, cxDesired, cyDesired);
1571 }
1572
1573 if(!hbmpRet)
1574 goto end;
1575
1576 hbmpOld = SelectObject(hdc, hbmpRet);
1577 if(!hbmpOld)
1578 goto end;
1579 if(!StretchDIBits(hdc, 0, 0, cxDesired, cyDesired,
1580 0, 0, width, height,
1581 pvBits, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
1582 {
1583 ERR("StretchDIBits failed!.\n");
1585 DeleteObject(hbmpRet);
1586 hbmpRet = NULL;
1587 goto end;
1588 }
1589
1591
1592end:
1593 if(hdcScreen)
1594 DeleteDC(hdcScreen);
1595 if(hdc)
1596 DeleteDC(hdc);
1597 if(pbmiScaled)
1598 HeapFree(GetProcessHeap(), 0, pbmiScaled);
1599 if(pbmiCopy)
1600 HeapFree(GetProcessHeap(), 0, pbmiCopy);
1601 if (pvMapping)
1602 UnmapViewOfFile( pvMapping );
1603 if(hgRsrc)
1604 FreeResource(hgRsrc);
1605
1606 return hbmpRet;
1607}
1608
1609
1610static
1611HANDLE
1613 _In_ LPCWSTR lpszName,
1614 _In_ int cxDesired,
1615 _In_ int cyDesired,
1616 _In_ UINT fuLoad,
1617 _In_ BOOL bIcon
1618)
1619{
1621 const CURSORICONFILEDIR *dir;
1622 DWORD filesize = 0, BmpIconSize;
1623 PBYTE bits, pbBmpIcon = NULL;
1624 HANDLE hCurIcon = NULL;
1625 CURSORDATA cursorData = { 0 };
1626
1627 TRACE("loading %s\n", debugstr_w( lpszName ));
1628
1629 bits = map_fileW( lpszName, &filesize );
1630 if (!bits)
1631 return NULL;
1632
1633 /* Check for .ani. */
1634 if (memcmp( bits, "RIFF", 4 ) == 0)
1635 {
1637 goto end;
1638 }
1639
1641 entry = get_best_icon_file_entry(dir, filesize, cxDesired, cyDesired, bIcon, fuLoad);
1642 if(!entry)
1643 goto end;
1644
1645 /* Fix dimensions */
1646 if(!cxDesired) cxDesired = entry->bWidth;
1647 if(!cyDesired) cyDesired = entry->bHeight;
1648 /* A bit of preparation */
1649 if(!bIcon)
1650 {
1651 cursorData.xHotspot = entry->xHotspot;
1652 cursorData.yHotspot = entry->yHotspot;
1653 }
1654 cursorData.rt = LOWORD(bIcon ? RT_ICON : RT_CURSOR);
1655
1656 /* Try to load BMP icon */
1657 if (!CURSORICON_GetCursorDataFromBMI(&cursorData, (PBITMAPINFO)(&bits[entry->dwDIBOffset])))
1658 {
1659 /* Convert PNG raw data to BMP icon if the icon was PNG icon */
1660 PBYTE pngBits = &bits[entry->dwDIBOffset];
1661 pbBmpIcon = CURSORICON_ConvertPngToBmpIcon(pngBits, filesize, &BmpIconSize);
1662 if (!pbBmpIcon)
1663 goto end; /* Not PNG icon or failed */
1664
1665 /* Find icon entry from BMP icon */
1666 dir = (CURSORICONFILEDIR *)pbBmpIcon;
1667 entry = &dir->idEntries[0]; /* Only one entry */
1668
1669 /* A bit of preparation */
1670 ZeroMemory(&cursorData, sizeof(cursorData));
1671 cursorData.rt = LOWORD(bIcon ? RT_ICON : RT_CURSOR);
1672
1673 /* Can we load this BMP icon? */
1674 if (!CURSORICON_GetCursorDataFromBMI(&cursorData, (PBITMAPINFO)(&pbBmpIcon[entry->dwDIBOffset])))
1675 {
1676 ERR("Failing file: '%S'.\n", lpszName);
1677 goto end;
1678 }
1679
1680 TRACE("Processing PNG/Vista icon: '%S'\n", lpszName);
1681 }
1682
1684 if(!hCurIcon)
1685 goto end;
1686
1687 /* Tell win32k */
1688 if(!NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData))
1689 {
1690 NtUserDestroyCursor(hCurIcon, TRUE);
1691 hCurIcon = NULL;
1692 }
1693
1694end:
1695 if (!hCurIcon)
1696 {
1697 if (cursorData.hbmMask) DeleteObject(cursorData.hbmMask);
1698 if (cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
1699 if (cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
1700 }
1701 HeapFree(GetProcessHeap(), 0, pbBmpIcon);
1703 return hCurIcon;
1704}
1705
1706static
1707HANDLE
1710 _In_ LPCWSTR lpszName,
1711 _In_ int cxDesired,
1712 _In_ int cyDesired,
1713 _In_ UINT fuLoad,
1714 _In_ BOOL bIcon
1715)
1716{
1717 HRSRC hrsrc;
1718 HANDLE handle, hCurIcon = NULL;
1720 WORD wResId;
1721 LPBYTE bits;
1722 CURSORDATA cursorData;
1723 BOOL bStatus;
1724 UNICODE_STRING ustrRsrc;
1725 UNICODE_STRING ustrModule = {0, 0, NULL};
1726
1727 /* Fix width/height */
1728 if(fuLoad & LR_DEFAULTSIZE)
1729 {
1730 if(!cxDesired) cxDesired = GetSystemMetrics(bIcon ? SM_CXICON : SM_CXCURSOR);
1731 if(!cyDesired) cyDesired = GetSystemMetrics(bIcon ? SM_CYICON : SM_CYCURSOR);
1732 }
1733
1734 if(fuLoad & LR_LOADFROMFILE)
1735 {
1736 return CURSORICON_LoadFromFileW(lpszName, cxDesired, cyDesired, fuLoad, bIcon);
1737 }
1738
1739 /* Check if caller wants OEM icons */
1740 if(!hinst)
1742
1743 if(lpszName)
1744 {
1745 /* Prepare the resource name string */
1746 if(IS_INTRESOURCE(lpszName))
1747 {
1748 ustrRsrc.Buffer = (LPWSTR)lpszName;
1749 ustrRsrc.Length = 0;
1750 ustrRsrc.MaximumLength = 0;
1751 }
1752 else
1753 RtlInitUnicodeString(&ustrRsrc, lpszName);
1754 }
1755
1757 {
1758 /* We don't have a real module for GetModuleFileName, construct a fake name instead.
1759 * GetIconInfoEx reveals the name used by Windows. */
1760 LPCWSTR fakeNameFmt = sizeof(void*) > 4 ? L"\x01%016IX" : L"\x01%08IX";
1761 ustrModule.MaximumLength = 18 * sizeof(WCHAR);
1762 ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength);
1763 if (!ustrModule.Buffer)
1764 {
1766 return NULL;
1767 }
1768 ustrModule.Length = (USHORT)wsprintfW(ustrModule.Buffer, fakeNameFmt, hinst) * sizeof(WCHAR);
1769 }
1770 else if(hinst)
1771 {
1773 /* Get the module name string */
1774 while (TRUE)
1775 {
1776 DWORD ret;
1777 ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
1778 if (!ustrModule.Buffer)
1779 {
1781 return NULL;
1782 }
1783 ret = GetModuleFileNameW(hinst, ustrModule.Buffer, size);
1784 if(ret == 0)
1785 {
1786 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1787 return NULL;
1788 }
1789
1790 /* This API is completely broken... */
1791 if (ret == size)
1792 {
1793 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1794 size *= 2;
1795 continue;
1796 }
1797
1798 ustrModule.Buffer[ret] = UNICODE_NULL;
1799 ustrModule.Length = (USHORT)(ret * sizeof(WCHAR));
1800 ustrModule.MaximumLength = (USHORT)(size * sizeof(WCHAR));
1801 break;
1802 }
1803 }
1804
1805 if(fuLoad & LR_SHARED)
1806 {
1808
1809 TRACE("Checking for an LR_SHARED cursor/icon.\n");
1810 /* Ask win32k */
1811 param.bIcon = bIcon;
1812 param.cx = cxDesired;
1813 param.cy = cyDesired;
1814 hCurIcon = NtUserFindExistingCursorIcon(&ustrModule, &ustrRsrc, &param);
1815 if(hCurIcon)
1816 {
1817 /* Woohoo, got it! */
1818 TRACE("MATCH! %p\n",hCurIcon);
1819 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1820 return hCurIcon;
1821 }
1822 }
1823
1824 /* Find resource ID */
1825 hrsrc = FindResourceW(
1826 hinst,
1827 lpszName,
1828 bIcon ? RT_GROUP_ICON : RT_GROUP_CURSOR);
1829
1830 /* We let FindResource, LoadResource, etc. call SetLastError */
1831 if(!hrsrc)
1832 goto done;
1833
1834 handle = LoadResource(hinst, hrsrc);
1835 if(!handle)
1836 goto done;
1837
1839 if(!dir)
1840 goto done;
1841
1842 wResId = LookupIconIdFromDirectoryEx((PBYTE)dir, bIcon, cxDesired, cyDesired, fuLoad);
1844
1845 /* Get the relevant resource pointer */
1846 hrsrc = FindResourceW(
1847 hinst,
1848 MAKEINTRESOURCEW(wResId),
1849 bIcon ? RT_ICON : RT_CURSOR);
1850 if(!hrsrc)
1851 goto done;
1852
1853 handle = LoadResource(hinst, hrsrc);
1854 if(!handle)
1855 goto done;
1856
1858 if(!bits)
1859 {
1861 goto done;
1862 }
1863
1864 ZeroMemory(&cursorData, sizeof(cursorData));
1865
1866 /* This is from resource */
1868
1869 if(dir->idType == 2)
1870 {
1871 /* idType == 2 for cursor resources */
1872 SHORT* ptr = (SHORT*)bits;
1873 cursorData.xHotspot = ptr[0];
1874 cursorData.yHotspot = ptr[1];
1875 bits += 2*sizeof(SHORT);
1876 }
1877 cursorData.cx = cxDesired;
1878 cursorData.cy = cyDesired;
1879 cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR));
1880
1881 /* Get the bitmaps */
1883 &cursorData,
1884 (BITMAPINFO*)bits);
1885
1887
1888 if(!bStatus)
1889 goto done;
1890
1891 /* Create the handle */
1893 if(!hCurIcon)
1894 {
1895 goto end_error;
1896 }
1897
1898 if(fuLoad & LR_SHARED)
1899 {
1900 cursorData.CURSORF_flags |= CURSORF_LRSHARED;
1901 }
1902
1903 /* Tell win32k */
1904 bStatus = NtUserSetCursorIconData(hCurIcon, hinst ? &ustrModule : NULL, lpszName ? &ustrRsrc : NULL, &cursorData);
1905
1906 if(!bStatus)
1907 {
1908 NtUserDestroyCursor(hCurIcon, TRUE);
1909 goto end_error;
1910 }
1911
1912done:
1913 if(ustrModule.Buffer)
1914 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1915 return hCurIcon;
1916
1917end_error:
1918 if(ustrModule.Buffer)
1919 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1920 DeleteObject(cursorData.hbmMask);
1921 if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
1922 if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
1923
1924 return NULL;
1925}
1926
1927static
1928HBITMAP
1930 _In_ HBITMAP hnd,
1931 _In_ int desiredx,
1932 _In_ int desiredy,
1934)
1935{
1936 HBITMAP res = NULL;
1937 DIBSECTION ds;
1938 int objSize;
1939 BITMAPINFO * bi;
1940
1941 objSize = GetObjectW( hnd, sizeof(ds), &ds );
1942 if (!objSize) return 0;
1943 if ((desiredx < 0) || (desiredy < 0)) return 0;
1944
1946 {
1947 FIXME("The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
1948 }
1949
1950 if (flags & LR_COPYRETURNORG)
1951 {
1952 FIXME("The flag LR_COPYRETURNORG is not implemented for bitmaps\n");
1953 }
1954
1955 if (desiredx == 0) desiredx = ds.dsBm.bmWidth;
1956 if (desiredy == 0) desiredy = ds.dsBm.bmHeight;
1957
1958 /* Allocate memory for a BITMAPINFOHEADER structure and a
1959 color table. The maximum number of colors in a color table
1960 is 256 which corresponds to a bitmap with depth 8.
1961 Bitmaps with higher depths don't have color tables. */
1962 bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1963 if (!bi) return 0;
1964
1965 bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
1966 bi->bmiHeader.biPlanes = ds.dsBm.bmPlanes;
1967 bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
1969
1971 {
1972 /* Create a DIB section. LR_MONOCHROME is ignored */
1973 void * bits;
1975
1976 if (objSize == sizeof(DIBSECTION))
1977 {
1978 /* The source bitmap is a DIB.
1979 Get its attributes to create an exact copy */
1980 memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
1981 }
1982
1983 bi->bmiHeader.biWidth = desiredx;
1984 bi->bmiHeader.biHeight = desiredy;
1985
1986 /* Get the color table or the color masks */
1987 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
1988
1990 DeleteDC(dc);
1991 }
1992 else
1993 {
1994 /* Create a device-dependent bitmap */
1995
1996 BOOL monochrome = (flags & LR_MONOCHROME);
1997
1998 if (objSize == sizeof(DIBSECTION))
1999 {
2000 /* The source bitmap is a DIB section.
2001 Get its attributes */
2003 bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
2004 bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
2005 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
2006 DeleteDC(dc);
2007
2008 if (!monochrome && ds.dsBm.bmBitsPixel == 1)
2009 {
2010 /* Look if the colors of the DIB are black and white */
2011
2012 monochrome =
2013 (bi->bmiColors[0].rgbRed == 0xff
2014 && bi->bmiColors[0].rgbGreen == 0xff
2015 && bi->bmiColors[0].rgbBlue == 0xff
2016 && bi->bmiColors[0].rgbReserved == 0
2017 && bi->bmiColors[1].rgbRed == 0
2018 && bi->bmiColors[1].rgbGreen == 0
2019 && bi->bmiColors[1].rgbBlue == 0
2020 && bi->bmiColors[1].rgbReserved == 0)
2021 ||
2022 (bi->bmiColors[0].rgbRed == 0
2023 && bi->bmiColors[0].rgbGreen == 0
2024 && bi->bmiColors[0].rgbBlue == 0
2025 && bi->bmiColors[0].rgbReserved == 0
2026 && bi->bmiColors[1].rgbRed == 0xff
2027 && bi->bmiColors[1].rgbGreen == 0xff
2028 && bi->bmiColors[1].rgbBlue == 0xff
2029 && bi->bmiColors[1].rgbReserved == 0);
2030 }
2031 }
2032 else if (!monochrome)
2033 {
2034 monochrome = ds.dsBm.bmBitsPixel == 1;
2035 }
2036
2037 if (monochrome)
2038 {
2039 res = CreateBitmap(desiredx, desiredy, 1, 1, NULL);
2040 }
2041 else
2042 {
2043 HDC screenDC = GetDC(NULL);
2044 res = CreateCompatibleBitmap(screenDC, desiredx, desiredy);
2045 ReleaseDC(NULL, screenDC);
2046 }
2047 }
2048
2049 if (res)
2050 {
2051 /* Only copy the bitmap if it's a DIB section or if it's
2052 compatible to the screen */
2053 BOOL copyContents;
2054
2055 if (objSize == sizeof(DIBSECTION))
2056 {
2057 copyContents = TRUE;
2058 }
2059 else
2060 {
2061 HDC screenDC = GetDC(NULL);
2062 int screen_depth = GetDeviceCaps(screenDC, BITSPIXEL);
2063 ReleaseDC(NULL, screenDC);
2064
2065 copyContents = (ds.dsBm.bmBitsPixel == 1 || ds.dsBm.bmBitsPixel == screen_depth);
2066 }
2067
2068 if (copyContents)
2069 {
2070 /* The source bitmap may already be selected in a device context,
2071 use GetDIBits/StretchDIBits and not StretchBlt */
2072
2073 HDC dc;
2074 void * bits;
2075
2077
2078 bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
2079 bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
2080 bi->bmiHeader.biSizeImage = 0;
2081 bi->bmiHeader.biClrUsed = 0;
2082 bi->bmiHeader.biClrImportant = 0;
2083
2084 /* Fill in biSizeImage */
2085 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
2087
2088 if (bits)
2089 {
2090 HBITMAP oldBmp;
2091
2092 /* Get the image bits of the source bitmap */
2093 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
2094
2095 /* Copy it to the destination bitmap */
2096 oldBmp = SelectObject(dc, res);
2097 StretchDIBits(dc, 0, 0, desiredx, desiredy,
2098 0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight,
2100 SelectObject(dc, oldBmp);
2101
2103 }
2104
2105 DeleteDC(dc);
2106 }
2107
2108 if (flags & LR_COPYDELETEORG)
2109 {
2110 DeleteObject(hnd);
2111 }
2112 }
2113 HeapFree(GetProcessHeap(), 0, bi);
2114 return res;
2115}
2116
2117static
2118HICON
2120 _In_ HICON hicon,
2121 _In_ BOOL bIcon,
2122 _In_ int cxDesired,
2123 _In_ int cyDesired,
2124 _In_ UINT fuFlags
2125)
2126{
2127 HICON ret = NULL;
2128 ICONINFO ii;
2129 CURSORDATA CursorData;
2130
2131 if (fuFlags & LR_COPYFROMRESOURCE)
2132 {
2133 /* Get the icon module/resource names */
2134 UNICODE_STRING ustrModule;
2135 UNICODE_STRING ustrRsrc;
2137
2138 ustrModule.MaximumLength = 0;
2139 ustrRsrc.MaximumLength = 0;
2140
2141 /* Get the buffer size */
2142 if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
2143 {
2144 return NULL;
2145 }
2146
2147 ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength);
2148 if (!ustrModule.Buffer)
2149 {
2151 return NULL;
2152 }
2153
2154 if (ustrRsrc.MaximumLength)
2155 {
2156 ustrRsrc.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength);
2157 if (!ustrRsrc.Buffer)
2158 {
2159 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
2161 return NULL;
2162 }
2163 }
2164
2165 if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
2166 {
2167 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
2168 if (!IS_INTRESOURCE(ustrRsrc.Buffer))
2169 HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer);
2170 return NULL;
2171 }
2172
2173 /* NULL-terminate our strings */
2174 ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = UNICODE_NULL;
2175 if (!IS_INTRESOURCE(ustrRsrc.Buffer))
2176 ustrRsrc.Buffer[ustrRsrc.Length/sizeof(WCHAR)] = UNICODE_NULL;
2177
2178 TRACE("Got module %wZ, resource %p (%S).\n", &ustrModule,
2179 ustrRsrc.Buffer, IS_INTRESOURCE(ustrRsrc.Buffer) ? L"" : ustrRsrc.Buffer);
2180
2181 /* Get the module handle or load the module */
2182 hModule = LoadLibraryExW(ustrModule.Buffer, NULL, /* NT6+: LOAD_LIBRARY_AS_IMAGE_RESOURCE | */ LOAD_LIBRARY_AS_DATAFILE);
2183 if (!hModule)
2184 {
2186 ERR("Unable to load/use module '%wZ' in process %lu, error %lu.\n", &ustrModule, GetCurrentProcessId(), err);
2188 goto leave;
2189 }
2190
2191 /* Call the relevant function */
2193 hModule,
2194 ustrRsrc.Buffer,
2195 cxDesired,
2196 cyDesired,
2197 fuFlags & (LR_DEFAULTSIZE | LR_SHARED),
2198 bIcon);
2199
2201
2202 /* If we're here, that means that the passed icon is shared. Don't destroy it, even if LR_COPYDELETEORG is specified */
2203 leave:
2204 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
2205 if (!IS_INTRESOURCE(ustrRsrc.Buffer))
2206 HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer);
2207
2208 TRACE("Returning 0x%08x.\n", ret);
2209
2210 return ret;
2211 }
2212
2213 /* This is a regular copy */
2214 if (fuFlags & ~(LR_COPYDELETEORG | LR_SHARED))
2215 FIXME("Unimplemented flags: 0x%08x\n", fuFlags);
2216
2217 if (!GetIconInfo(hicon, &ii))
2218 {
2219 ERR("GetIconInfo failed.\n");
2220 return NULL;
2221 }
2222
2223 /* This is CreateIconIndirect with the LR_SHARED coat added */
2224 if (!CURSORICON_GetCursorDataFromIconInfo(&CursorData, &ii))
2225 goto Leave;
2226
2227 if (fuFlags & LR_SHARED)
2228 CursorData.CURSORF_flags |= CURSORF_LRSHARED;
2229
2231 if (!ret)
2232 goto Leave;
2233
2234 if (!NtUserSetCursorIconData(ret, NULL, NULL, &CursorData))
2235 {
2237 goto Leave;
2238 }
2239
2240Leave:
2242 if (ii.hbmColor) DeleteObject(ii.hbmColor);
2243
2244 if (ret && (fuFlags & LR_COPYDELETEORG))
2245 DestroyIcon(hicon);
2246
2247 return ret;
2248}
2249
2252{
2254 HANDLE Result;
2255 Common = (PCOPYIMAGE_CALLBACK_ARGUMENTS) Arguments;
2256
2257 Result = CopyImage(Common->hImage,
2258 Common->uType,
2259 Common->cxDesired,
2260 Common->cyDesired,
2261 Common->fuFlags);
2262
2263 return ZwCallbackReturn(&Result, sizeof(HANDLE), STATUS_SUCCESS);
2264}
2265
2266
2267/************* PUBLIC FUNCTIONS *******************/
2268
2269#define COPYIMAGE_VALID_FLAGS ( \
2270 LR_SHARED | LR_COPYFROMRESOURCE | LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS | 0x800 | \
2271 LR_VGACOLOR | LR_LOADREALSIZE | LR_DEFAULTSIZE | LR_LOADTRANSPARENT | LR_LOADFROMFILE | \
2272 LR_COPYDELETEORG | LR_COPYRETURNORG | LR_COLOR | LR_MONOCHROME \
2273)
2274
2276 _In_ HANDLE hImage,
2277 _In_ UINT uType,
2278 _In_ int cxDesired,
2279 _In_ int cyDesired,
2280 _In_ UINT fuFlags
2281)
2282{
2283 TRACE("hImage=%p, uType=%u, cxDesired=%d, cyDesired=%d, fuFlags=%x\n",
2284 hImage, uType, cxDesired, cyDesired, fuFlags);
2285
2286 if (fuFlags & ~COPYIMAGE_VALID_FLAGS)
2287 {
2289 return NULL;
2290 }
2291
2292 switch(uType)
2293 {
2294 case IMAGE_BITMAP:
2295 if (!hImage)
2296 {
2298 break;
2299 }
2300 return BITMAP_CopyImage(hImage, cxDesired, cyDesired, fuFlags);
2301 case IMAGE_CURSOR:
2302 case IMAGE_ICON:
2303 {
2304 HANDLE handle;
2305 if (!hImage)
2306 {
2308 break;
2309 }
2310 handle = CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, cxDesired, cyDesired, fuFlags);
2311 if (!handle && (fuFlags & LR_COPYFROMRESOURCE))
2312 {
2313 /* Test if the hImage is the same size as what we want by getting
2314 * its BITMAP and comparing its dimensions to the desired size. */
2315 BITMAP bm;
2316
2317 ICONINFO iconinfo = { 0 };
2318 if (!GetIconInfo(hImage, &iconinfo))
2319 {
2320 ERR("GetIconInfo Failed. hImage %p\n", hImage);
2321 return NULL;
2322 }
2323 if (!GetObject(iconinfo.hbmColor, sizeof(bm), &bm))
2324 {
2325 ERR("GetObject Failed. iconinfo %p\n", iconinfo);
2326 return NULL;
2327 }
2328
2329 DeleteObject(iconinfo.hbmMask);
2330 DeleteObject(iconinfo.hbmColor);
2331
2332 /* If the images are the same size remove LF_COPYFROMRESOURCE and try again */
2333 if (cxDesired == bm.bmWidth && cyDesired == bm.bmHeight)
2334 {
2335 handle = CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, cxDesired,
2336 cyDesired, (fuFlags & ~LR_COPYFROMRESOURCE));
2337 }
2338 }
2339 return handle;
2340 }
2341 default:
2343 break;
2344 }
2345 return NULL;
2346}
2347
2350)
2351{
2352 return CURSORICON_CopyImage(hIcon, FALSE, 0, 0, 0);
2353}
2354
2356 _In_ HDC hDC,
2357 _In_ int X,
2358 _In_ int Y,
2360)
2361{
2362 return DrawIconEx(hDC, X, Y, hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
2363}
2364
2366 _In_ HDC hdc,
2367 _In_ int xLeft,
2368 _In_ int yTop,
2370 _In_ int cxWidth,
2371 _In_ int cyWidth,
2372 _In_ UINT istepIfAniCur,
2373 _In_opt_ HBRUSH hbrFlickerFreeDraw,
2374 _In_ UINT diFlags
2375)
2376{
2377 return NtUserDrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth,
2378 istepIfAniCur, hbrFlickerFreeDraw, diFlags,
2379 0, 0);
2380}
2381
2384 _Out_ PICONINFO piconinfo
2385)
2386{
2387 return NtUserGetIconInfo(hIcon, piconinfo, NULL, NULL, NULL, FALSE);
2388}
2389
2392)
2393{
2395}
2396
2399 _In_ LPCSTR lpIconName
2400)
2401{
2402 TRACE("%p, %s\n", hInstance, debugstr_a(lpIconName));
2403
2404 return LoadImageA(hInstance,
2405 lpIconName,
2406 IMAGE_ICON,
2407 0,
2408 0,
2410}
2411
2414 _In_ LPCWSTR lpIconName
2415)
2416{
2417 TRACE("%p, %s\n", hInstance, debugstr_w(lpIconName));
2418
2419 return LoadImageW(hInstance,
2420 lpIconName,
2421 IMAGE_ICON,
2422 0,
2423 0,
2425}
2426
2429 _In_ LPCSTR lpCursorName
2430)
2431{
2432 TRACE("%p, %s\n", hInstance, debugstr_a(lpCursorName));
2433
2434 return LoadImageA(hInstance,
2435 lpCursorName,
2437 0,
2438 0,
2440}
2441
2444 _In_ LPCWSTR lpCursorName
2445)
2446{
2447 TRACE("%p, %s\n", hInstance, debugstr_w(lpCursorName));
2448
2449 return LoadImageW(hInstance,
2450 lpCursorName,
2452 0,
2453 0,
2455}
2456
2459)
2460{
2461 TRACE("%s\n", debugstr_a(lpFileName));
2462
2463 return LoadImageA(NULL,
2464 lpFileName,
2466 0,
2467 0,
2469}
2470
2473)
2474{
2475 TRACE("%s\n", debugstr_w(lpFileName));
2476
2477 return LoadImageW(NULL,
2478 lpFileName,
2480 0,
2481 0,
2483}
2484
2487 _In_ LPCSTR lpBitmapName
2488)
2489{
2490 TRACE("%p, %s\n", hInstance, debugstr_a(lpBitmapName));
2491
2492 return LoadImageA(hInstance,
2493 lpBitmapName,
2495 0,
2496 0,
2497 0);
2498}
2499
2502 _In_ LPCWSTR lpBitmapName
2503)
2504{
2505 TRACE("%p, %s\n", hInstance, debugstr_w(lpBitmapName));
2506
2507 return LoadImageW(hInstance,
2508 lpBitmapName,
2510 0,
2511 0,
2512 0);
2513}
2514
2517 _In_ LPCSTR lpszName,
2518 _In_ UINT uType,
2519 _In_ int cxDesired,
2520 _In_ int cyDesired,
2521 _In_ UINT fuLoad
2522)
2523{
2524 HANDLE res;
2525 LPWSTR u_name;
2526 DWORD len;
2527
2528 if (IS_INTRESOURCE(lpszName))
2529 return LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired, cyDesired, fuLoad);
2530
2531 len = MultiByteToWideChar( CP_ACP, 0, lpszName, -1, NULL, 0 );
2532 u_name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2533 MultiByteToWideChar( CP_ACP, 0, lpszName, -1, u_name, len );
2534
2535 res = LoadImageW(hinst, u_name, uType, cxDesired, cyDesired, fuLoad);
2536 HeapFree(GetProcessHeap(), 0, u_name);
2537 return res;
2538}
2539
2542 _In_ LPCWSTR lpszName,
2543 _In_ UINT uType,
2544 _In_ int cxDesired,
2545 _In_ int cyDesired,
2546 _In_ UINT fuLoad
2547)
2548{
2549 TRACE("hinst 0x%p, name %s, uType 0x%08x, cxDesired %d, cyDesired %d, fuLoad 0x%08x.\n",
2550 hinst, debugstr_w(lpszName), uType, cxDesired, cyDesired, fuLoad);
2551 /* Redirect to each implementation */
2552 switch(uType)
2553 {
2554 case IMAGE_BITMAP:
2555 return BITMAP_LoadImageW(hinst, lpszName, cxDesired, cyDesired, fuLoad);
2556 case IMAGE_CURSOR:
2557 case IMAGE_ICON:
2558 return CURSORICON_LoadImageW(hinst, lpszName, cxDesired, cyDesired, fuLoad, uType == IMAGE_ICON);
2559 default:
2561 break;
2562 }
2563 return NULL;
2564}
2565
2567 _In_ PBYTE presbits,
2568 _In_ BOOL fIcon
2569)
2570{
2571 return LookupIconIdFromDirectoryEx( presbits, fIcon,
2574}
2575
2577 _In_ PBYTE presbits,
2578 _In_ BOOL fIcon,
2579 _In_ int cxDesired,
2580 _In_ int cyDesired,
2582)
2583{
2584 WORD bppDesired;
2585 CURSORICONDIR* dir = (CURSORICONDIR*)presbits;
2587 int i, numMatch = 0, iIndex = -1;
2588 WORD width, height, BitCount = 0;
2589 BOOL notPaletted = FALSE;
2590 ULONG bestScore = 0xFFFFFFFF, score;
2591
2592 TRACE("%p, %x, %i, %i, %x.\n", presbits, fIcon, cxDesired, cyDesired, Flags);
2593
2594 if(!(dir && !dir->idReserved && (dir->idType & 3)))
2595 {
2596 WARN("Invalid resource.\n");
2597 return 0;
2598 }
2599
2600 if(Flags & LR_MONOCHROME)
2601 bppDesired = 1;
2602 else
2603 {
2604 HDC icScreen;
2605 icScreen = CreateICW(DISPLAYW, NULL, NULL, NULL);
2606 if(!icScreen)
2607 return FALSE;
2608
2609 bppDesired = GetDeviceCaps(icScreen, BITSPIXEL);
2610 DeleteDC(icScreen);
2611 }
2612
2613 if(!cxDesired)
2614 cxDesired = Flags & LR_DEFAULTSIZE ? GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR) : 256;
2615 if(!cyDesired)
2616 cyDesired = Flags & LR_DEFAULTSIZE ? GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR) : 256;
2617
2618 /* Find the best match for the desired size */
2619 for(i = 0; i < dir->idCount; i++)
2620 {
2621 entry = &dir->idEntries[i];
2622 width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2623 /* Height is twice as big in cursor resources */
2624 height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2625 /* 0 represents 256 */
2626 if(!width) width = 256;
2627 if(!height) height = 256;
2628 /* Calculate the "score" (lower is better) */
2629 score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2630 if( score > bestScore)
2631 continue;
2632 /* Bigger than requested lowers the score */
2633 if(width > cxDesired)
2634 score -= width - cxDesired;
2635 if(height > cyDesired)
2636 score -= height - cyDesired;
2637 if(score > bestScore)
2638 continue;
2639 if(score == bestScore)
2640 {
2641 if(entry->wBitCount > BitCount)
2642 BitCount = entry->wBitCount;
2643 numMatch++;
2644 continue;
2645 }
2646 iIndex = i;
2647 numMatch = 1;
2648 bestScore = score;
2649 BitCount = entry->wBitCount;
2650 }
2651
2652 if(numMatch == 1)
2653 {
2654 /* Only one entry fits the asked dimensions */
2655 return dir->idEntries[iIndex].wResId;
2656 }
2657
2658 /* Avoid paletted icons on non-paletted device */
2659 if (bppDesired > 8 && BitCount > 8)
2660 notPaletted = TRUE;
2661
2662 BitCount = 0;
2663 iIndex = -1;
2664 /* Now find the entry with the best depth */
2665 for(i = 0; i < dir->idCount; i++)
2666 {
2667 entry = &dir->idEntries[i];
2668 width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2669 height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2670 /* 0 represents 256 */
2671 if(!width) width = 256;
2672 if(!height) height = 256;
2673 /* Check if this is the best match we had */
2674 score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2675 if(width > cxDesired)
2676 score -= width - cxDesired;
2677 if(height > cyDesired)
2678 score -= height - cyDesired;
2679 if(score != bestScore)
2680 continue;
2681 /* Exact match? */
2682 if(entry->wBitCount == bppDesired)
2683 return entry->wResId;
2684 /* We take the highest possible but smaller than the display depth */
2685 if((entry->wBitCount > BitCount) && (entry->wBitCount < bppDesired))
2686 {
2687 /* Avoid paletted icons on non paletted devices */
2688 if ((entry->wBitCount <= 8) && notPaletted)
2689 continue;
2690 iIndex = i;
2691 BitCount = entry->wBitCount;
2692 }
2693 }
2694
2695 if(iIndex >= 0)
2696 return dir->idEntries[iIndex].wResId;
2697
2698 /* No inferior or equal depth available. Get the smallest bigger one */
2699 BitCount = 0xFFFF;
2700 iIndex = -1;
2701 for(i = 0; i < dir->idCount; i++)
2702 {
2703 entry = &dir->idEntries[i];
2704 width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2705 height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2706 /* 0 represents 256 */
2707 if(!width) width = 256;
2708 if(!height) height = 256;
2709 /* Check if this is the best match we had */
2710 score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2711 if(width > cxDesired)
2712 score -= width - cxDesired;
2713 if(height > cyDesired)
2714 score -= height - cyDesired;
2715 if(score != bestScore)
2716 continue;
2717 /* Check the bit depth */
2718 if(entry->wBitCount < BitCount)
2719 {
2720 if((entry->wBitCount <= 8) && notPaletted)
2721 continue;
2722 iIndex = i;
2723 BitCount = entry->wBitCount;
2724 }
2725 }
2726 if (iIndex >= 0)
2727 return dir->idEntries[iIndex].wResId;
2728
2729 return 0;
2730}
2731
2734 _In_ int nWidth,
2735 _In_ int nHeight,
2736 _In_ BYTE cPlanes,
2737 _In_ BYTE cBitsPixel,
2738 _In_ const BYTE *lpbANDbits,
2739 _In_ const BYTE *lpbXORbits
2740)
2741{
2742 ICONINFO iinfo;
2743 HICON hIcon;
2744
2745 TRACE_(icon)("%dx%d, planes %d, bpp %d, xor %p, and %p\n",
2746 nWidth, nHeight, cPlanes, cBitsPixel, lpbXORbits, lpbANDbits);
2747
2748 iinfo.fIcon = TRUE;
2749 iinfo.xHotspot = nWidth / 2;
2750 iinfo.yHotspot = nHeight / 2;
2751 if (cPlanes * cBitsPixel > 1)
2752 {
2753 iinfo.hbmColor = CreateBitmap( nWidth, nHeight, cPlanes, cBitsPixel, lpbXORbits );
2754 iinfo.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, lpbANDbits );
2755 }
2756 else
2757 {
2758 iinfo.hbmMask = CreateBitmap( nWidth, nHeight * 2, 1, 1, lpbANDbits );
2759 iinfo.hbmColor = NULL;
2760 }
2761
2762 hIcon = CreateIconIndirect( &iinfo );
2763
2764 DeleteObject( iinfo.hbmMask );
2765 if (iinfo.hbmColor) DeleteObject( iinfo.hbmColor );
2766
2767 return hIcon;
2768}
2769
2771 _In_ PBYTE presbits,
2772 _In_ DWORD dwResSize,
2773 _In_ BOOL fIcon,
2774 _In_ DWORD dwVer
2775)
2776{
2777 return CreateIconFromResourceEx( presbits, dwResSize, fIcon, dwVer, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
2778}
2779
2781 _In_ PBYTE pbIconBits,
2782 _In_ DWORD cbIconBits,
2783 _In_ BOOL fIcon,
2785 _In_ int cxDesired,
2786 _In_ int cyDesired,
2788)
2789{
2790 CURSORDATA cursorData;
2791 HICON hIcon;
2792 BOOL isAnimated;
2793 PBYTE pbBmpIcon = NULL;
2794 DWORD BmpIconSize;
2795
2796 TRACE("%p, %lu, %lu, %lu, %i, %i, %lu.\n", pbIconBits, cbIconBits, fIcon, dwVersion, cxDesired, cyDesired, uFlags);
2797
2798 if (!pbIconBits || cbIconBits < 2 * sizeof(DWORD))
2799 {
2800 ERR("Invalid IconBits array\n");
2801 return NULL;
2802 }
2803
2805 {
2806 if(!cxDesired) cxDesired = GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR);
2807 if(!cyDesired) cyDesired = GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR);
2808 }
2809
2810 ZeroMemory(&cursorData, sizeof(cursorData));
2811 cursorData.cx = cxDesired;
2812 cursorData.cy = cyDesired;
2813 cursorData.rt = LOWORD(fIcon ? RT_ICON : RT_CURSOR);
2814
2815 /* Convert to win32k-ready data */
2816 if(!memcmp(pbIconBits, "RIFF", 4))
2817 {
2818 if(!CURSORICON_GetCursorDataFromANI(&cursorData, pbIconBits, cbIconBits, uFlags))
2819 {
2820 ERR("Could not get cursor data from .ani.\n");
2821 return NULL;
2822 }
2823 isAnimated = !!(cursorData.CURSORF_flags & CURSORF_ACON);
2824 }
2825 else
2826 {
2827 /* It is possible to pass Icon Directories to this API */
2828 int wResId = LookupIconIdFromDirectoryEx(pbIconBits, fIcon, cxDesired, cyDesired, uFlags);
2829 HANDLE ResHandle = NULL;
2830#ifdef __REACTOS__
2831 if (wResId && (pbIconBits[4] != sizeof(BITMAPINFOHEADER)))
2832#else
2833 if(wResId)
2834#endif
2835 {
2837 HRSRC hrsrc;
2838 CURSORICONDIR* pCurIconDir = (CURSORICONDIR*)pbIconBits;
2839
2840 TRACE("Pointer points to a directory structure.\n");
2841
2842 /* So this is a pointer to an icon directory structure. Find the module */
2843 if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
2844 (LPCWSTR)pbIconBits,
2845 &hinst))
2846 {
2847 return NULL;
2848 }
2849
2850 /* Check we were given the right type of resource */
2851 if((fIcon && pCurIconDir->idType == 2) || (!fIcon && pCurIconDir->idType == 1))
2852 {
2853 WARN("Got a %s directory pointer, but called for a %s\n", fIcon ? "cursor" : "icon", fIcon ? "icon" : "cursor");
2854 return NULL;
2855 }
2856
2857 /* Get the relevant resource pointer */
2858 hrsrc = FindResourceW(
2859 hinst,
2860 MAKEINTRESOURCEW(wResId),
2861 fIcon ? RT_ICON : RT_CURSOR);
2862 if (!hrsrc)
2863 return NULL;
2864
2865 ResHandle = LoadResource(hinst, hrsrc);
2866 if (!ResHandle)
2867 return NULL;
2868
2869 pbIconBits = LockResource(ResHandle);
2870 if (!pbIconBits)
2871 {
2872 FreeResource(ResHandle);
2873 return NULL;
2874 }
2875 }
2876 if(!fIcon)
2877 {
2878 WORD* pt = (WORD*)pbIconBits;
2879 cursorData.xHotspot = *pt++;
2880 cursorData.yHotspot = *pt++;
2881 pbIconBits = (PBYTE)pt;
2882 }
2883
2884 isAnimated = FALSE;
2885
2886 /* Try to load BMP icon */
2887 if (!CURSORICON_GetCursorDataFromBMI(&cursorData, (PBITMAPINFO)pbIconBits))
2888 {
2889 /* Convert PNG raw data to BMP icon if the icon was PNG icon */
2890 pbBmpIcon = CURSORICON_ConvertPngToBmpIcon(pbIconBits, cbIconBits, &BmpIconSize);
2891 if (!pbBmpIcon)
2892 return NULL; /* Not PNG icon or failed */
2893
2894 /* Find icon entry from BMP icon */
2895 CURSORICONFILEDIR *dir = (CURSORICONFILEDIR *)pbBmpIcon;
2896 CURSORICONFILEDIRENTRY *entry = &dir->idEntries[0]; /* Only one entry */
2897
2898 /* A bit of preparation */
2899 RtlZeroMemory(&cursorData, sizeof(cursorData));
2900 cursorData.rt = LOWORD(fIcon ? RT_ICON : RT_CURSOR);
2901
2902 /* Can we load this BMP icon? */
2903 if (!CURSORICON_GetCursorDataFromBMI(&cursorData, (PBITMAPINFO)&pbBmpIcon[entry->dwDIBOffset]))
2904 {
2905 ERR("Couldn't get cursor/icon data\n");
2906 goto end_error;
2907 }
2908 }
2909 }
2910
2911 if (uFlags & LR_SHARED)
2912 cursorData.CURSORF_flags |= CURSORF_LRSHARED;
2913
2914 hIcon = NtUserxCreateEmptyCurObject(isAnimated);
2915 if (!hIcon)
2916 goto end_error;
2917
2918 if(!NtUserSetCursorIconData(hIcon, NULL, NULL, &cursorData))
2919 {
2920 ERR("NtUserSetCursorIconData failed.\n");
2922 goto end_error;
2923 }
2924
2925 if(isAnimated)
2926 HeapFree(GetProcessHeap(), 0, cursorData.aspcur);
2927
2928 HeapFree(GetProcessHeap(), 0, pbBmpIcon);
2929 return hIcon;
2930
2931 /* Clean up */
2932end_error:
2933 HeapFree(GetProcessHeap(), 0, pbBmpIcon);
2934 if(isAnimated)
2935 HeapFree(GetProcessHeap(), 0, cursorData.aspcur);
2936 if (cursorData.hbmMask) DeleteObject(cursorData.hbmMask);
2937 if (cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
2938 if (cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
2939
2940 return NULL;
2941}
2942
2944 _In_ PICONINFO piconinfo
2945)
2946{
2947 /* As simple as creating a handle, and let win32k deal with the bitmaps */
2948 HICON hiconRet;
2949 CURSORDATA cursorData;
2950
2951 TRACE("%p.\n", piconinfo);
2952
2953 ZeroMemory(&cursorData, sizeof(cursorData));
2954
2955 if(!CURSORICON_GetCursorDataFromIconInfo(&cursorData, piconinfo))
2956 return NULL;
2957
2959 if(!hiconRet)
2960 goto end_error;
2961
2962 if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, &cursorData))
2963 {
2964 NtUserDestroyCursor(hiconRet, FALSE);
2965 goto end_error;
2966 }
2967
2968 TRACE("Returning 0x%08x.\n", hiconRet);
2969
2970 return hiconRet;
2971
2972end_error:
2973 /* Clean up */
2974 DeleteObject(cursorData.hbmMask);
2975 if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
2976 if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
2977
2978 return NULL;
2979}
2980
2983 _In_ int xHotSpot,
2984 _In_ int yHotSpot,
2985 _In_ int nWidth,
2986 _In_ int nHeight,
2987 _In_ const VOID *pvANDPlane,
2988 _In_ const VOID *pvXORPlane
2989)
2990{
2991 ICONINFO info;
2992 HCURSOR hCursor;
2993
2994 TRACE_(cursor)("%dx%d spot=%d,%d xor=%p and=%p\n",
2995 nWidth, nHeight, xHotSpot, yHotSpot, pvXORPlane, pvANDPlane);
2996
2997 info.fIcon = FALSE;
2998 info.xHotspot = xHotSpot;
2999 info.yHotspot = yHotSpot;
3000 info.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, pvANDPlane );
3001 info.hbmColor = CreateBitmap( nWidth, nHeight, 1, 1, pvXORPlane );
3002 hCursor = CreateIconIndirect( &info );
3003 DeleteObject( info.hbmMask );
3004 DeleteObject( info.hbmColor );
3005 return hCursor;
3006}
3007
3009 _In_ HCURSOR hcur,
3010 _In_ DWORD id
3011)
3012{
3013 if (hcur == NULL)
3014 {
3016 if (hcur == NULL)
3017 {
3018 return FALSE;
3019 }
3020 }
3021 return NtUserSetSystemCursor(hcur,id);
3022}
3023
3025 _In_ int X,
3026 _In_ int Y
3027)
3028{
3029 return NtUserxSetCursorPos(X,Y);
3030}
3031
3033 _Out_ LPPOINT lpPoint
3034)
3035{
3036 return NtUserxGetCursorPos(lpPoint);
3037}
3038
3040 _In_ BOOL bShow
3041)
3042{
3043 return NtUserxShowCursor(bShow);
3044}
3045
3047{
3049}
3050
3052 _In_ HCURSOR hCursor
3053)
3054{
3055 return NtUserDestroyCursor(hCursor, FALSE);
3056}
3057
3058HCURSOR
3059WINAPI
3060GetCursorFrameInfo(HCURSOR hCursor, DWORD reserved, DWORD istep, PINT rate_jiffies, DWORD *num_steps)
3061{
3062 return NtUserGetCursorFrameInfo(hCursor, istep, rate_jiffies, num_steps);
3063}
static HDC hDC
Definition: 3dtext.c:33
DWORD dwVersion
Definition: LocaleTests.cpp:63
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
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
HMODULE hModule
Definition: animate.c:44
#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
PSERVERINFO gpsi
Definition: imm.c:18
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
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:56
#define GetBValue(quad)
Definition: precomp.h:75
#define GetGValue(quad)
Definition: precomp.h:74
ULONG RGBQUAD
Definition: precomp.h:59
#define GetRValue(quad)
Definition: precomp.h:73
r reserved
Definition: btrfs.c:3006
HINSTANCE hInst
Definition: dxdiag.c:13
#define abs(i)
Definition: fconv.c:206
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
pKey DeleteObject()
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
#define CURSORF_LRSHARED
Definition: ntuser.h:1201
@ THREADSTATE_GETCURSOR
Definition: ntuser.h:2478
#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:599
#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 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:534
#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)
#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
#define L(x)
Definition: ntvdm.h:50
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::@5280 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
Definition: bl.h:1331
CURSORICONFILEDIRENTRY idEntries[1]
Definition: cursoricon.c:43
DWORD yHotspot
Definition: winuser.h:3136
BOOL fIcon
Definition: winuser.h:3134
DWORD xHotspot
Definition: winuser.h:3135
HBITMAP hbmColor
Definition: winuser.h:3138
HBITMAP hbmMask
Definition: winuser.h:3137
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:1100
DWORD data_size
Definition: cursoricon.c:1099
ULONG biClrImportant
Definition: precomp.h:52
USHORT biBitCount
Definition: precomp.h:46
ULONG biCompression
Definition: precomp.h:47
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1476
RGBQUAD bmiColors[1]
Definition: wingdi.h:1477
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:1438
#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
int ret
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:2084
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:861
BOOL APIENTRY NtUserDestroyCursor(_In_ HANDLE hCurIcon, _In_ BOOL bForce)
Definition: cursoricon.c:793
__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:1510
BOOL APIENTRY NtUserSetSystemCursor(HCURSOR hcur, DWORD id)
Definition: cursoricon.c:2201
HCURSOR NTAPI NtUserGetCursorFrameInfo(HCURSOR hCursor, DWORD istep, INT *rate_jiffies, DWORD *num_steps)
Definition: cursoricon.c:2131
static int bitmap_info_size(const BITMAPINFO *info, WORD coloruse)
Definition: cursoricon.c:406
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:2981
HBITMAP WINAPI LoadBitmapW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpBitmapName)
Definition: cursoricon.c:2500
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:2540
#define EOFM
HCURSOR WINAPI LoadCursorFromFileW(_In_ LPCWSTR lpFileName)
Definition: cursoricon.c:2471
static BOOL CURSORICON_GetCursorDataFromIconInfo(_Out_ CURSORDATA *pCursorData, _In_ ICONINFO *pIconInfo)
Definition: cursoricon.c:988
BOOL WINAPI GetCursorPos(_Out_ LPPOINT lpPoint)
Definition: cursoricon.c:3032
static BOOL CURSORICON_GetCursorDataFromBMI(_Inout_ CURSORDATA *pdata, _In_ const BITMAPINFO *pbmi)
Definition: cursoricon.c:838
#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:3008
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:1118
HCURSOR WINAPI LoadCursorFromFileA(_In_ LPCSTR lpFileName)
Definition: cursoricon.c:2457
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:808
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:2566
#define COPYIMAGE_VALID_FLAGS
Definition: cursoricon.c:2269
static BOOL bmi_has_alpha(const BITMAPINFO *info, const void *bits)
Definition: cursoricon.c:532
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:2780
static BOOL CURSORICON_GetCursorDataFromANI(_Inout_ CURSORDATA *pCurData, _In_ const BYTE *pData, _In_ DWORD dwDataSize, _In_ DWORD fuLoad)
Definition: cursoricon.c:1145
#define PNG_CHECK_SIG_SIZE
Definition: cursoricon.c:47
BOOL WINAPI SetCursorPos(_In_ int X, _In_ int Y)
Definition: cursoricon.c:3024
#define CR
static void stretch_blt_icon(HDC hdc_dst, int dst_width, int dst_height, HBITMAP src)
Definition: cursoricon.c:485
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:1708
static HBITMAP BITMAP_LoadImageW(_In_opt_ HINSTANCE hinst, _In_ LPCWSTR lpszName, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuLoad)
Definition: cursoricon.c:1322
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:551
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:722
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:1929
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpCursorName)
Definition: cursoricon.c:2442
static HANDLE CURSORICON_LoadFromFileW(_In_ LPCWSTR lpszName, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuLoad, _In_ BOOL bIcon)
Definition: cursoricon.c:1612
#define HighBitDetect
HCURSOR WINAPI GetCursorFrameInfo(HCURSOR hCursor, DWORD reserved, DWORD istep, PINT rate_jiffies, DWORD *num_steps)
Definition: cursoricon.c:3060
static int DIB_GetBitmapInfo(const BITMAPINFOHEADER *header, LONG *width, LONG *height, WORD *bpp, DWORD *compr)
Definition: cursoricon.c:443
HBITMAP WINAPI LoadBitmapA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpBitmapName)
Definition: cursoricon.c:2485
int WINAPI LookupIconIdFromDirectoryEx(_In_ PBYTE presbits, _In_ BOOL fIcon, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT Flags)
Definition: cursoricon.c:2576
NTSTATUS WINAPI User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: cursoricon.c:2251
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:1104
static const WCHAR DISPLAYW[]
Definition: cursoricon.c:336
HICON WINAPI CopyIcon(_In_ HICON hIcon)
Definition: cursoricon.c:2348
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpIconName)
Definition: cursoricon.c:2412
static HICON CURSORICON_CopyImage(_In_ HICON hicon, _In_ BOOL bIcon, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuFlags)
Definition: cursoricon.c:2119
#define ZeroMemory
Definition: winbase.h:1743
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ LPCSTR lpFileName
Definition: winbase.h:3102
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:368
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define CopyMemory
Definition: winbase.h:1741
_In_ ULONG _In_ ULONG rgb
Definition: winddi.h:3521
int * PINT
Definition: windef.h:177
DWORD COLORREF
Definition: windef.h:300
HICON HCURSOR
Definition: windef.h:299
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_CURSOR_HANDLE
Definition: winerror.h:883
#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:3046
#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 CBM_INIT
Definition: wingdi.h:365
#define GetObject
Definition: wingdi.h:4468
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:2943
BOOL WINAPI DestroyCursor(_In_ HCURSOR)
Definition: cursoricon.c:3051
#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:2732
BOOL WINAPI GetIconInfo(_In_ HICON, _Out_ PICONINFO)
Definition: cursoricon.c:2382
#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:2355
#define IDC_NO
Definition: winuser.h:705
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
#define IDC_ARROW
Definition: winuser.h:695
#define LR_MONOCHROME
Definition: winuser.h:1099
int WINAPI ShowCursor(_In_ BOOL)
Definition: cursoricon.c:3039
#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:2275
#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:2397
#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:2365
#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:2515
#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:2427
#define COLOR_3DLIGHT
Definition: winuser.h:951
#define SM_CXCURSOR
Definition: winuser.h:985
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2390
#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
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193