ReactOS 0.4.16-dev-1537-g4e425b5
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)
1741 {
1742 #ifndef IDI_SHIELD
1743 #define IDI_SHIELD MAKEINTRESOURCE(32518)
1744 #endif
1745
1747
1748 /* Map IDI to resource id */
1749 if (bIcon && lpszName >= IDI_APPLICATION && lpszName <= IDI_SHIELD)
1750 {
1751 SIZE_T id = 100 + (SIZE_T)lpszName - (SIZE_T)IDI_APPLICATION;
1752 if ((id | 2) == 103)
1753 id ^= 2; /* Must swap IDI_ERROR and IDI_WARNING */
1754 lpszName = MAKEINTRESOURCEW(id);
1755 }
1756 }
1757
1758 if(lpszName)
1759 {
1760 /* Prepare the resource name string */
1761 if(IS_INTRESOURCE(lpszName))
1762 {
1763 ustrRsrc.Buffer = (LPWSTR)lpszName;
1764 ustrRsrc.Length = 0;
1765 ustrRsrc.MaximumLength = 0;
1766 }
1767 else
1768 RtlInitUnicodeString(&ustrRsrc, lpszName);
1769 }
1770
1772 {
1773 /* We don't have a real module for GetModuleFileName, construct a fake name instead.
1774 * GetIconInfoEx reveals the name used by Windows. */
1775 LPCWSTR fakeNameFmt = sizeof(void*) > 4 ? L"\x01%016IX" : L"\x01%08IX";
1776 ustrModule.MaximumLength = 18 * sizeof(WCHAR);
1777 ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength);
1778 if (!ustrModule.Buffer)
1779 {
1781 return NULL;
1782 }
1783 ustrModule.Length = (USHORT)wsprintfW(ustrModule.Buffer, fakeNameFmt, hinst) * sizeof(WCHAR);
1784 }
1785 else if(hinst)
1786 {
1788 /* Get the module name string */
1789 while (TRUE)
1790 {
1791 DWORD ret;
1792 ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
1793 if (!ustrModule.Buffer)
1794 {
1796 return NULL;
1797 }
1798 ret = GetModuleFileNameW(hinst, ustrModule.Buffer, size);
1799 if(ret == 0)
1800 {
1801 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1802 return NULL;
1803 }
1804
1805 /* This API is completely broken... */
1806 if (ret == size)
1807 {
1808 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1809 size *= 2;
1810 continue;
1811 }
1812
1813 ustrModule.Buffer[ret] = UNICODE_NULL;
1814 ustrModule.Length = (USHORT)(ret * sizeof(WCHAR));
1815 ustrModule.MaximumLength = (USHORT)(size * sizeof(WCHAR));
1816 break;
1817 }
1818 }
1819
1820 if(fuLoad & LR_SHARED)
1821 {
1823
1824 TRACE("Checking for an LR_SHARED cursor/icon.\n");
1825 /* Ask win32k */
1826 param.bIcon = bIcon;
1827 param.cx = cxDesired;
1828 param.cy = cyDesired;
1829 hCurIcon = NtUserFindExistingCursorIcon(&ustrModule, &ustrRsrc, &param);
1830 if(hCurIcon)
1831 {
1832 /* Woohoo, got it! */
1833 TRACE("MATCH! %p\n",hCurIcon);
1834 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1835 return hCurIcon;
1836 }
1837 }
1838
1839 /* Find resource ID */
1840 hrsrc = FindResourceW(
1841 hinst,
1842 lpszName,
1843 bIcon ? RT_GROUP_ICON : RT_GROUP_CURSOR);
1844
1845 /* We let FindResource, LoadResource, etc. call SetLastError */
1846 if(!hrsrc)
1847 goto done;
1848
1849 handle = LoadResource(hinst, hrsrc);
1850 if(!handle)
1851 goto done;
1852
1854 if(!dir)
1855 goto done;
1856
1857 wResId = LookupIconIdFromDirectoryEx((PBYTE)dir, bIcon, cxDesired, cyDesired, fuLoad);
1859
1860 /* Get the relevant resource pointer */
1861 hrsrc = FindResourceW(
1862 hinst,
1863 MAKEINTRESOURCEW(wResId),
1864 bIcon ? RT_ICON : RT_CURSOR);
1865 if(!hrsrc)
1866 goto done;
1867
1868 handle = LoadResource(hinst, hrsrc);
1869 if(!handle)
1870 goto done;
1871
1873 if(!bits)
1874 {
1876 goto done;
1877 }
1878
1879 ZeroMemory(&cursorData, sizeof(cursorData));
1880
1881 /* This is from resource */
1883
1884 if(dir->idType == 2)
1885 {
1886 /* idType == 2 for cursor resources */
1887 SHORT* ptr = (SHORT*)bits;
1888 cursorData.xHotspot = ptr[0];
1889 cursorData.yHotspot = ptr[1];
1890 bits += 2*sizeof(SHORT);
1891 }
1892 cursorData.cx = cxDesired;
1893 cursorData.cy = cyDesired;
1894 cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR));
1895
1896 /* Get the bitmaps */
1898 &cursorData,
1899 (BITMAPINFO*)bits);
1900
1902
1903 if(!bStatus)
1904 goto done;
1905
1906 /* Create the handle */
1908 if(!hCurIcon)
1909 {
1910 goto end_error;
1911 }
1912
1913 if(fuLoad & LR_SHARED)
1914 {
1915 cursorData.CURSORF_flags |= CURSORF_LRSHARED;
1916 }
1917
1918 /* Tell win32k */
1919 bStatus = NtUserSetCursorIconData(hCurIcon, hinst ? &ustrModule : NULL, lpszName ? &ustrRsrc : NULL, &cursorData);
1920
1921 if(!bStatus)
1922 {
1923 NtUserDestroyCursor(hCurIcon, TRUE);
1924 goto end_error;
1925 }
1926
1927done:
1928 if(ustrModule.Buffer)
1929 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1930 return hCurIcon;
1931
1932end_error:
1933 if(ustrModule.Buffer)
1934 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1935 DeleteObject(cursorData.hbmMask);
1936 if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
1937 if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
1938
1939 return NULL;
1940}
1941
1942static
1943HBITMAP
1945 _In_ HBITMAP hnd,
1946 _In_ int desiredx,
1947 _In_ int desiredy,
1949)
1950{
1951 HBITMAP res = NULL;
1952 DIBSECTION ds;
1953 int objSize;
1954 BITMAPINFO * bi;
1955
1956 objSize = GetObjectW( hnd, sizeof(ds), &ds );
1957 if (!objSize) return 0;
1958 if ((desiredx < 0) || (desiredy < 0)) return 0;
1959
1961 {
1962 FIXME("The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
1963 }
1964
1965 if (flags & LR_COPYRETURNORG)
1966 {
1967 FIXME("The flag LR_COPYRETURNORG is not implemented for bitmaps\n");
1968 }
1969
1970 if (desiredx == 0) desiredx = ds.dsBm.bmWidth;
1971 if (desiredy == 0) desiredy = ds.dsBm.bmHeight;
1972
1973 /* Allocate memory for a BITMAPINFOHEADER structure and a
1974 color table. The maximum number of colors in a color table
1975 is 256 which corresponds to a bitmap with depth 8.
1976 Bitmaps with higher depths don't have color tables. */
1977 bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1978 if (!bi) return 0;
1979
1980 bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
1981 bi->bmiHeader.biPlanes = ds.dsBm.bmPlanes;
1982 bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
1984
1986 {
1987 /* Create a DIB section. LR_MONOCHROME is ignored */
1988 void * bits;
1990
1991 if (objSize == sizeof(DIBSECTION))
1992 {
1993 /* The source bitmap is a DIB.
1994 Get its attributes to create an exact copy */
1995 memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
1996 }
1997
1998 bi->bmiHeader.biWidth = desiredx;
1999 bi->bmiHeader.biHeight = desiredy;
2000
2001 /* Get the color table or the color masks */
2002 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
2003
2005 DeleteDC(dc);
2006 }
2007 else
2008 {
2009 /* Create a device-dependent bitmap */
2010
2011 BOOL monochrome = (flags & LR_MONOCHROME);
2012
2013 if (objSize == sizeof(DIBSECTION))
2014 {
2015 /* The source bitmap is a DIB section.
2016 Get its attributes */
2018 bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
2019 bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
2020 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
2021 DeleteDC(dc);
2022
2023 if (!monochrome && ds.dsBm.bmBitsPixel == 1)
2024 {
2025 /* Look if the colors of the DIB are black and white */
2026
2027 monochrome =
2028 (bi->bmiColors[0].rgbRed == 0xff
2029 && bi->bmiColors[0].rgbGreen == 0xff
2030 && bi->bmiColors[0].rgbBlue == 0xff
2031 && bi->bmiColors[0].rgbReserved == 0
2032 && bi->bmiColors[1].rgbRed == 0
2033 && bi->bmiColors[1].rgbGreen == 0
2034 && bi->bmiColors[1].rgbBlue == 0
2035 && bi->bmiColors[1].rgbReserved == 0)
2036 ||
2037 (bi->bmiColors[0].rgbRed == 0
2038 && bi->bmiColors[0].rgbGreen == 0
2039 && bi->bmiColors[0].rgbBlue == 0
2040 && bi->bmiColors[0].rgbReserved == 0
2041 && bi->bmiColors[1].rgbRed == 0xff
2042 && bi->bmiColors[1].rgbGreen == 0xff
2043 && bi->bmiColors[1].rgbBlue == 0xff
2044 && bi->bmiColors[1].rgbReserved == 0);
2045 }
2046 }
2047 else if (!monochrome)
2048 {
2049 monochrome = ds.dsBm.bmBitsPixel == 1;
2050 }
2051
2052 if (monochrome)
2053 {
2054 res = CreateBitmap(desiredx, desiredy, 1, 1, NULL);
2055 }
2056 else
2057 {
2058 HDC screenDC = GetDC(NULL);
2059 res = CreateCompatibleBitmap(screenDC, desiredx, desiredy);
2060 ReleaseDC(NULL, screenDC);
2061 }
2062 }
2063
2064 if (res)
2065 {
2066 /* Only copy the bitmap if it's a DIB section or if it's
2067 compatible to the screen */
2068 BOOL copyContents;
2069
2070 if (objSize == sizeof(DIBSECTION))
2071 {
2072 copyContents = TRUE;
2073 }
2074 else
2075 {
2076 HDC screenDC = GetDC(NULL);
2077 int screen_depth = GetDeviceCaps(screenDC, BITSPIXEL);
2078 ReleaseDC(NULL, screenDC);
2079
2080 copyContents = (ds.dsBm.bmBitsPixel == 1 || ds.dsBm.bmBitsPixel == screen_depth);
2081 }
2082
2083 if (copyContents)
2084 {
2085 /* The source bitmap may already be selected in a device context,
2086 use GetDIBits/StretchDIBits and not StretchBlt */
2087
2088 HDC dc;
2089 void * bits;
2090
2092
2093 bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
2094 bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
2095 bi->bmiHeader.biSizeImage = 0;
2096 bi->bmiHeader.biClrUsed = 0;
2097 bi->bmiHeader.biClrImportant = 0;
2098
2099 /* Fill in biSizeImage */
2100 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
2102
2103 if (bits)
2104 {
2105 HBITMAP oldBmp;
2106
2107 /* Get the image bits of the source bitmap */
2108 GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
2109
2110 /* Copy it to the destination bitmap */
2111 oldBmp = SelectObject(dc, res);
2112 StretchDIBits(dc, 0, 0, desiredx, desiredy,
2113 0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight,
2115 SelectObject(dc, oldBmp);
2116
2118 }
2119
2120 DeleteDC(dc);
2121 }
2122
2123 if (flags & LR_COPYDELETEORG)
2124 {
2125 DeleteObject(hnd);
2126 }
2127 }
2128 HeapFree(GetProcessHeap(), 0, bi);
2129 return res;
2130}
2131
2132static
2133HICON
2135 _In_ HICON hicon,
2136 _In_ BOOL bIcon,
2137 _In_ int cxDesired,
2138 _In_ int cyDesired,
2139 _In_ UINT fuFlags
2140)
2141{
2142 HICON ret = NULL;
2143 ICONINFO ii;
2144 CURSORDATA CursorData;
2145
2146 if (fuFlags & LR_COPYFROMRESOURCE)
2147 {
2148 /* Get the icon module/resource names */
2149 UNICODE_STRING ustrModule;
2150 UNICODE_STRING ustrRsrc;
2152
2153 ustrModule.MaximumLength = 0;
2154 ustrRsrc.MaximumLength = 0;
2155
2156 /* Get the buffer size */
2157 if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
2158 {
2159 return NULL;
2160 }
2161
2162 ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength);
2163 if (!ustrModule.Buffer)
2164 {
2166 return NULL;
2167 }
2168
2169 if (ustrRsrc.MaximumLength)
2170 {
2171 ustrRsrc.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength);
2172 if (!ustrRsrc.Buffer)
2173 {
2174 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
2176 return NULL;
2177 }
2178 }
2179
2180 if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
2181 {
2182 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
2183 if (!IS_INTRESOURCE(ustrRsrc.Buffer))
2184 HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer);
2185 return NULL;
2186 }
2187
2188 /* NULL-terminate our strings */
2189 ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = UNICODE_NULL;
2190 if (!IS_INTRESOURCE(ustrRsrc.Buffer))
2191 ustrRsrc.Buffer[ustrRsrc.Length/sizeof(WCHAR)] = UNICODE_NULL;
2192
2193 TRACE("Got module %wZ, resource %p (%S).\n", &ustrModule,
2194 ustrRsrc.Buffer, IS_INTRESOURCE(ustrRsrc.Buffer) ? L"" : ustrRsrc.Buffer);
2195
2196 /* Get the module handle or load the module */
2197 hModule = LoadLibraryExW(ustrModule.Buffer, NULL, /* NT6+: LOAD_LIBRARY_AS_IMAGE_RESOURCE | */ LOAD_LIBRARY_AS_DATAFILE);
2198 if (!hModule)
2199 {
2201 ERR("Unable to load/use module '%wZ' in process %lu, error %lu.\n", &ustrModule, GetCurrentProcessId(), err);
2203 goto leave;
2204 }
2205
2206 /* Call the relevant function */
2208 hModule,
2209 ustrRsrc.Buffer,
2210 cxDesired,
2211 cyDesired,
2212 fuFlags & (LR_DEFAULTSIZE | LR_SHARED),
2213 bIcon);
2214
2216
2217 /* If we're here, that means that the passed icon is shared. Don't destroy it, even if LR_COPYDELETEORG is specified */
2218 leave:
2219 HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
2220 if (!IS_INTRESOURCE(ustrRsrc.Buffer))
2221 HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer);
2222
2223 TRACE("Returning 0x%08x.\n", ret);
2224
2225 return ret;
2226 }
2227
2228 /* This is a regular copy */
2229 if (fuFlags & ~(LR_COPYDELETEORG | LR_SHARED))
2230 FIXME("Unimplemented flags: 0x%08x\n", fuFlags);
2231
2232 if (!GetIconInfo(hicon, &ii))
2233 {
2234 ERR("GetIconInfo failed.\n");
2235 return NULL;
2236 }
2237
2238 /* This is CreateIconIndirect with the LR_SHARED coat added */
2239 if (!CURSORICON_GetCursorDataFromIconInfo(&CursorData, &ii))
2240 goto Leave;
2241
2242 if (fuFlags & LR_SHARED)
2243 CursorData.CURSORF_flags |= CURSORF_LRSHARED;
2244
2246 if (!ret)
2247 goto Leave;
2248
2249 if (!NtUserSetCursorIconData(ret, NULL, NULL, &CursorData))
2250 {
2252 goto Leave;
2253 }
2254
2255Leave:
2257 if (ii.hbmColor) DeleteObject(ii.hbmColor);
2258
2259 if (ret && (fuFlags & LR_COPYDELETEORG))
2260 DestroyIcon(hicon);
2261
2262 return ret;
2263}
2264
2267{
2269 HANDLE Result;
2270 Common = (PCOPYIMAGE_CALLBACK_ARGUMENTS) Arguments;
2271
2272 Result = CopyImage(Common->hImage,
2273 Common->uType,
2274 Common->cxDesired,
2275 Common->cyDesired,
2276 Common->fuFlags);
2277
2278 return ZwCallbackReturn(&Result, sizeof(HANDLE), STATUS_SUCCESS);
2279}
2280
2281
2282/************* PUBLIC FUNCTIONS *******************/
2283
2284#define COPYIMAGE_VALID_FLAGS ( \
2285 LR_SHARED | LR_COPYFROMRESOURCE | LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS | 0x800 | \
2286 LR_VGACOLOR | LR_LOADREALSIZE | LR_DEFAULTSIZE | LR_LOADTRANSPARENT | LR_LOADFROMFILE | \
2287 LR_COPYDELETEORG | LR_COPYRETURNORG | LR_COLOR | LR_MONOCHROME \
2288)
2289
2291 _In_ HANDLE hImage,
2292 _In_ UINT uType,
2293 _In_ int cxDesired,
2294 _In_ int cyDesired,
2295 _In_ UINT fuFlags
2296)
2297{
2298 TRACE("hImage=%p, uType=%u, cxDesired=%d, cyDesired=%d, fuFlags=%x\n",
2299 hImage, uType, cxDesired, cyDesired, fuFlags);
2300
2301 if (fuFlags & ~COPYIMAGE_VALID_FLAGS)
2302 {
2304 return NULL;
2305 }
2306
2307 switch(uType)
2308 {
2309 case IMAGE_BITMAP:
2310 if (!hImage)
2311 {
2313 break;
2314 }
2315 return BITMAP_CopyImage(hImage, cxDesired, cyDesired, fuFlags);
2316 case IMAGE_CURSOR:
2317 case IMAGE_ICON:
2318 {
2319 HANDLE handle;
2320 if (!hImage)
2321 {
2323 break;
2324 }
2325 handle = CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, cxDesired, cyDesired, fuFlags);
2326 if (!handle && (fuFlags & LR_COPYFROMRESOURCE))
2327 {
2328 /* Test if the hImage is the same size as what we want by getting
2329 * its BITMAP and comparing its dimensions to the desired size. */
2330 BITMAP bm;
2331
2332 ICONINFO iconinfo = { 0 };
2333 if (!GetIconInfo(hImage, &iconinfo))
2334 {
2335 ERR("GetIconInfo Failed. hImage %p\n", hImage);
2336 return NULL;
2337 }
2338 if (!GetObject(iconinfo.hbmColor, sizeof(bm), &bm))
2339 {
2340 ERR("GetObject Failed. iconinfo %p\n", iconinfo);
2341 return NULL;
2342 }
2343
2344 DeleteObject(iconinfo.hbmMask);
2345 DeleteObject(iconinfo.hbmColor);
2346
2347 /* If the images are the same size remove LF_COPYFROMRESOURCE and try again */
2348 if (cxDesired == bm.bmWidth && cyDesired == bm.bmHeight)
2349 {
2350 handle = CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, cxDesired,
2351 cyDesired, (fuFlags & ~LR_COPYFROMRESOURCE));
2352 }
2353 }
2354 return handle;
2355 }
2356 default:
2358 break;
2359 }
2360 return NULL;
2361}
2362
2365)
2366{
2367 return CURSORICON_CopyImage(hIcon, FALSE, 0, 0, 0);
2368}
2369
2371 _In_ HDC hDC,
2372 _In_ int X,
2373 _In_ int Y,
2375)
2376{
2377 return DrawIconEx(hDC, X, Y, hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
2378}
2379
2381 _In_ HDC hdc,
2382 _In_ int xLeft,
2383 _In_ int yTop,
2385 _In_ int cxWidth,
2386 _In_ int cyWidth,
2387 _In_ UINT istepIfAniCur,
2388 _In_opt_ HBRUSH hbrFlickerFreeDraw,
2389 _In_ UINT diFlags
2390)
2391{
2392 return NtUserDrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth,
2393 istepIfAniCur, hbrFlickerFreeDraw, diFlags,
2394 0, 0);
2395}
2396
2399 _Out_ PICONINFO piconinfo
2400)
2401{
2402 return NtUserGetIconInfo(hIcon, piconinfo, NULL, NULL, NULL, FALSE);
2403}
2404
2407)
2408{
2410}
2411
2414 _In_ LPCSTR lpIconName
2415)
2416{
2417 TRACE("%p, %s\n", hInstance, debugstr_a(lpIconName));
2418
2419 return LoadImageA(hInstance,
2420 lpIconName,
2421 IMAGE_ICON,
2422 0,
2423 0,
2425}
2426
2429 _In_ LPCWSTR lpIconName
2430)
2431{
2432 TRACE("%p, %s\n", hInstance, debugstr_w(lpIconName));
2433
2434 return LoadImageW(hInstance,
2435 lpIconName,
2436 IMAGE_ICON,
2437 0,
2438 0,
2440}
2441
2444 _In_ LPCSTR lpCursorName
2445)
2446{
2447 TRACE("%p, %s\n", hInstance, debugstr_a(lpCursorName));
2448
2449 return LoadImageA(hInstance,
2450 lpCursorName,
2452 0,
2453 0,
2455}
2456
2459 _In_ LPCWSTR lpCursorName
2460)
2461{
2462 TRACE("%p, %s\n", hInstance, debugstr_w(lpCursorName));
2463
2464 return LoadImageW(hInstance,
2465 lpCursorName,
2467 0,
2468 0,
2470}
2471
2474)
2475{
2476 TRACE("%s\n", debugstr_a(lpFileName));
2477
2478 return LoadImageA(NULL,
2479 lpFileName,
2481 0,
2482 0,
2484}
2485
2488)
2489{
2490 TRACE("%s\n", debugstr_w(lpFileName));
2491
2492 return LoadImageW(NULL,
2493 lpFileName,
2495 0,
2496 0,
2498}
2499
2502 _In_ LPCSTR lpBitmapName
2503)
2504{
2505 TRACE("%p, %s\n", hInstance, debugstr_a(lpBitmapName));
2506
2507 return LoadImageA(hInstance,
2508 lpBitmapName,
2510 0,
2511 0,
2512 0);
2513}
2514
2517 _In_ LPCWSTR lpBitmapName
2518)
2519{
2520 TRACE("%p, %s\n", hInstance, debugstr_w(lpBitmapName));
2521
2522 return LoadImageW(hInstance,
2523 lpBitmapName,
2525 0,
2526 0,
2527 0);
2528}
2529
2532 _In_ LPCSTR lpszName,
2533 _In_ UINT uType,
2534 _In_ int cxDesired,
2535 _In_ int cyDesired,
2536 _In_ UINT fuLoad
2537)
2538{
2539 HANDLE res;
2540 LPWSTR u_name;
2541 DWORD len;
2542
2543 if (IS_INTRESOURCE(lpszName))
2544 return LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired, cyDesired, fuLoad);
2545
2546 len = MultiByteToWideChar( CP_ACP, 0, lpszName, -1, NULL, 0 );
2547 u_name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2548 MultiByteToWideChar( CP_ACP, 0, lpszName, -1, u_name, len );
2549
2550 res = LoadImageW(hinst, u_name, uType, cxDesired, cyDesired, fuLoad);
2551 HeapFree(GetProcessHeap(), 0, u_name);
2552 return res;
2553}
2554
2557 _In_ LPCWSTR lpszName,
2558 _In_ UINT uType,
2559 _In_ int cxDesired,
2560 _In_ int cyDesired,
2561 _In_ UINT fuLoad
2562)
2563{
2564 TRACE("hinst 0x%p, name %s, uType 0x%08x, cxDesired %d, cyDesired %d, fuLoad 0x%08x.\n",
2565 hinst, debugstr_w(lpszName), uType, cxDesired, cyDesired, fuLoad);
2566 /* Redirect to each implementation */
2567 switch(uType)
2568 {
2569 case IMAGE_BITMAP:
2570 return BITMAP_LoadImageW(hinst, lpszName, cxDesired, cyDesired, fuLoad);
2571 case IMAGE_CURSOR:
2572 case IMAGE_ICON:
2573 return CURSORICON_LoadImageW(hinst, lpszName, cxDesired, cyDesired, fuLoad, uType == IMAGE_ICON);
2574 default:
2576 break;
2577 }
2578 return NULL;
2579}
2580
2582 _In_ PBYTE presbits,
2583 _In_ BOOL fIcon
2584)
2585{
2586 return LookupIconIdFromDirectoryEx( presbits, fIcon,
2589}
2590
2592 _In_ PBYTE presbits,
2593 _In_ BOOL fIcon,
2594 _In_ int cxDesired,
2595 _In_ int cyDesired,
2597)
2598{
2599 WORD bppDesired;
2600 CURSORICONDIR* dir = (CURSORICONDIR*)presbits;
2602 int i, numMatch = 0, iIndex = -1;
2603 WORD width, height, BitCount = 0;
2604 BOOL notPaletted = FALSE;
2605 ULONG bestScore = 0xFFFFFFFF, score;
2606
2607 TRACE("%p, %x, %i, %i, %x.\n", presbits, fIcon, cxDesired, cyDesired, Flags);
2608
2609 if(!(dir && !dir->idReserved && (dir->idType & 3)))
2610 {
2611 WARN("Invalid resource.\n");
2612 return 0;
2613 }
2614
2615 if(Flags & LR_MONOCHROME)
2616 bppDesired = 1;
2617 else
2618 {
2619 HDC icScreen;
2620 icScreen = CreateICW(DISPLAYW, NULL, NULL, NULL);
2621 if(!icScreen)
2622 return FALSE;
2623
2624 bppDesired = GetDeviceCaps(icScreen, BITSPIXEL);
2625 DeleteDC(icScreen);
2626 }
2627
2628 if(!cxDesired)
2629 cxDesired = Flags & LR_DEFAULTSIZE ? GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR) : 256;
2630 if(!cyDesired)
2631 cyDesired = Flags & LR_DEFAULTSIZE ? GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR) : 256;
2632
2633 /* Find the best match for the desired size */
2634 for(i = 0; i < dir->idCount; i++)
2635 {
2636 entry = &dir->idEntries[i];
2637 width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2638 /* Height is twice as big in cursor resources */
2639 height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2640 /* 0 represents 256 */
2641 if(!width) width = 256;
2642 if(!height) height = 256;
2643 /* Calculate the "score" (lower is better) */
2644 score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2645 if( score > bestScore)
2646 continue;
2647 /* Bigger than requested lowers the score */
2648 if(width > cxDesired)
2649 score -= width - cxDesired;
2650 if(height > cyDesired)
2651 score -= height - cyDesired;
2652 if(score > bestScore)
2653 continue;
2654 if(score == bestScore)
2655 {
2656 if(entry->wBitCount > BitCount)
2657 BitCount = entry->wBitCount;
2658 numMatch++;
2659 continue;
2660 }
2661 iIndex = i;
2662 numMatch = 1;
2663 bestScore = score;
2664 BitCount = entry->wBitCount;
2665 }
2666
2667 if(numMatch == 1)
2668 {
2669 /* Only one entry fits the asked dimensions */
2670 return dir->idEntries[iIndex].wResId;
2671 }
2672
2673 /* Avoid paletted icons on non-paletted device */
2674 if (bppDesired > 8 && BitCount > 8)
2675 notPaletted = TRUE;
2676
2677 BitCount = 0;
2678 iIndex = -1;
2679 /* Now find the entry with the best depth */
2680 for(i = 0; i < dir->idCount; i++)
2681 {
2682 entry = &dir->idEntries[i];
2683 width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2684 height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2685 /* 0 represents 256 */
2686 if(!width) width = 256;
2687 if(!height) height = 256;
2688 /* Check if this is the best match we had */
2689 score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2690 if(width > cxDesired)
2691 score -= width - cxDesired;
2692 if(height > cyDesired)
2693 score -= height - cyDesired;
2694 if(score != bestScore)
2695 continue;
2696 /* Exact match? */
2697 if(entry->wBitCount == bppDesired)
2698 return entry->wResId;
2699 /* We take the highest possible but smaller than the display depth */
2700 if((entry->wBitCount > BitCount) && (entry->wBitCount < bppDesired))
2701 {
2702 /* Avoid paletted icons on non paletted devices */
2703 if ((entry->wBitCount <= 8) && notPaletted)
2704 continue;
2705 iIndex = i;
2706 BitCount = entry->wBitCount;
2707 }
2708 }
2709
2710 if(iIndex >= 0)
2711 return dir->idEntries[iIndex].wResId;
2712
2713 /* No inferior or equal depth available. Get the smallest bigger one */
2714 BitCount = 0xFFFF;
2715 iIndex = -1;
2716 for(i = 0; i < dir->idCount; i++)
2717 {
2718 entry = &dir->idEntries[i];
2719 width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2720 height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2721 /* 0 represents 256 */
2722 if(!width) width = 256;
2723 if(!height) height = 256;
2724 /* Check if this is the best match we had */
2725 score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2726 if(width > cxDesired)
2727 score -= width - cxDesired;
2728 if(height > cyDesired)
2729 score -= height - cyDesired;
2730 if(score != bestScore)
2731 continue;
2732 /* Check the bit depth */
2733 if(entry->wBitCount < BitCount)
2734 {
2735 if((entry->wBitCount <= 8) && notPaletted)
2736 continue;
2737 iIndex = i;
2738 BitCount = entry->wBitCount;
2739 }
2740 }
2741 if (iIndex >= 0)
2742 return dir->idEntries[iIndex].wResId;
2743
2744 return 0;
2745}
2746
2749 _In_ int nWidth,
2750 _In_ int nHeight,
2751 _In_ BYTE cPlanes,
2752 _In_ BYTE cBitsPixel,
2753 _In_ const BYTE *lpbANDbits,
2754 _In_ const BYTE *lpbXORbits
2755)
2756{
2757 ICONINFO iinfo;
2758 HICON hIcon;
2759
2760 TRACE_(icon)("%dx%d, planes %d, bpp %d, xor %p, and %p\n",
2761 nWidth, nHeight, cPlanes, cBitsPixel, lpbXORbits, lpbANDbits);
2762
2763 iinfo.fIcon = TRUE;
2764 iinfo.xHotspot = nWidth / 2;
2765 iinfo.yHotspot = nHeight / 2;
2766 if (cPlanes * cBitsPixel > 1)
2767 {
2768 iinfo.hbmColor = CreateBitmap( nWidth, nHeight, cPlanes, cBitsPixel, lpbXORbits );
2769 iinfo.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, lpbANDbits );
2770 }
2771 else
2772 {
2773 iinfo.hbmMask = CreateBitmap( nWidth, nHeight * 2, 1, 1, lpbANDbits );
2774 iinfo.hbmColor = NULL;
2775 }
2776
2777 hIcon = CreateIconIndirect( &iinfo );
2778
2779 DeleteObject( iinfo.hbmMask );
2780 if (iinfo.hbmColor) DeleteObject( iinfo.hbmColor );
2781
2782 return hIcon;
2783}
2784
2786 _In_ PBYTE presbits,
2787 _In_ DWORD dwResSize,
2788 _In_ BOOL fIcon,
2789 _In_ DWORD dwVer
2790)
2791{
2792 return CreateIconFromResourceEx( presbits, dwResSize, fIcon, dwVer, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
2793}
2794
2796 _In_ PBYTE pbIconBits,
2797 _In_ DWORD cbIconBits,
2798 _In_ BOOL fIcon,
2800 _In_ int cxDesired,
2801 _In_ int cyDesired,
2803)
2804{
2805 CURSORDATA cursorData;
2806 HICON hIcon;
2807 BOOL isAnimated;
2808 PBYTE pbBmpIcon = NULL;
2809 DWORD BmpIconSize;
2810
2811 TRACE("%p, %lu, %lu, %lu, %i, %i, %lu.\n", pbIconBits, cbIconBits, fIcon, dwVersion, cxDesired, cyDesired, uFlags);
2812
2813 if (!pbIconBits || cbIconBits < 2 * sizeof(DWORD))
2814 {
2815 ERR("Invalid IconBits array\n");
2816 return NULL;
2817 }
2818
2820 {
2821 if(!cxDesired) cxDesired = GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR);
2822 if(!cyDesired) cyDesired = GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR);
2823 }
2824
2825 ZeroMemory(&cursorData, sizeof(cursorData));
2826 cursorData.cx = cxDesired;
2827 cursorData.cy = cyDesired;
2828 cursorData.rt = LOWORD(fIcon ? RT_ICON : RT_CURSOR);
2829
2830 /* Convert to win32k-ready data */
2831 if(!memcmp(pbIconBits, "RIFF", 4))
2832 {
2833 if(!CURSORICON_GetCursorDataFromANI(&cursorData, pbIconBits, cbIconBits, uFlags))
2834 {
2835 ERR("Could not get cursor data from .ani.\n");
2836 return NULL;
2837 }
2838 isAnimated = !!(cursorData.CURSORF_flags & CURSORF_ACON);
2839 }
2840 else
2841 {
2842 /* It is possible to pass Icon Directories to this API */
2843 int wResId = LookupIconIdFromDirectoryEx(pbIconBits, fIcon, cxDesired, cyDesired, uFlags);
2844 HANDLE ResHandle = NULL;
2845#ifdef __REACTOS__
2846 if (wResId && (pbIconBits[4] != sizeof(BITMAPINFOHEADER)))
2847#else
2848 if(wResId)
2849#endif
2850 {
2852 HRSRC hrsrc;
2853 CURSORICONDIR* pCurIconDir = (CURSORICONDIR*)pbIconBits;
2854
2855 TRACE("Pointer points to a directory structure.\n");
2856
2857 /* So this is a pointer to an icon directory structure. Find the module */
2858 if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
2859 (LPCWSTR)pbIconBits,
2860 &hinst))
2861 {
2862 return NULL;
2863 }
2864
2865 /* Check we were given the right type of resource */
2866 if((fIcon && pCurIconDir->idType == 2) || (!fIcon && pCurIconDir->idType == 1))
2867 {
2868 WARN("Got a %s directory pointer, but called for a %s\n", fIcon ? "cursor" : "icon", fIcon ? "icon" : "cursor");
2869 return NULL;
2870 }
2871
2872 /* Get the relevant resource pointer */
2873 hrsrc = FindResourceW(
2874 hinst,
2875 MAKEINTRESOURCEW(wResId),
2876 fIcon ? RT_ICON : RT_CURSOR);
2877 if (!hrsrc)
2878 return NULL;
2879
2880 ResHandle = LoadResource(hinst, hrsrc);
2881 if (!ResHandle)
2882 return NULL;
2883
2884 pbIconBits = LockResource(ResHandle);
2885 if (!pbIconBits)
2886 {
2887 FreeResource(ResHandle);
2888 return NULL;
2889 }
2890 }
2891 if(!fIcon)
2892 {
2893 WORD* pt = (WORD*)pbIconBits;
2894 cursorData.xHotspot = *pt++;
2895 cursorData.yHotspot = *pt++;
2896 pbIconBits = (PBYTE)pt;
2897 }
2898
2899 isAnimated = FALSE;
2900
2901 /* Try to load BMP icon */
2902 if (!CURSORICON_GetCursorDataFromBMI(&cursorData, (PBITMAPINFO)pbIconBits))
2903 {
2904 /* Convert PNG raw data to BMP icon if the icon was PNG icon */
2905 pbBmpIcon = CURSORICON_ConvertPngToBmpIcon(pbIconBits, cbIconBits, &BmpIconSize);
2906 if (!pbBmpIcon)
2907 return NULL; /* Not PNG icon or failed */
2908
2909 /* Find icon entry from BMP icon */
2910 CURSORICONFILEDIR *dir = (CURSORICONFILEDIR *)pbBmpIcon;
2911 CURSORICONFILEDIRENTRY *entry = &dir->idEntries[0]; /* Only one entry */
2912
2913 /* A bit of preparation */
2914 RtlZeroMemory(&cursorData, sizeof(cursorData));
2915 cursorData.rt = LOWORD(fIcon ? RT_ICON : RT_CURSOR);
2916
2917 /* Can we load this BMP icon? */
2918 if (!CURSORICON_GetCursorDataFromBMI(&cursorData, (PBITMAPINFO)&pbBmpIcon[entry->dwDIBOffset]))
2919 {
2920 ERR("Couldn't get cursor/icon data\n");
2921 goto end_error;
2922 }
2923 }
2924 }
2925
2926 if (uFlags & LR_SHARED)
2927 cursorData.CURSORF_flags |= CURSORF_LRSHARED;
2928
2929 hIcon = NtUserxCreateEmptyCurObject(isAnimated);
2930 if (!hIcon)
2931 goto end_error;
2932
2933 if(!NtUserSetCursorIconData(hIcon, NULL, NULL, &cursorData))
2934 {
2935 ERR("NtUserSetCursorIconData failed.\n");
2937 goto end_error;
2938 }
2939
2940 if(isAnimated)
2941 HeapFree(GetProcessHeap(), 0, cursorData.aspcur);
2942
2943 HeapFree(GetProcessHeap(), 0, pbBmpIcon);
2944 return hIcon;
2945
2946 /* Clean up */
2947end_error:
2948 HeapFree(GetProcessHeap(), 0, pbBmpIcon);
2949 if(isAnimated)
2950 HeapFree(GetProcessHeap(), 0, cursorData.aspcur);
2951 if (cursorData.hbmMask) DeleteObject(cursorData.hbmMask);
2952 if (cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
2953 if (cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
2954
2955 return NULL;
2956}
2957
2959 _In_ PICONINFO piconinfo
2960)
2961{
2962 /* As simple as creating a handle, and let win32k deal with the bitmaps */
2963 HICON hiconRet;
2964 CURSORDATA cursorData;
2965
2966 TRACE("%p.\n", piconinfo);
2967
2968 ZeroMemory(&cursorData, sizeof(cursorData));
2969
2970 if(!CURSORICON_GetCursorDataFromIconInfo(&cursorData, piconinfo))
2971 return NULL;
2972
2974 if(!hiconRet)
2975 goto end_error;
2976
2977 if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, &cursorData))
2978 {
2979 NtUserDestroyCursor(hiconRet, FALSE);
2980 goto end_error;
2981 }
2982
2983 TRACE("Returning 0x%08x.\n", hiconRet);
2984
2985 return hiconRet;
2986
2987end_error:
2988 /* Clean up */
2989 DeleteObject(cursorData.hbmMask);
2990 if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
2991 if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
2992
2993 return NULL;
2994}
2995
2998 _In_ int xHotSpot,
2999 _In_ int yHotSpot,
3000 _In_ int nWidth,
3001 _In_ int nHeight,
3002 _In_ const VOID *pvANDPlane,
3003 _In_ const VOID *pvXORPlane
3004)
3005{
3006 ICONINFO info;
3007 HCURSOR hCursor;
3008
3009 TRACE_(cursor)("%dx%d spot=%d,%d xor=%p and=%p\n",
3010 nWidth, nHeight, xHotSpot, yHotSpot, pvXORPlane, pvANDPlane);
3011
3012 info.fIcon = FALSE;
3013 info.xHotspot = xHotSpot;
3014 info.yHotspot = yHotSpot;
3015 info.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, pvANDPlane );
3016 info.hbmColor = CreateBitmap( nWidth, nHeight, 1, 1, pvXORPlane );
3017 hCursor = CreateIconIndirect( &info );
3018 DeleteObject( info.hbmMask );
3019 DeleteObject( info.hbmColor );
3020 return hCursor;
3021}
3022
3024 _In_ HCURSOR hcur,
3025 _In_ DWORD id
3026)
3027{
3028 if (hcur == NULL)
3029 {
3031 if (hcur == NULL)
3032 {
3033 return FALSE;
3034 }
3035 }
3036 return NtUserSetSystemCursor(hcur,id);
3037}
3038
3040 _In_ int X,
3041 _In_ int Y
3042)
3043{
3044 return NtUserxSetCursorPos(X,Y);
3045}
3046
3048 _Out_ LPPOINT lpPoint
3049)
3050{
3051 return NtUserxGetCursorPos(lpPoint);
3052}
3053
3055 _In_ BOOL bShow
3056)
3057{
3058 return NtUserxShowCursor(bShow);
3059}
3060
3062{
3064}
3065
3067 _In_ HCURSOR hCursor
3068)
3069{
3070 return NtUserDestroyCursor(hCursor, FALSE);
3071}
3072
3073HCURSOR
3074WINAPI
3075GetCursorFrameInfo(HCURSOR hCursor, DWORD reserved, DWORD istep, PINT rate_jiffies, DWORD *num_steps)
3076{
3077 return NtUserGetCursorFrameInfo(hCursor, istep, rate_jiffies, num_steps);
3078}
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
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
BOOL WINAPI FreeResource(HGLOBAL handle)
Definition: res.c:559
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
#define IS_INTRESOURCE(x)
Definition: loader.c:613
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
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
r reserved
Definition: btrfs.c:3006
HINSTANCE hInst
Definition: dxdiag.c:13
#define abs(i)
Definition: fconv.c:206
unsigned 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
PSERVERINFO gpsi
Definition: imm.c:18
#define CURSORF_LRSHARED
Definition: ntuser.h:1201
@ THREADSTATE_GETCURSOR
Definition: ntuser.h:2495
#define CURSORF_FROMRESOURCE
Definition: ntuser.h:1199
DWORD_PTR NTAPI NtUserGetThreadState(DWORD Routine)
Definition: misc.c:240
#define CURSORF_ACONFRAME
Definition: ntuser.h:1204
#define CURSORF_ACON
Definition: ntuser.h:1202
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h: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:530
#define ANI_FLAG_SEQUENCE
Definition: cursoricon.c:70
#define ANI_fram_ID
Definition: cursoricon.c:65
#define ANI_RIFF_ID
Definition: cursoricon.c:60
#define ANI_LIST_ID
Definition: cursoricon.c:61
#define ANI_ACON_ID
Definition: cursoricon.c:62
#define ANI_FLAG_ICON
Definition: cursoricon.c:69
#define ANI_anih_ID
Definition: cursoricon.c:63
static DWORD DWORD istep
Definition: cursoricon.c:1638
#define ANI_seq__ID
Definition: cursoricon.c:64
#define ANI_rate_ID
Definition: cursoricon.c:67
DWORD dwFileSize
Definition: more.c:40
HICON hIcon
Definition: msconfig.c:44
_In_ HANDLE hFile
Definition: mswsock.h:90
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI NTSTATUS NTAPI ZwCallbackReturn(_In_ PVOID Result, _In_ ULONG ResultLength, _In_ NTSTATUS Status)
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define DWORD
Definition: nt_native.h:44
#define UNICODE_NULL
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2033
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO pbmi
Definition: ntgdi.h:2780
EXTINLINE BOOL NtUserxSetCursorPos(INT x, INT y)
Definition: ntwrapper.h:676
EXTINLINE BOOL NtUserxGetCursorPos(POINT *lpPoint)
Definition: ntwrapper.h:811
EXTINLINE HICON NtUserxCreateEmptyCurObject(DWORD_PTR Param)
Definition: ntwrapper.h:616
EXTINLINE INT NtUserxShowCursor(BOOL bShow)
Definition: ntwrapper.h:606
#define LOWORD(l)
Definition: pedump.c:82
#define RT_BITMAP
Definition: pedump.c:364
BYTE * PBYTE
Definition: pedump.c:66
DWORD * PDWORD
Definition: pedump.c:68
#define RT_ICON
Definition: pedump.c:365
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
#define RT_GROUP_CURSOR
Definition: pedump.c:374
unsigned short USHORT
Definition: pedump.c:61
#define RT_GROUP_ICON
Definition: pedump.c:375
#define RT_CURSOR
Definition: pedump.c:363
png_voidp PNGAPI png_get_io_ptr(png_const_structrp png_ptr)
Definition: png.c:686
png_structrp png_ptr
Definition: png.h:1080
png_uint_32
Definition: png.h:1936
#define png_check_sig(sig, n)
Definition: png.h:916
#define PNG_LIBPNG_VER_STRING
Definition: png.h:281
png_const_structrp png_const_inforp info_ptr
Definition: png.h:1937
png_byte * png_bytep
Definition: pngconf.h:579
png_byte ** png_bytepp
Definition: pngconf.h:606
int This channels
Definition: rdpsnd_libao.c:37
#define err(...)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE(s)
Definition: solgame.cpp:4
ICONRESDIR icon
Definition: ntusrtyp.h:88
DWORD dwBytesInRes
Definition: ntusrtyp.h:93
CURSORRESDIR cursor
Definition: ntusrtyp.h:89
union CURSORICONDIRENTRY::@5399 ResInfo
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:3227
BOOL fIcon
Definition: winuser.h:3225
DWORD xHotspot
Definition: winuser.h:3226
HBITMAP hbmColor
Definition: winuser.h:3229
HBITMAP hbmMask
Definition: winuser.h:3228
png_bytep buffer
Definition: cursoricon.c:52
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: name.c:39
const unsigned char * data
Definition: cursoricon.c: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:1922
RGBQUAD bmiColors[1]
Definition: wingdi.h:1923
HBITMAP hbmMask
Definition: ntuser.h:1182
ULONG CURSORF_flags
Definition: ntuser.h:1179
ULONG cy
Definition: ntuser.h:1189
ULONG cx
Definition: ntuser.h:1188
HBITMAP hbmColor
Definition: ntuser.h:1183
HBITMAP hbmAlpha
Definition: ntuser.h:1184
SHORT xHotspot
Definition: ntuser.h:1180
USHORT rt
Definition: ntuser.h:1177
struct tagCURSORDATA * aspcur
Definition: ntuser.h:1192
SHORT yHotspot
Definition: ntuser.h:1181
UCHAR rgbReserved
Definition: bootanim.c:106
UCHAR rgbBlue
Definition: bootanim.c:103
UCHAR rgbRed
Definition: bootanim.c:105
UCHAR rgbGreen
Definition: bootanim.c:104
BYTE rgbtBlue
Definition: wingdi.h:1884
#define max(a, b)
Definition: svc.c:63
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
HINSTANCE User32Instance
Definition: dllmain.c:27
static int __cdecl compr(const void *a, const void *b)
Definition: bidi.c:641
HDC hdcMem
Definition: welcome.c:104
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:245
struct _COPYIMAGE_CALLBACK_ARGUMENTS * PCOPYIMAGE_CALLBACK_ARGUMENTS
BOOL APIENTRY NtUserDrawIconEx(HDC hdc, int xLeft, int yTop, HICON hIcon, int cxWidth, int cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags, BOOL bMetaHDC, PVOID pDIXData)
Definition: cursoricon.c: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:2996
#define IDI_SHIELD
HBITMAP WINAPI LoadBitmapW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpBitmapName)
Definition: cursoricon.c:2515
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:2555
#define EOFM
HCURSOR WINAPI LoadCursorFromFileW(_In_ LPCWSTR lpFileName)
Definition: cursoricon.c:2486
static BOOL CURSORICON_GetCursorDataFromIconInfo(_Out_ CURSORDATA *pCursorData, _In_ ICONINFO *pIconInfo)
Definition: cursoricon.c:988
BOOL WINAPI GetCursorPos(_Out_ LPPOINT lpPoint)
Definition: cursoricon.c:3047
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:3023
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:2472
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:2581
#define COPYIMAGE_VALID_FLAGS
Definition: cursoricon.c:2284
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:2795
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:3039
#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:1944
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpCursorName)
Definition: cursoricon.c:2457
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:3075
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:2500
int WINAPI LookupIconIdFromDirectoryEx(_In_ PBYTE presbits, _In_ BOOL fIcon, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT Flags)
Definition: cursoricon.c:2591
NTSTATUS WINAPI User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: cursoricon.c:2266
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:2363
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpIconName)
Definition: cursoricon.c:2427
static HICON CURSORICON_CopyImage(_In_ HICON hicon, _In_ BOOL bIcon, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuFlags)
Definition: cursoricon.c:2134
#define ZeroMemory
Definition: winbase.h:1753
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ LPCSTR lpFileName
Definition: winbase.h:3112
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:375
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define CopyMemory
Definition: winbase.h:1751
_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:1229
#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:3061
#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:4914
BOOL WINAPI DeleteDC(_In_ HDC)
HBITMAP WINAPI CreateDIBitmap(_In_ HDC hdc, _In_opt_ const BITMAPINFOHEADER *pbmih, _In_ DWORD fdwInit, _In_opt_ const VOID *pvInit, _In_opt_ const BITMAPINFO *pbmi, _In_ UINT uUsage)
#define DI_DEFAULTSIZE
Definition: wingdi.h:69
int WINAPI StretchDIBits(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ const VOID *, _In_ const BITMAPINFO *, _In_ UINT, _In_ DWORD)
HDC WINAPI CreateDCW(_In_opt_ LPCWSTR pszDriver, _In_opt_ LPCWSTR pszDevice, _In_opt_ LPCWSTR psz, _In_opt_ const DEVMODEW *pdmInit)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HICON WINAPI CreateIconFromResource(_In_reads_bytes_(dwResSize) PBYTE presbits, _In_ DWORD dwResSize, _In_ BOOL fIcon, _In_ DWORD dwVer)
DWORD WINAPI GetSysColor(_In_ int)
#define IMAGE_BITMAP
Definition: winuser.h:211
#define LR_LOADTRANSPARENT
Definition: winuser.h:1104
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2958
BOOL WINAPI DestroyCursor(_In_ HCURSOR)
Definition: cursoricon.c:3066
#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:2747
BOOL WINAPI GetIconInfo(_In_ HICON, _Out_ PICONINFO)
Definition: cursoricon.c:2397
#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:2370
#define IDC_NO
Definition: winuser.h:705
#define IDC_ARROW
Definition: winuser.h:695
#define LR_MONOCHROME
Definition: winuser.h:1099
int WINAPI ShowCursor(_In_ BOOL)
Definition: cursoricon.c:3054
#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:2290
#define IDI_APPLICATION
Definition: winuser.h:712
#define IDC_SIZENS
Definition: winuser.h:703
#define IDC_CROSS
Definition: winuser.h:698
#define SM_CYICON
Definition: winuser.h:984
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpIconName)
Definition: cursoricon.c:2412
#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:2380
#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:2530
#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:2442
#define COLOR_3DLIGHT
Definition: winuser.h:951
#define SM_CXCURSOR
Definition: winuser.h:985
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2405
#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