ReactOS  r76032
cursoricon.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS user32.dll
3  * COPYRIGHT: GPL - See COPYING in the top level directory
4  * FILE: win32ss/user/user32/windows/cursoricon.c
5  * PURPOSE: cursor and icons implementation
6  * PROGRAMMER: Jérôme Gardou (jerome.gardou@reactos.org)
7  */
8 
9 #include <user32.h>
10 
11 #include <wine/debug.h>
12 
15 //WINE_DECLARE_DEBUG_CHANNEL(resource);
16 
17 /* We only use Wide string functions */
18 #undef MAKEINTRESOURCE
19 #define MAKEINTRESOURCE MAKEINTRESOURCEW
20 
21 /************* USER32 INTERNAL FUNCTIONS **********/
22 
24 {
25  if (!gpsi->hIconSmWindows)
26  {
27  ERR("Loading System Cursors\n");
44  }
45 }
46 
47 /* This callback routine is called directly after switching to gui mode */
49 WINAPI
51  ULONG ArgumentLength)
52 {
53  BOOL *DefaultCursor = (BOOL*)Arguments;
54  HCURSOR hCursor;
55 
56  /* Load system cursors first */
58 
59  if(*DefaultCursor)
60  {
61  /* set default cursor */
62  hCursor = LoadCursorW(0, IDC_ARROW);
63  SetCursor(hCursor);
64  }
65  else
66  {
67  /* FIXME load system cursor scheme */
68  SetCursor(0);
69  hCursor = LoadCursorW(0, IDC_ARROW);
70  SetCursor(hCursor);
71  }
72 
73  return(ZwCallbackReturn(&hCursor, sizeof(HCURSOR), STATUS_SUCCESS));
74 }
75 
77 {
78  return NtUserGetIconSize(hIcon, 0, &size->cx, &size->cy);
79 }
80 
81 HCURSOR CursorIconToCursor(HICON hIcon, BOOL SemiTransparent)
82 {
84  return NULL;
85 }
86 
87 /************* IMPLEMENTATION HELPERS ******************/
88 
89 static const WCHAR DISPLAYW[] = L"DISPLAY";
90 
91 static void *map_fileW( LPCWSTR name, LPDWORD filesize )
92 {
93  HANDLE hFile, hMapping;
94  LPVOID ptr = NULL;
95 
98  if (hFile != INVALID_HANDLE_VALUE)
99  {
100  hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
101  if (hMapping)
102  {
103  ptr = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
104  CloseHandle( hMapping );
105  if (filesize)
106  *filesize = GetFileSize( hFile, NULL );
107  }
108  CloseHandle( hFile );
109  }
110  return ptr;
111 }
112 
113 static int get_dib_image_size( int width, int height, int depth )
114 {
115  return (((width * depth + 31) / 8) & ~3) * abs( height );
116 }
117 
119 {
120  if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
121  {
122  const RGBTRIPLE *rgb = ((const BITMAPCOREINFO*)info)->bmciColors;
123 
124  if (((const BITMAPCOREINFO*)info)->bmciHeader.bcBitCount != 1) return FALSE;
125 
126  /* Check if the first color is black */
127  if ((rgb->rgbtRed == 0) && (rgb->rgbtGreen == 0) && (rgb->rgbtBlue == 0))
128  {
129  rgb++;
130 
131  /* Check if the second color is white */
132  return ((rgb->rgbtRed == 0xff) && (rgb->rgbtGreen == 0xff)
133  && (rgb->rgbtBlue == 0xff));
134  }
135  else return FALSE;
136  }
137  else /* assume BITMAPINFOHEADER */
138  {
139  const RGBQUAD *rgb = info->bmiColors;
140 
141  if (info->bmiHeader.biBitCount != 1) return FALSE;
142 
143  /* Check if the first color is black */
144  if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) &&
145  (rgb->rgbBlue == 0) && (rgb->rgbReserved == 0))
146  {
147  rgb++;
148 
149  /* Check if the second color is white */
150  return ((rgb->rgbRed == 0xff) && (rgb->rgbGreen == 0xff)
151  && (rgb->rgbBlue == 0xff) && (rgb->rgbReserved == 0));
152  }
153  else return FALSE;
154  }
155 }
156 
157 static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
158 {
159  unsigned int colors, size, masks = 0;
160 
161  if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
162  {
163  const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
164  colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
165  return sizeof(BITMAPCOREHEADER) + colors *
166  ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
167  }
168  else /* assume BITMAPINFOHEADER */
169  {
170  colors = info->bmiHeader.biClrUsed;
171  if (colors > 256) /* buffer overflow otherwise */
172  colors = 256;
173  if (!colors && (info->bmiHeader.biBitCount <= 8))
174  colors = 1 << info->bmiHeader.biBitCount;
175  if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
176  size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
177  return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
178  }
179 }
180 
182  LONG *height, WORD *bpp, DWORD *compr )
183 {
184  if (header->biSize == sizeof(BITMAPCOREHEADER))
185  {
186  const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
187  *width = core->bcWidth;
188  *height = core->bcHeight;
189  *bpp = core->bcBitCount;
190  *compr = 0;
191  return 0;
192  }
193  else if (header->biSize == sizeof(BITMAPINFOHEADER) ||
194  header->biSize == sizeof(BITMAPV4HEADER) ||
195  header->biSize == sizeof(BITMAPV5HEADER))
196  {
197  *width = header->biWidth;
198  *height = header->biHeight;
199  *bpp = header->biBitCount;
200  *compr = header->biCompression;
201  return 1;
202  }
203  ERR("(%d): unknown/wrong size for header\n", header->biSize );
204  return -1;
205 }
206 
207 /* copy an icon bitmap, even when it can't be selected into a DC */
208 /* helper for CreateIconIndirect */
209 static void stretch_blt_icon(HDC hdc_dst, int dst_width, int dst_height, HBITMAP src)
210 {
211  HDC hdc = CreateCompatibleDC( 0 );
212  BITMAP bm;
213  HBITMAP hbmpPrev;
214 
215  GetObjectW(src, sizeof(bm), &bm);
216 
217  hbmpPrev = SelectObject(hdc, src);
218 
219  if (!hbmpPrev) /* do it the hard way */
220  {
221  BITMAPINFO *info;
222  void *bits;
223 
224  if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) return;
225  info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
226  info->bmiHeader.biWidth = bm.bmWidth;
227  info->bmiHeader.biHeight = bm.bmHeight;
228  info->bmiHeader.biPlanes = GetDeviceCaps( hdc_dst, PLANES );
229  info->bmiHeader.biBitCount = GetDeviceCaps( hdc_dst, BITSPIXEL );
231  info->bmiHeader.biSizeImage = get_dib_image_size( bm.bmWidth, bm.bmHeight, info->bmiHeader.biBitCount );
232  info->bmiHeader.biXPelsPerMeter = 0;
233  info->bmiHeader.biYPelsPerMeter = 0;
234  info->bmiHeader.biClrUsed = 0;
235  info->bmiHeader.biClrImportant = 0;
236  bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage );
237  if (bits && GetDIBits( hdc, src, 0, bm.bmHeight, bits, info, DIB_RGB_COLORS ))
238  StretchDIBits( hdc_dst, 0, 0, dst_width, dst_height,
239  0, 0, bm.bmWidth, bm.bmHeight, bits, info, DIB_RGB_COLORS, SRCCOPY );
240 
241  HeapFree( GetProcessHeap(), 0, bits );
242  HeapFree( GetProcessHeap(), 0, info );
243  }
244  else
245  {
246  StretchBlt( hdc_dst, 0, 0, dst_width, dst_height, hdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY );
247  SelectObject(hdc, hbmpPrev);
248  }
249 
250  DeleteDC( hdc );
251 }
252 
253 /***********************************************************************
254  * bmi_has_alpha
255  */
256 static BOOL bmi_has_alpha( const BITMAPINFO *info, const void *bits )
257 {
258  int i;
259  BOOL has_alpha = FALSE;
260  const unsigned char *ptr = bits;
261 
262  if (info->bmiHeader.biBitCount != 32) return FALSE;
263  for (i = 0; i < info->bmiHeader.biWidth * abs(info->bmiHeader.biHeight); i++, ptr += 4)
264  if ((has_alpha = (ptr[3] != 0))) break;
265  return has_alpha;
266 }
267 
268 /***********************************************************************
269  * create_alpha_bitmap
270  *
271  * Create the alpha bitmap for a 32-bpp icon that has an alpha channel.
272  */
273 static
274 HBITMAP
277  _In_opt_ BITMAPINFO *src_info,
278  _In_opt_ const void *color_bits,
279  _In_ LONG width,
280  _In_ LONG height)
281 {
283  HDC hdc = NULL, hdcScreen;
284  unsigned char *ptr;
285  void *bits = NULL;
286  size_t size;
287 
288  hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
289  if (!hdcScreen)
290  return NULL;
291  hdc = CreateCompatibleDC(hdcScreen);
292  if (!hdc)
293  {
294  DeleteDC(hdcScreen);
295  return NULL;
296  }
297 
298  if (color)
299  {
300  BITMAP bm;
301  BITMAPINFO *info = NULL;
302 
303  TRACE("Creating alpha bitmap from existing bitmap.\n");
304 
305  if (!GetObjectW( color, sizeof(bm), &bm ))
306  goto done;
307  if (bm.bmBitsPixel != 32)
308  goto done;
309 
310  size = get_dib_image_size(bm.bmWidth, bm.bmHeight, 32);
311 
312  info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
313  if(!info)
314  goto done;
315  info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
316  info->bmiHeader.biWidth = bm.bmWidth;
317  info->bmiHeader.biHeight = -bm.bmHeight;
318  info->bmiHeader.biPlanes = 1;
319  info->bmiHeader.biBitCount = 32;
321  info->bmiHeader.biSizeImage = size;
322  info->bmiHeader.biXPelsPerMeter = 0;
323  info->bmiHeader.biYPelsPerMeter = 0;
324  info->bmiHeader.biClrUsed = 0;
325  info->bmiHeader.biClrImportant = 0;
326 
327  bits = HeapAlloc(GetProcessHeap(), 0, size);
328  if(!bits)
329  {
330  HeapFree(GetProcessHeap(), 0, info);
331  goto done;
332  }
333  if(!GetDIBits( hdc, color, 0, bm.bmHeight, bits, info, DIB_RGB_COLORS ))
334  {
335  HeapFree(GetProcessHeap(), 0, info);
336  goto done;
337  }
338  if (!bmi_has_alpha( info, bits ))
339  {
340  HeapFree(GetProcessHeap(), 0, info);
341  goto done;
342  }
343 
344  /* pre-multiply by alpha */
345  for (ptr = bits; ptr < ((BYTE*)bits + size); ptr += 4)
346  {
347  unsigned int alpha = ptr[3];
348  ptr[0] = (ptr[0] * alpha) / 255;
349  ptr[1] = (ptr[1] * alpha) / 255;
350  ptr[2] = (ptr[2] * alpha) / 255;
351  }
352 
353  /* Directly create a 32-bits DDB (thanks to undocumented CreateDIBitmap flag). */
354  alpha = CreateDIBitmap(hdc, NULL, CBM_INIT | 2, bits, info, DIB_RGB_COLORS);
355 
356  HeapFree(GetProcessHeap(), 0, info);
357  }
358  else
359  {
360  WORD bpp;
361  DWORD compr;
362  LONG orig_width, orig_height;
363 
364  TRACE("Creating alpha bitmap from bitmap info.\n");
365 
366  if(!bmi_has_alpha(src_info, color_bits))
367  goto done;
368 
369  if(!DIB_GetBitmapInfo(&src_info->bmiHeader, &orig_width, &orig_height, &bpp, &compr))
370  goto done;
371  if(bpp != 32)
372  goto done;
373 
374  size = get_dib_image_size(orig_width, orig_height, bpp);
375  bits = HeapAlloc(GetProcessHeap(), 0, size);
376  if(!bits)
377  goto done;
378  CopyMemory(bits, color_bits, size);
379  /* pre-multiply by alpha */
380  for (ptr = bits; ptr < ((BYTE*)bits + size); ptr += 4)
381  {
382  unsigned int alpha = ptr[3];
383  ptr[0] = (ptr[0] * alpha) / 255;
384  ptr[1] = (ptr[1] * alpha) / 255;
385  ptr[2] = (ptr[2] * alpha) / 255;
386  }
387 
388  /* Create the bitmap. Set the bitmap info to have the right width and height */
389  if(src_info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
390  {
391  ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcWidth = width;
392  ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcHeight = height;
393  }
394  else
395  {
396  src_info->bmiHeader.biWidth = width;
397  src_info->bmiHeader.biHeight = height;
398  }
399  /* Directly create a 32-bits DDB (thanks to undocumented CreateDIBitmap flag). */
400  alpha = CreateDIBitmap(hdcScreen, NULL, 2, NULL, src_info, DIB_RGB_COLORS);
401  /* Restore values */
402  if(src_info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
403  {
404  ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcWidth = orig_width;
405  ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcHeight = orig_height;
406  }
407  else
408  {
409  src_info->bmiHeader.biWidth = orig_width;
410  src_info->bmiHeader.biHeight = orig_height;
411  }
412  if(!alpha)
413  goto done;
414  hbmpOld = SelectObject(hdc, alpha);
415  if(!hbmpOld)
416  {
417  DeleteObject(alpha);
418  alpha = NULL;
419  goto done;
420  }
421  if(!StretchDIBits( hdc, 0, 0, width, height,
422  0, 0, orig_width, orig_height,
423  bits, src_info, DIB_RGB_COLORS, SRCCOPY ))
424  {
425  SelectObject(hdc, hbmpOld);
426  hbmpOld = NULL;
427  DeleteObject(alpha);
428  alpha = NULL;
429  }
430  else
431  {
432  SelectObject(hdc, hbmpOld);
433  }
434  }
435 
436 done:
437  DeleteDC(hdcScreen);
438  DeleteDC( hdc );
439  if(bits) HeapFree(GetProcessHeap(), 0, bits);
440 
441  TRACE("Returning 0x%08x.\n", alpha);
442  return alpha;
443 }
444 
445 #include "pshpack1.h"
446 
447 typedef struct {
448  BYTE bWidth;
449  BYTE bHeight;
450  BYTE bColorCount;
451  BYTE bReserved;
452  WORD xHotspot;
453  WORD yHotspot;
454  DWORD dwDIBSize;
455  DWORD dwDIBOffset;
457 
458 typedef struct
459 {
460  WORD idReserved;
461  WORD idType;
462  WORD idCount;
463  CURSORICONFILEDIRENTRY idEntries[1];
465 
466 #include "poppack.h"
467 
470  _In_ const CURSORICONFILEDIR* dir,
472  _In_ int cxDesired,
473  _In_ int cyDesired,
474  _In_ BOOL bIcon,
475  _In_ DWORD fuLoad
476 )
477 {
478  CURSORICONDIR* fakeDir;
479  CURSORICONDIRENTRY* fakeEntry;
480  WORD i;
482 
483  /* Check our file is what it claims to be */
484  if ( dwFileSize < sizeof(*dir) )
485  return NULL;
486 
487  if (dwFileSize < FIELD_OFFSET(CURSORICONFILEDIR, idEntries[dir->idCount]))
488  return NULL;
489 
490  /*
491  * Cute little hack:
492  * We allocate a buffer, fake it as if it was a pointer to a resource in a module,
493  * pass it to LookupIconIdFromDirectoryEx and get back the index we have to use
494  */
495  fakeDir = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(CURSORICONDIR, idEntries[dir->idCount]));
496  if(!fakeDir)
497  {
499  return NULL;
500  }
501  fakeDir->idReserved = 0;
502  fakeDir->idType = dir->idType;
503  fakeDir->idCount = dir->idCount;
504  for(i = 0; i<dir->idCount; i++)
505  {
506  fakeEntry = &fakeDir->idEntries[i];
507  entry = &dir->idEntries[i];
508  /* Take this as an occasion to perform a size check */
509  if ((entry->dwDIBOffset > dwFileSize)
510  || ((entry->dwDIBOffset + entry->dwDIBSize) > dwFileSize))
511  {
512  ERR("Corrupted icon file?.\n");
513  HeapFree(GetProcessHeap(), 0, fakeDir);
514  return NULL;
515  }
516  /* File icon/cursors are not like resource ones */
517  if(bIcon)
518  {
519  fakeEntry->ResInfo.icon.bWidth = entry->bWidth;
520  fakeEntry->ResInfo.icon.bHeight = entry->bHeight;
521  fakeEntry->ResInfo.icon.bColorCount = 0;
522  fakeEntry->ResInfo.icon.bReserved = 0;
523  }
524  else
525  {
526  fakeEntry->ResInfo.cursor.wWidth = entry->bWidth;
527  fakeEntry->ResInfo.cursor.wHeight = entry->bHeight;
528  }
529  /* Let's assume there's always one plane */
530  fakeEntry->wPlanes = 1;
531  /* We must get the bitcount from the BITMAPINFOHEADER itself */
532  if (((BITMAPINFOHEADER *)((char *)dir + entry->dwDIBOffset))->biSize == sizeof(BITMAPCOREHEADER))
533  fakeEntry->wBitCount = ((BITMAPCOREHEADER *)((char *)dir + entry->dwDIBOffset))->bcBitCount;
534  else
535  fakeEntry->wBitCount = ((BITMAPINFOHEADER *)((char *)dir + entry->dwDIBOffset))->biBitCount;
536  fakeEntry->dwBytesInRes = entry->dwDIBSize;
537  fakeEntry->wResId = i + 1;
538  }
539 
540  /* Now call LookupIconIdFromResourceEx */
541  i = LookupIconIdFromDirectoryEx((PBYTE)fakeDir, bIcon, cxDesired, cyDesired, fuLoad & LR_MONOCHROME);
542  /* We don't need this anymore */
543  HeapFree(GetProcessHeap(), 0, fakeDir);
544  if(i == 0)
545  {
546  WARN("Unable to get a fit entry index.\n");
547  return NULL;
548  }
549 
550  /* We found it */
551  return &dir->idEntries[i-1];
552 }
553 
554 DWORD
556  _In_ const LPBYTE dir,
558  _In_ int cxDesired,
559  _In_ int cyDesired,
560  _In_ BOOL bIcon,
561  _In_ DWORD fuLoad,
562  _Out_ POINT *ptHotSpot
563 )
564 {
566 
567  entry = get_best_icon_file_entry((CURSORICONFILEDIR *) dir, dwFileSize, cxDesired, cyDesired, bIcon, fuLoad);
568 
569  if(ptHotSpot)
570  {
571  ptHotSpot->x = entry->xHotspot;
572  ptHotSpot->y = entry->yHotspot;
573  }
574 
575  if(entry)
576  return entry->dwDIBOffset;
577 
578  return 0;
579 }
580 
581 
582 
583 /************* IMPLEMENTATION CORE ****************/
584 
587  _In_ const BITMAPINFO *pbmi
588 )
589 {
590  UINT ubmiSize = bitmap_info_size(pbmi, DIB_RGB_COLORS);
591  BOOL monochrome = is_dib_monochrome(pbmi);
592  LONG width, height;
593  WORD bpp;
594  DWORD compr;
595  int ibmpType;
596  HDC hdc, hdcScreen;
597  BITMAPINFO* pbmiCopy;
598  HBITMAP hbmpOld = NULL;
599  BOOL bResult = FALSE;
600  const VOID *pvColor, *pvMask;
601 
602  ibmpType = DIB_GetBitmapInfo(&pbmi->bmiHeader, &width, &height, &bpp, &compr);
603  /* Invalid data */
604  if(ibmpType < 0)
605  return FALSE;
606 
607  /* No compression for icons */
608  if(compr != BI_RGB)
609  return FALSE;
610 
611  /* If no dimensions were set, use the one from the icon */
612  if(!pdata->cx) pdata->cx = width;
613  if(!pdata->cy) pdata->cy = height < 0 ? -height/2 : height/2;
614 
615  /* Fix the hotspot coords */
616  if(pdata->rt == (USHORT)((ULONG_PTR)RT_CURSOR))
617  {
618  if(pdata->cx != width)
619  pdata->xHotspot = (pdata->xHotspot * pdata->cx) / width;
620  if(pdata->cy != height/2)
621  pdata->yHotspot = (pdata->yHotspot * pdata->cy * 2) / height;
622  }
623  else
624  {
625  pdata->xHotspot = pdata->cx/2;
626  pdata->yHotspot = pdata->cy/2;
627  }
628 
629  hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
630  if(!hdcScreen)
631  return FALSE;
632  hdc = CreateCompatibleDC(hdcScreen);
633  if(!hdc)
634  {
635  DeleteDC(hdcScreen);
636  return FALSE;
637  }
638 
639  pbmiCopy = HeapAlloc(GetProcessHeap(), 0, max(ubmiSize, FIELD_OFFSET(BITMAPINFO, bmiColors[3])));
640  if(!pbmiCopy)
641  goto done;
642  RtlCopyMemory(pbmiCopy, pbmi, ubmiSize);
643 
644  /* In an icon/cursor, the BITMAPINFO holds twice the height */
645  if(pbmiCopy->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
646  ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcHeight /= 2;
647  else
648  pbmiCopy->bmiHeader.biHeight /= 2;
649  height /= 2;
650 
651  pvColor = (const char*)pbmi + ubmiSize;
652  pvMask = (const char*)pvColor +
653  get_dib_image_size(width, height, bpp );
654 
655  /* Set XOR bits */
656  if(monochrome)
657  {
658  /* Create the 1bpp bitmap which will contain everything */
659  pdata->hbmColor = NULL;
660  pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy * 2, 1, 1, NULL);
661  if(!pdata->hbmMask)
662  goto done;
663  hbmpOld = SelectObject(hdc, pdata->hbmMask);
664  if(!hbmpOld)
665  goto done;
666 
667  if(!StretchDIBits(hdc, 0, pdata->cy, pdata->cx, pdata->cy,
668  0, 0, width, height,
669  pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
670  goto done;
671  pdata->bpp = 1;
672  }
673  else
674  {
675  /* Create the bitmap. It has to be compatible with the screen surface */
676  pdata->hbmColor = CreateCompatibleBitmap(hdcScreen, pdata->cx, pdata->cy);
677  if(!pdata->hbmColor)
678  goto done;
679  /* Create the 1bpp mask bitmap */
680  pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy, 1, 1, NULL);
681  if(!pdata->hbmMask)
682  goto done;
683  hbmpOld = SelectObject(hdc, pdata->hbmColor);
684  if(!hbmpOld)
685  goto done;
686  if(!StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy,
687  0, 0, width, height,
688  pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
689  goto done;
690  pdata->bpp = GetDeviceCaps(hdcScreen, BITSPIXEL);
691  pdata->hbmAlpha = create_alpha_bitmap(NULL, pbmiCopy, pvColor, pdata->cx, pdata->cy);
692 
693  /* Now convert the info to monochrome for the mask bits */
694  if (pbmiCopy->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))
695  {
696  RGBQUAD *rgb = pbmiCopy->bmiColors;
697 
698  pbmiCopy->bmiHeader.biClrUsed = pbmiCopy->bmiHeader.biClrImportant = 2;
699  rgb[0].rgbBlue = rgb[0].rgbGreen = rgb[0].rgbRed = 0x00;
700  rgb[1].rgbBlue = rgb[1].rgbGreen = rgb[1].rgbRed = 0xff;
701  rgb[0].rgbReserved = rgb[1].rgbReserved = 0;
702  pbmiCopy->bmiHeader.biBitCount = 1;
703  }
704  else
705  {
706  RGBTRIPLE *rgb = (RGBTRIPLE *)(((BITMAPCOREHEADER *)pbmiCopy) + 1);
707 
708  rgb[0].rgbtBlue = rgb[0].rgbtGreen = rgb[0].rgbtRed = 0x00;
709  rgb[1].rgbtBlue = rgb[1].rgbtGreen = rgb[1].rgbtRed = 0xff;
710  ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcBitCount = 1;
711  }
712  }
713  /* Set the mask bits */
714  if(!SelectObject(hdc, pdata->hbmMask))
715  goto done;
716  bResult = StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy,
717  0, 0, width, height,
718  pvMask, pbmiCopy, DIB_RGB_COLORS, SRCCOPY) != 0;
719 
720 done:
721  DeleteDC(hdcScreen);
722  if(hbmpOld) SelectObject(hdc, hbmpOld);
723  DeleteDC(hdc);
724  if(pbmiCopy) HeapFree(GetProcessHeap(), 0, pbmiCopy);
725  /* Clean up in case of failure */
726  if(!bResult)
727  {
728  if(pdata->hbmMask) DeleteObject(pdata->hbmMask);
729  if(pdata->hbmColor) DeleteObject(pdata->hbmColor);
730  if(pdata->hbmAlpha) DeleteObject(pdata->hbmAlpha);
731  }
732  return bResult;
733 }
734 
736  _Out_ CURSORDATA* pCursorData,
737  _In_ ICONINFO* pIconInfo
738 )
739 {
740  BITMAP bm;
741 
742  ZeroMemory(pCursorData, sizeof(*pCursorData));
743  if(pIconInfo->hbmColor)
744  {
745  /* We must convert the color bitmap to screen format */
746  HDC hdcScreen, hdcMem;
747  HBITMAP hbmpPrev;
748 
749  /* The mask dictates its dimensions */
750  if (!GetObject(pIconInfo->hbmMask, sizeof(bm), &bm))
751  return FALSE;
752  hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
753  if(!hdcScreen)
754  return FALSE;
755  hdcMem = CreateCompatibleDC(hdcScreen);
756  if(!hdcMem)
757  {
758  DeleteDC(hdcScreen);
759  return FALSE;
760  }
761  pCursorData->hbmColor = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight);
762  DeleteDC(hdcScreen);
763  if (!pCursorData->hbmColor)
764  {
765  DeleteDC(hdcMem);
766  return FALSE;
767  }
768  hbmpPrev = SelectObject(hdcMem, pCursorData->hbmColor);
769  if (!hbmpPrev)
770  {
771  DeleteDC(hdcMem);
772  DeleteObject(pCursorData->hbmColor);
773  return FALSE;
774  }
775  stretch_blt_icon( hdcMem, bm.bmWidth, bm.bmHeight, pIconInfo->hbmColor);
776  SelectObject(hdcMem, hbmpPrev);
777  DeleteDC(hdcMem);
778  }
779  pCursorData->hbmMask = CopyImage(pIconInfo->hbmMask, IMAGE_BITMAP, 0, 0, LR_MONOCHROME);
780  if(!pCursorData->hbmMask)
781  return FALSE;
782 
783  /* Now, fill some information */
784  pCursorData->rt = (USHORT)((ULONG_PTR)(pIconInfo->fIcon ? RT_ICON : RT_CURSOR));
785  if(pCursorData->hbmColor)
786  {
787  GetObject(pCursorData->hbmColor, sizeof(bm), &bm);
788  pCursorData->bpp = bm.bmBitsPixel;
789  pCursorData->cx = bm.bmWidth;
790  pCursorData->cy = bm.bmHeight;
791  if(pCursorData->bpp == 32)
792  pCursorData->hbmAlpha = create_alpha_bitmap(pCursorData->hbmColor, NULL, NULL, 0, 0);
793  }
794  else
795  {
796  GetObject(pCursorData->hbmMask, sizeof(bm), &bm);
797  pCursorData->bpp = 1;
798  pCursorData->cx = bm.bmWidth;
799  pCursorData->cy = bm.bmHeight/2;
800  }
801 
802  if(pIconInfo->fIcon)
803  {
804  pCursorData->xHotspot = pCursorData->cx/2;
805  pCursorData->yHotspot = pCursorData->cy/2;
806  }
807  else
808  {
809  pCursorData->xHotspot = pIconInfo->xHotspot;
810  pCursorData->yHotspot = pIconInfo->yHotspot;
811  }
812 
813  return TRUE;
814 }
815 
816 
817 #define RIFF_FOURCC( c0, c1, c2, c3 ) \
818  ( (DWORD)(BYTE)(c0) | ( (DWORD)(BYTE)(c1) << 8 ) | \
819  ( (DWORD)(BYTE)(c2) << 16 ) | ( (DWORD)(BYTE)(c3) << 24 ) )
820 
821 #define ANI_RIFF_ID RIFF_FOURCC('R', 'I', 'F', 'F')
822 #define ANI_LIST_ID RIFF_FOURCC('L', 'I', 'S', 'T')
823 #define ANI_ACON_ID RIFF_FOURCC('A', 'C', 'O', 'N')
824 #define ANI_anih_ID RIFF_FOURCC('a', 'n', 'i', 'h')
825 #define ANI_seq__ID RIFF_FOURCC('s', 'e', 'q', ' ')
826 #define ANI_fram_ID RIFF_FOURCC('f', 'r', 'a', 'm')
827 #define ANI_rate_ID RIFF_FOURCC('r', 'a', 't', 'e')
828 
829 #define ANI_FLAG_ICON 0x1
830 #define ANI_FLAG_SEQUENCE 0x2
831 
832 #include <pshpack1.h>
833 typedef struct {
834  DWORD header_size;
835  DWORD num_frames;
836  DWORD num_steps;
837  DWORD width;
838  DWORD height;
839  DWORD bpp;
840  DWORD num_planes;
841  DWORD display_rate;
842  DWORD flags;
843 } ani_header;
844 
845 typedef struct {
847  const unsigned char *data;
848 } riff_chunk_t;
849 #include <poppack.h>
850 
851 static void dump_ani_header( const ani_header *header )
852 {
853  TRACE(" header size: %d\n", header->header_size);
854  TRACE(" frames: %d\n", header->num_frames);
855  TRACE(" steps: %d\n", header->num_steps);
856  TRACE(" width: %d\n", header->width);
857  TRACE(" height: %d\n", header->height);
858  TRACE(" bpp: %d\n", header->bpp);
859  TRACE(" planes: %d\n", header->num_planes);
860  TRACE(" display rate: %d\n", header->display_rate);
861  TRACE(" flags: 0x%08x\n", header->flags);
862 }
863 
864 /* Find an animated cursor chunk, given its type and ID */
865 static void riff_find_chunk( DWORD chunk_id, DWORD chunk_type, const riff_chunk_t *parent_chunk, riff_chunk_t *chunk )
866 {
867  const unsigned char *ptr = parent_chunk->data;
868  const unsigned char *end = parent_chunk->data + (parent_chunk->data_size - (2 * sizeof(DWORD)));
869 
870  if (chunk_type == ANI_LIST_ID || chunk_type == ANI_RIFF_ID) end -= sizeof(DWORD);
871 
872  while (ptr < end)
873  {
874  if ((!chunk_type && *(const DWORD *)ptr == chunk_id )
875  || (chunk_type && *(const DWORD *)ptr == chunk_type && *((const DWORD *)ptr + 2) == chunk_id ))
876  {
877  ptr += sizeof(DWORD);
878  chunk->data_size = (*(const DWORD *)ptr + 1) & ~1;
879  ptr += sizeof(DWORD);
880  if (chunk_type == ANI_LIST_ID || chunk_type == ANI_RIFF_ID) ptr += sizeof(DWORD);
881  chunk->data = ptr;
882 
883  return;
884  }
885 
886  ptr += sizeof(DWORD);
887  ptr += (*(const DWORD *)ptr + 1) & ~1;
888  ptr += sizeof(DWORD);
889  }
890 }
891 
893  _Inout_ CURSORDATA* pCurData,
894  _In_ const BYTE *pData,
895  _In_ DWORD dwDataSize,
896  _In_ DWORD fuLoad
897 )
898 {
899  UINT i;
900  const ani_header *pHeader;
901  riff_chunk_t root_chunk = { dwDataSize, pData };
902  riff_chunk_t ACON_chunk = {0};
903  riff_chunk_t anih_chunk = {0};
904  riff_chunk_t fram_chunk = {0};
905  riff_chunk_t rate_chunk = {0};
906  riff_chunk_t seq_chunk = {0};
907  const unsigned char *icon_chunk;
908  const unsigned char *icon_data;
909 
910  /* Find the root chunk */
911  riff_find_chunk( ANI_ACON_ID, ANI_RIFF_ID, &root_chunk, &ACON_chunk );
912  if (!ACON_chunk.data)
913  {
914  ERR("Failed to get root chunk.\n");
915  return FALSE;
916  }
917 
918  /* Find the header chunk */
919  riff_find_chunk( ANI_anih_ID, 0, &ACON_chunk, &anih_chunk );
920  if (!ACON_chunk.data)
921  {
922  ERR("Failed to get header chunk.\n");
923  return FALSE;
924  }
925  pHeader = (ani_header*)anih_chunk.data;
926  dump_ani_header(pHeader);
927 
928  /* Set up the master data */
929  pCurData->CURSORF_flags |= CURSORF_ACON;
930  pCurData->cpcur = pHeader->num_frames;
931  pCurData->cicur = pHeader->num_steps;
932  pCurData->iicur = pHeader->display_rate;
933 
934  /* Get the sequences */
935  if (pHeader->flags & ANI_FLAG_SEQUENCE)
936  {
937  riff_find_chunk( ANI_seq__ID, 0, &ACON_chunk, &seq_chunk );
938  if (!seq_chunk.data)
939  {
940  ERR("No sequence data although the flag is set!\n");
941  return FALSE;
942  }
943  }
944 
945  /* Get the frame rates */
946  riff_find_chunk( ANI_rate_ID, 0, &ACON_chunk, &rate_chunk );
947  if (rate_chunk.data)
948  pCurData->ajifRate = (INT*)rate_chunk.data;
949 
950  /* Get the frames chunk */
951  riff_find_chunk( ANI_fram_ID, ANI_LIST_ID, &ACON_chunk, &fram_chunk );
952  if (!fram_chunk.data)
953  {
954  ERR("Failed to get icon list.\n");
955  return 0;
956  }
957  icon_chunk = fram_chunk.data;
958  icon_data = fram_chunk.data + (2 * sizeof(DWORD));
959 
960  if(pHeader->num_frames > 1)
961  {
962  /* Allocate frame descriptors, step indices and rates */
963  pCurData->aspcur = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
964  pHeader->num_frames * sizeof(CURSORDATA) + pHeader->num_steps * (sizeof(DWORD) + sizeof(INT)));
965  if(!pCurData->aspcur)
966  {
968  return FALSE;
969  }
970  pCurData->aicur = (DWORD*)(pCurData->aspcur + pHeader->num_frames);
971  pCurData->ajifRate = (INT*)(pCurData->aicur + pHeader->num_steps);
972  }
973 
974  for(i=0; i < pHeader->num_frames; i++)
975  {
976  CURSORDATA* pFrameData;
977  const DWORD chunk_size = *(const DWORD *)(icon_chunk + sizeof(DWORD));
978  const BITMAPINFO* pbmi;
979 
980  if(pHeader->num_frames > 1)
981  pFrameData = &pCurData->aspcur[i];
982  else
983  pFrameData = pCurData;
984 
985  pFrameData->rt = pCurData->rt;
986 
987  if (pHeader->flags & ANI_FLAG_ICON)
988  {
989  /* The chunks describe an icon file */
991  (const CURSORICONFILEDIR *) icon_data,
992  chunk_size,
993  pCurData->cx,
994  pCurData->cy,
995  TRUE,
996  fuLoad);
997  if(!pDirEntry)
998  {
999  ERR("Unable to find the right file entry for frame %d.\n", i);
1000  goto error;
1001  }
1002  pFrameData->xHotspot = pDirEntry->xHotspot;
1003  pFrameData->yHotspot = pDirEntry->yHotspot;
1004  if(!pHeader->width || !pHeader->height)
1005  {
1006  pFrameData->cx = pDirEntry->bWidth;
1007  pFrameData->cy = pDirEntry->bHeight;
1008  }
1009  else
1010  {
1011  pFrameData->cx = pHeader->width;
1012  pFrameData->cy = pHeader->height;
1013  }
1014  pbmi = (const BITMAPINFO *) (icon_data + pDirEntry->dwDIBOffset);
1015  }
1016  else
1017  {
1018  /* The chunks just describe bitmaps */
1019  pbmi = (const BITMAPINFO *)icon_data;
1020  pFrameData->xHotspot = pFrameData->yHotspot = 0;
1021  }
1022 
1023  /* Do the real work */
1024  CURSORICON_GetCursorDataFromBMI(pFrameData, pbmi);
1025 
1026  if(pHeader->num_frames > 1)
1027  pFrameData->CURSORF_flags |= CURSORF_ACONFRAME;
1028  else
1029  pFrameData->CURSORF_flags &= ~CURSORF_ACON;
1030 
1031 
1032  /* Next frame */
1033  icon_chunk += chunk_size + (2 * sizeof(DWORD));
1034  icon_data = icon_chunk + (2 * sizeof(DWORD));
1035  }
1036 
1037  if(pHeader->num_frames <= 1)
1038  return TRUE;
1039 
1040  if(rate_chunk.data)
1041  CopyMemory(pCurData->ajifRate, rate_chunk.data, pHeader->num_steps * sizeof(INT));
1042  else
1043  {
1044  for(i=0; i < pHeader->num_steps; i++)
1045  pCurData->ajifRate[i] = pHeader->display_rate;
1046  }
1047 
1048  if (pHeader->flags & ANI_FLAG_SEQUENCE)
1049  {
1050  CopyMemory(pCurData->aicur, seq_chunk.data, pHeader->num_steps * sizeof(DWORD));
1051  }
1052  else
1053  {
1054  for(i=0; i < pHeader->num_steps; i++)
1055  pCurData->aicur[i] = i;
1056  }
1057 
1058  return TRUE;
1059 
1060 error:
1061  HeapFree(GetProcessHeap(), 0, pCurData->aspcur);
1062  ZeroMemory(pCurData, sizeof(CURSORDATA));
1063  return FALSE;
1064 }
1065 
1066 
1067 static
1068 HBITMAP
1071  _In_ LPCWSTR lpszName,
1072  _In_ int cxDesired,
1073  _In_ int cyDesired,
1074  _In_ UINT fuLoad
1075 )
1076 {
1077  const BITMAPINFO* pbmi;
1078  BITMAPINFO* pbmiScaled = NULL;
1079  BITMAPINFO* pbmiCopy = NULL;
1080  const VOID* pvMapping = NULL;
1081  DWORD dwOffset = 0;
1082  HGLOBAL hgRsrc = NULL;
1083  int iBMISize;
1084  PVOID pvBits;
1085  HDC hdcScreen = NULL;
1086  HDC hdc = NULL;
1087  HBITMAP hbmpOld, hbmpRet = NULL;
1088  LONG width, height;
1089  WORD bpp;
1090  DWORD compr;
1091 
1092  /* Map the bitmap info */
1093  if(fuLoad & LR_LOADFROMFILE)
1094  {
1095  const BITMAPFILEHEADER* pbmfh;
1096 
1097  pvMapping = map_fileW(lpszName, NULL);
1098  if(!pvMapping)
1099  return NULL;
1100  pbmfh = pvMapping;
1101  if (pbmfh->bfType != 0x4d42 /* 'BM' */)
1102  {
1103  WARN("Invalid/unsupported bitmap format!\n");
1104  goto end;
1105  }
1106  pbmi = (const BITMAPINFO*)(pbmfh + 1);
1107 
1108  /* Get the image bits */
1109  if(pbmfh->bfOffBits)
1110  dwOffset = pbmfh->bfOffBits - sizeof(BITMAPFILEHEADER);
1111  }
1112  else
1113  {
1114  HRSRC hrsrc;
1115 
1116  /* Caller wants an OEM bitmap */
1117  if(!hinst)
1118  hinst = User32Instance;
1119  hrsrc = FindResourceW(hinst, lpszName, RT_BITMAP);
1120  if(!hrsrc)
1121  return NULL;
1122  hgRsrc = LoadResource(hinst, hrsrc);
1123  if(!hgRsrc)
1124  return NULL;
1125  pbmi = LockResource(hgRsrc);
1126  if(!pbmi)
1127  return NULL;
1128  }
1129 
1130  /* Fix up values */
1131  if(DIB_GetBitmapInfo(&pbmi->bmiHeader, &width, &height, &bpp, &compr) == -1)
1132  goto end;
1133  if((width > 65535) || (height > 65535))
1134  goto end;
1135  if(cxDesired == 0)
1136  cxDesired = width;
1137  if(cyDesired == 0)
1138  cyDesired = height;
1139  else if(height < 0)
1140  cyDesired = -cyDesired;
1141 
1142  iBMISize = bitmap_info_size(pbmi, DIB_RGB_COLORS);
1143 
1144  /* Get a pointer to the image data */
1145  pvBits = (char*)pbmi + (dwOffset ? dwOffset : iBMISize);
1146 
1147  /* Create a copy of the info describing the bitmap in the file */
1148  pbmiCopy = HeapAlloc(GetProcessHeap(), 0, iBMISize);
1149  if(!pbmiCopy)
1150  goto end;
1151  CopyMemory(pbmiCopy, pbmi, iBMISize);
1152 
1153  /* Fix it up, if needed */
1154  if(fuLoad & (LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS))
1155  {
1156  WORD bpp, incr, numColors;
1157  char* pbmiColors;
1158  RGBTRIPLE* ptr;
1159  COLORREF crWindow, cr3DShadow, cr3DFace, cr3DLight;
1160  BYTE pixel = *((BYTE*)pvBits);
1161  UINT i;
1162 
1163  if(pbmiCopy->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1164  {
1165  bpp = ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcBitCount;
1166  numColors = 1 << bpp;
1167  /* BITMAPCOREINFO holds RGBTRIPLEs */
1168  incr = 3;
1169  }
1170  else
1171  {
1172  bpp = pbmiCopy->bmiHeader.biBitCount;
1173  /* BITMAPINFOHEADER holds RGBQUADs */
1174  incr = 4;
1175  numColors = pbmiCopy->bmiHeader.biClrUsed;
1176  if(numColors > 256) numColors = 256;
1177  if (!numColors && (bpp <= 8)) numColors = 1 << bpp;
1178  }
1179 
1180  if(bpp > 8)
1181  goto create_bitmap;
1182 
1183  pbmiColors = (char*)pbmiCopy + pbmiCopy->bmiHeader.biSize;
1184 
1185  /* Get the relevant colors */
1186  crWindow = GetSysColor(COLOR_WINDOW);
1187  cr3DShadow = GetSysColor(COLOR_3DSHADOW);
1188  cr3DFace = GetSysColor(COLOR_3DFACE);
1189  cr3DLight = GetSysColor(COLOR_3DLIGHT);
1190 
1191  /* Fix the transparent palette entry */
1192  if(fuLoad & LR_LOADTRANSPARENT)
1193  {
1194  switch(bpp)
1195  {
1196  case 1: pixel >>= 7; break;
1197  case 4: pixel >>= 4; break;
1198  case 8: break;
1199  default:
1200  FIXME("Unhandled bit depth %d.\n", bpp);
1201  goto create_bitmap;
1202  }
1203 
1204  if(pixel >= numColors)
1205  {
1206  ERR("Wrong pixel passed in.\n");
1207  goto create_bitmap;
1208  }
1209 
1210  /* If both flags are set, we must use COLOR_3DFACE */
1211  if(fuLoad & LR_LOADMAP3DCOLORS) crWindow = cr3DFace;
1212 
1213  /* Define the color */
1214  ptr = (RGBTRIPLE*)(pbmiColors + pixel*incr);
1215  ptr->rgbtBlue = GetBValue(crWindow);
1216  ptr->rgbtGreen = GetGValue(crWindow);
1217  ptr->rgbtRed = GetRValue(crWindow);
1218  goto create_bitmap;
1219  }
1220 
1221  /* If we are here, then LR_LOADMAP3DCOLORS is set without LR_TRANSPARENT */
1222  for(i = 0; i<numColors; i++)
1223  {
1224  ptr = (RGBTRIPLE*)(pbmiColors + i*incr);
1225  if((ptr->rgbtBlue == ptr->rgbtRed) && (ptr->rgbtBlue == ptr->rgbtGreen))
1226  {
1227  if(ptr->rgbtBlue == 128)
1228  {
1229  ptr->rgbtBlue = GetBValue(cr3DShadow);
1230  ptr->rgbtGreen = GetGValue(cr3DShadow);
1231  ptr->rgbtRed = GetRValue(cr3DShadow);
1232  }
1233  if(ptr->rgbtBlue == 192)
1234  {
1235  ptr->rgbtBlue = GetBValue(cr3DFace);
1236  ptr->rgbtGreen = GetGValue(cr3DFace);
1237  ptr->rgbtRed = GetRValue(cr3DFace);
1238  }
1239  if(ptr->rgbtBlue == 223)
1240  {
1241  ptr->rgbtBlue = GetBValue(cr3DLight);
1242  ptr->rgbtGreen = GetGValue(cr3DLight);
1243  ptr->rgbtRed = GetRValue(cr3DLight);
1244  }
1245  }
1246  }
1247  }
1248 
1250  if(fuLoad & LR_CREATEDIBSECTION)
1251  {
1252  /* Allocate the BMI describing the new bitmap */
1253  pbmiScaled = HeapAlloc(GetProcessHeap(), 0, iBMISize);
1254  if(!pbmiScaled)
1255  goto end;
1256  CopyMemory(pbmiScaled, pbmiCopy, iBMISize);
1257 
1258  /* Fix it up */
1259  if(pbmiScaled->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1260  {
1261  BITMAPCOREHEADER* pbmch = (BITMAPCOREHEADER*)&pbmiScaled->bmiHeader;
1262  pbmch->bcWidth = cxDesired;
1263  pbmch->bcHeight = cyDesired;
1264  }
1265  else
1266  {
1267  pbmiScaled->bmiHeader.biWidth = cxDesired;
1268  pbmiScaled->bmiHeader.biHeight = cyDesired;
1269  /* No compression for DIB sections */
1270  pbmiScaled->bmiHeader.biCompression = BI_RGB;
1271  }
1272  }
1273 
1274  /* Top-down image */
1275  if(cyDesired < 0) cyDesired = -cyDesired;
1276 
1277  /* We need a device context */
1278  hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
1279  if(!hdcScreen)
1280  goto end;
1281  hdc = CreateCompatibleDC(hdcScreen);
1282  if(!hdc)
1283  goto end;
1284 
1285  /* Now create the bitmap */
1286  if(fuLoad & LR_CREATEDIBSECTION)
1287  hbmpRet = CreateDIBSection(hdc, pbmiScaled, DIB_RGB_COLORS, NULL, 0, 0);
1288  else
1289  {
1290  if(is_dib_monochrome(pbmiCopy) || (fuLoad & LR_MONOCHROME))
1291  hbmpRet = CreateBitmap(cxDesired, cyDesired, 1, 1, NULL);
1292  else
1293  hbmpRet = CreateCompatibleBitmap(hdcScreen, cxDesired, cyDesired);
1294  }
1295 
1296  if(!hbmpRet)
1297  goto end;
1298 
1299  hbmpOld = SelectObject(hdc, hbmpRet);
1300  if(!hbmpOld)
1301  goto end;
1302  if(!StretchDIBits(hdc, 0, 0, cxDesired, cyDesired,
1303  0, 0, width, height,
1304  pvBits, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
1305  {
1306  ERR("StretchDIBits failed!.\n");
1307  SelectObject(hdc, hbmpOld);
1308  DeleteObject(hbmpRet);
1309  hbmpRet = NULL;
1310  goto end;
1311  }
1312 
1313  SelectObject(hdc, hbmpOld);
1314 
1315 end:
1316  if(hdcScreen)
1317  DeleteDC(hdcScreen);
1318  if(hdc)
1319  DeleteDC(hdc);
1320  if(pbmiScaled)
1321  HeapFree(GetProcessHeap(), 0, pbmiScaled);
1322  if(pbmiCopy)
1323  HeapFree(GetProcessHeap(), 0, pbmiCopy);
1324  if (pvMapping)
1325  UnmapViewOfFile( pvMapping );
1326  if(hgRsrc)
1327  FreeResource(hgRsrc);
1328 
1329  return hbmpRet;
1330 }
1331 
1332 
1333 static
1334 HANDLE
1336  _In_ LPCWSTR lpszName,
1337  _In_ int cxDesired,
1338  _In_ int cyDesired,
1339  _In_ UINT fuLoad,
1340  _In_ BOOL bIcon
1341 )
1342 {
1344  const CURSORICONFILEDIR *dir;
1345  DWORD filesize = 0;
1346  LPBYTE bits;
1347  HANDLE hCurIcon = NULL;
1348  CURSORDATA cursorData;
1349 
1350  TRACE("loading %s\n", debugstr_w( lpszName ));
1351 
1352  bits = map_fileW( lpszName, &filesize );
1353  if (!bits)
1354  return NULL;
1355 
1356  /* Check for .ani. */
1357  if (memcmp( bits, "RIFF", 4 ) == 0)
1358  {
1359  UNIMPLEMENTED;
1360  goto end;
1361  }
1362 
1363  dir = (CURSORICONFILEDIR*) bits;
1364  entry = get_best_icon_file_entry(dir, filesize, cxDesired, cyDesired, bIcon, fuLoad);
1365  if(!entry)
1366  goto end;
1367 
1368  /* Fix dimensions */
1369  if(!cxDesired) cxDesired = entry->bWidth;
1370  if(!cyDesired) cyDesired = entry->bHeight;
1371  /* A bit of preparation */
1372  ZeroMemory(&cursorData, sizeof(cursorData));
1373  if(!bIcon)
1374  {
1375  cursorData.xHotspot = entry->xHotspot;
1376  cursorData.yHotspot = entry->yHotspot;
1377  }
1378  cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR));
1379 
1380  /* Do the dance */
1381  if(!CURSORICON_GetCursorDataFromBMI(&cursorData, (BITMAPINFO*)(&bits[entry->dwDIBOffset])))
1382  goto end;
1383 
1384  hCurIcon = NtUserxCreateEmptyCurObject(FALSE);
1385  if(!hCurIcon)
1386  goto end;
1387 
1388  /* Tell win32k */
1389  if(!NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData))
1390  {
1391  NtUserDestroyCursor(hCurIcon, TRUE);
1392  goto end_error;
1393  }
1394 
1395 end:
1396  UnmapViewOfFile(bits);
1397  return hCurIcon;
1398 
1399  /* Clean up */
1400 end_error:
1401  DeleteObject(cursorData.hbmMask);
1402  if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
1403  if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
1404  UnmapViewOfFile(bits);
1405 
1406  return NULL;
1407 }
1408 
1409 static
1410 HANDLE
1413  _In_ LPCWSTR lpszName,
1414  _In_ int cxDesired,
1415  _In_ int cyDesired,
1416  _In_ UINT fuLoad,
1417  _In_ BOOL bIcon
1418 )
1419 {
1420  HRSRC hrsrc;
1421  HANDLE handle, hCurIcon = NULL;
1422  CURSORICONDIR* dir;
1423  WORD wResId;
1424  LPBYTE bits;
1425  CURSORDATA cursorData;
1426  BOOL bStatus;
1427  UNICODE_STRING ustrRsrc;
1428  UNICODE_STRING ustrModule = {0, 0, NULL};
1429 
1430  /* Fix width/height */
1431  if(fuLoad & LR_DEFAULTSIZE)
1432  {
1433  if(!cxDesired) cxDesired = GetSystemMetrics(bIcon ? SM_CXICON : SM_CXCURSOR);
1434  if(!cyDesired) cyDesired = GetSystemMetrics(bIcon ? SM_CYICON : SM_CYCURSOR);
1435  }
1436 
1437  if(fuLoad & LR_LOADFROMFILE)
1438  {
1439  return CURSORICON_LoadFromFileW(lpszName, cxDesired, cyDesired, fuLoad, bIcon);
1440  }
1441 
1442  /* Check if caller wants OEM icons */
1443  if(!hinst)
1444  hinst = User32Instance;
1445 
1446  if(lpszName)
1447  {
1448  /* Prepare the resource name string */
1449  if(IS_INTRESOURCE(lpszName))
1450  {
1451  ustrRsrc.Buffer = (LPWSTR)lpszName;
1452  ustrRsrc.Length = 0;
1453  ustrRsrc.MaximumLength = 0;
1454  }
1455  else
1456  RtlInitUnicodeString(&ustrRsrc, lpszName);
1457  }
1458 
1459  if(hinst)
1460  {
1461  DWORD size = MAX_PATH;
1462  /* Get the module name string */
1463  while (TRUE)
1464  {
1465  DWORD ret;
1466  ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
1467  if (!ustrModule.Buffer)
1468  {
1470  return NULL;
1471  }
1472  ret = GetModuleFileNameW(hinst, ustrModule.Buffer, size);
1473  if(ret == 0)
1474  {
1475  HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1476  return NULL;
1477  }
1478 
1479  /* This API is completely broken... */
1480  if (ret == size)
1481  {
1482  HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1483  size *= 2;
1484  continue;
1485  }
1486 
1487  ustrModule.Buffer[ret] = UNICODE_NULL;
1488  ustrModule.Length = ret * sizeof(WCHAR);
1489  ustrModule.MaximumLength = size * sizeof(WCHAR);
1490  break;
1491  }
1492  }
1493 
1494  if(fuLoad & LR_SHARED)
1495  {
1497 
1498  TRACE("Checking for an LR_SHARED cursor/icon.\n");
1499  /* Ask win32k */
1500  param.bIcon = bIcon;
1501  param.cx = cxDesired;
1502  param.cy = cyDesired;
1503  hCurIcon = NtUserFindExistingCursorIcon(&ustrModule, &ustrRsrc, &param);
1504  if(hCurIcon)
1505  {
1506  /* Woohoo, got it! */
1507  TRACE("MATCH! %p\n",hCurIcon);
1508  HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1509  return hCurIcon;
1510  }
1511  }
1512 
1513  /* Find resource ID */
1514  hrsrc = FindResourceW(
1515  hinst,
1516  lpszName,
1517  bIcon ? RT_GROUP_ICON : RT_GROUP_CURSOR);
1518 
1519  /* We let FindResource, LoadResource, etc. call SetLastError */
1520  if(!hrsrc)
1521  goto done;
1522 
1523  handle = LoadResource(hinst, hrsrc);
1524  if(!handle)
1525  goto done;
1526 
1527  dir = LockResource(handle);
1528  if(!dir)
1529  goto done;
1530 
1531  wResId = LookupIconIdFromDirectoryEx((PBYTE)dir, bIcon, cxDesired, cyDesired, fuLoad);
1532  FreeResource(handle);
1533 
1534  /* Get the relevant resource pointer */
1535  hrsrc = FindResourceW(
1536  hinst,
1537  MAKEINTRESOURCEW(wResId),
1538  bIcon ? RT_ICON : RT_CURSOR);
1539  if(!hrsrc)
1540  goto done;
1541 
1542  handle = LoadResource(hinst, hrsrc);
1543  if(!handle)
1544  goto done;
1545 
1546  bits = LockResource(handle);
1547  if(!bits)
1548  {
1549  FreeResource(handle);
1550  goto done;
1551  }
1552 
1553  ZeroMemory(&cursorData, sizeof(cursorData));
1554 
1555  /* This is from resource */
1556  cursorData.CURSORF_flags = CURSORF_FROMRESOURCE;
1557 
1558  if(dir->idType == 2)
1559  {
1560  /* idType == 2 for cursor resources */
1561  SHORT* ptr = (SHORT*)bits;
1562  cursorData.xHotspot = ptr[0];
1563  cursorData.yHotspot = ptr[1];
1564  bits += 2*sizeof(SHORT);
1565  }
1566  cursorData.cx = cxDesired;
1567  cursorData.cy = cyDesired;
1568  cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR));
1569 
1570  /* Get the bitmaps */
1572  &cursorData,
1573  (BITMAPINFO*)bits);
1574 
1575  FreeResource( handle );
1576 
1577  if(!bStatus)
1578  goto done;
1579 
1580  /* Create the handle */
1581  hCurIcon = NtUserxCreateEmptyCurObject(FALSE);
1582  if(!hCurIcon)
1583  {
1584  goto end_error;
1585  }
1586 
1587  if(fuLoad & LR_SHARED)
1588  {
1589  cursorData.CURSORF_flags |= CURSORF_LRSHARED;
1590  }
1591 
1592  /* Tell win32k */
1593  bStatus = NtUserSetCursorIconData(hCurIcon, hinst ? &ustrModule : NULL, lpszName ? &ustrRsrc : NULL, &cursorData);
1594 
1595  if(!bStatus)
1596  {
1597  NtUserDestroyCursor(hCurIcon, TRUE);
1598  goto end_error;
1599  }
1600 
1601 done:
1602  if(ustrModule.Buffer)
1603  HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1604  return hCurIcon;
1605 
1606 end_error:
1607  if(ustrModule.Buffer)
1608  HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1609  DeleteObject(cursorData.hbmMask);
1610  if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
1611  if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
1612 
1613  return NULL;
1614 }
1615 
1616 static
1617 HBITMAP
1619  _In_ HBITMAP hnd,
1620  _In_ int desiredx,
1621  _In_ int desiredy,
1622  _In_ UINT flags
1623 )
1624 {
1625  HBITMAP res = NULL;
1626  DIBSECTION ds;
1627  int objSize;
1628  BITMAPINFO * bi;
1629 
1630  objSize = GetObjectW( hnd, sizeof(ds), &ds );
1631  if (!objSize) return 0;
1632  if ((desiredx < 0) || (desiredy < 0)) return 0;
1633 
1634  if (flags & LR_COPYFROMRESOURCE)
1635  {
1636  FIXME("The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
1637  }
1638 
1639  if (flags & LR_COPYRETURNORG)
1640  {
1641  FIXME("The flag LR_COPYRETURNORG is not implemented for bitmaps\n");
1642  }
1643 
1644  if (desiredx == 0) desiredx = ds.dsBm.bmWidth;
1645  if (desiredy == 0) desiredy = ds.dsBm.bmHeight;
1646 
1647  /* Allocate memory for a BITMAPINFOHEADER structure and a
1648  color table. The maximum number of colors in a color table
1649  is 256 which corresponds to a bitmap with depth 8.
1650  Bitmaps with higher depths don't have color tables. */
1651  bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1652  if (!bi) return 0;
1653 
1654  bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
1655  bi->bmiHeader.biPlanes = ds.dsBm.bmPlanes;
1656  bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
1658 
1659  if (flags & LR_CREATEDIBSECTION)
1660  {
1661  /* Create a DIB section. LR_MONOCHROME is ignored */
1662  void * bits;
1664 
1665  if (objSize == sizeof(DIBSECTION))
1666  {
1667  /* The source bitmap is a DIB.
1668  Get its attributes to create an exact copy */
1669  memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
1670  }
1671 
1672  bi->bmiHeader.biWidth = desiredx;
1673  bi->bmiHeader.biHeight = desiredy;
1674 
1675  /* Get the color table or the color masks */
1676  GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
1677 
1678  res = CreateDIBSection(dc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
1679  DeleteDC(dc);
1680  }
1681  else
1682  {
1683  /* Create a device-dependent bitmap */
1684 
1685  BOOL monochrome = (flags & LR_MONOCHROME);
1686 
1687  if (objSize == sizeof(DIBSECTION))
1688  {
1689  /* The source bitmap is a DIB section.
1690  Get its attributes */
1692  bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
1693  bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
1694  GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
1695  DeleteDC(dc);
1696 
1697  if (!monochrome && ds.dsBm.bmBitsPixel == 1)
1698  {
1699  /* Look if the colors of the DIB are black and white */
1700 
1701  monochrome =
1702  (bi->bmiColors[0].rgbRed == 0xff
1703  && bi->bmiColors[0].rgbGreen == 0xff
1704  && bi->bmiColors[0].rgbBlue == 0xff
1705  && bi->bmiColors[0].rgbReserved == 0
1706  && bi->bmiColors[1].rgbRed == 0
1707  && bi->bmiColors[1].rgbGreen == 0
1708  && bi->bmiColors[1].rgbBlue == 0
1709  && bi->bmiColors[1].rgbReserved == 0)
1710  ||
1711  (bi->bmiColors[0].rgbRed == 0
1712  && bi->bmiColors[0].rgbGreen == 0
1713  && bi->bmiColors[0].rgbBlue == 0
1714  && bi->bmiColors[0].rgbReserved == 0
1715  && bi->bmiColors[1].rgbRed == 0xff
1716  && bi->bmiColors[1].rgbGreen == 0xff
1717  && bi->bmiColors[1].rgbBlue == 0xff
1718  && bi->bmiColors[1].rgbReserved == 0);
1719  }
1720  }
1721  else if (!monochrome)
1722  {
1723  monochrome = ds.dsBm.bmBitsPixel == 1;
1724  }
1725 
1726  if (monochrome)
1727  {
1728  res = CreateBitmap(desiredx, desiredy, 1, 1, NULL);
1729  }
1730  else
1731  {
1732  HDC screenDC = GetDC(NULL);
1733  res = CreateCompatibleBitmap(screenDC, desiredx, desiredy);
1734  ReleaseDC(NULL, screenDC);
1735  }
1736  }
1737 
1738  if (res)
1739  {
1740  /* Only copy the bitmap if it's a DIB section or if it's
1741  compatible to the screen */
1742  BOOL copyContents;
1743 
1744  if (objSize == sizeof(DIBSECTION))
1745  {
1746  copyContents = TRUE;
1747  }
1748  else
1749  {
1750  HDC screenDC = GetDC(NULL);
1751  int screen_depth = GetDeviceCaps(screenDC, BITSPIXEL);
1752  ReleaseDC(NULL, screenDC);
1753 
1754  copyContents = (ds.dsBm.bmBitsPixel == 1 || ds.dsBm.bmBitsPixel == screen_depth);
1755  }
1756 
1757  if (copyContents)
1758  {
1759  /* The source bitmap may already be selected in a device context,
1760  use GetDIBits/StretchDIBits and not StretchBlt */
1761 
1762  HDC dc;
1763  void * bits;
1764 
1765  dc = CreateCompatibleDC(NULL);
1766 
1767  bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
1768  bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
1769  bi->bmiHeader.biSizeImage = 0;
1770  bi->bmiHeader.biClrUsed = 0;
1771  bi->bmiHeader.biClrImportant = 0;
1772 
1773  /* Fill in biSizeImage */
1774  GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
1776 
1777  if (bits)
1778  {
1779  HBITMAP oldBmp;
1780 
1781  /* Get the image bits of the source bitmap */
1782  GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
1783 
1784  /* Copy it to the destination bitmap */
1785  oldBmp = SelectObject(dc, res);
1786  StretchDIBits(dc, 0, 0, desiredx, desiredy,
1787  0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight,
1788  bits, bi, DIB_RGB_COLORS, SRCCOPY);
1789  SelectObject(dc, oldBmp);
1790 
1791  HeapFree(GetProcessHeap(), 0, bits);
1792  }
1793 
1794  DeleteDC(dc);
1795  }
1796 
1797  if (flags & LR_COPYDELETEORG)
1798  {
1799  DeleteObject(hnd);
1800  }
1801  }
1802  HeapFree(GetProcessHeap(), 0, bi);
1803  return res;
1804 }
1805 
1806 static
1807 HICON
1809  _In_ HICON hicon,
1810  _In_ BOOL bIcon,
1811  _In_ int cxDesired,
1812  _In_ int cyDesired,
1813  _In_ UINT fuFlags
1814 )
1815 {
1816  HICON ret = NULL;
1817  ICONINFO ii;
1818  CURSORDATA CursorData;
1819 
1820  if (fuFlags & LR_COPYFROMRESOURCE)
1821  {
1822  /* Get the icon module/resource names */
1823  UNICODE_STRING ustrModule;
1824  UNICODE_STRING ustrRsrc;
1825  HMODULE hModule;
1826 
1827  ustrModule.MaximumLength = 0;
1828  ustrRsrc.MaximumLength = 0;
1829 
1830  /* Get the buffer size */
1831  if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
1832  {
1833  return NULL;
1834  }
1835 
1836  ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength);
1837  if (!ustrModule.Buffer)
1838  {
1840  return NULL;
1841  }
1842 
1843  if (ustrRsrc.MaximumLength)
1844  {
1845  ustrRsrc.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength);
1846  if (!ustrRsrc.Buffer)
1847  {
1848  HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1850  return NULL;
1851  }
1852  }
1853 
1854  if (!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
1855  {
1856  HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1857  if (!IS_INTRESOURCE(ustrRsrc.Buffer))
1858  HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer);
1859  return NULL;
1860  }
1861 
1862  /* NULL-terminate our strings */
1863  ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = UNICODE_NULL;
1864  if (!IS_INTRESOURCE(ustrRsrc.Buffer))
1865  ustrRsrc.Buffer[ustrRsrc.Length/sizeof(WCHAR)] = UNICODE_NULL;
1866 
1867  TRACE("Got module %wZ, resource %p (%S).\n", &ustrModule,
1868  ustrRsrc.Buffer, IS_INTRESOURCE(ustrRsrc.Buffer) ? L"" : ustrRsrc.Buffer);
1869 
1870  /* Get the module handle or load the module */
1872  if (!hModule)
1873  {
1874  DWORD err = GetLastError();
1875  ERR("Unable to load/use module '%wZ' in process %lu, error %lu.\n", &ustrModule, GetCurrentProcessId(), err);
1877  goto leave;
1878  }
1879 
1880  /* Call the relevant function */
1881  ret = CURSORICON_LoadImageW(
1882  hModule,
1883  ustrRsrc.Buffer,
1884  cxDesired,
1885  cyDesired,
1886  fuFlags & (LR_DEFAULTSIZE | LR_SHARED),
1887  bIcon);
1888 
1889  FreeLibrary(hModule);
1890 
1891  /* If we're here, that means that the passed icon is shared. Don't destroy it, even if LR_COPYDELETEORG is specified */
1892  leave:
1893  HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
1894  if (!IS_INTRESOURCE(ustrRsrc.Buffer))
1895  HeapFree(GetProcessHeap(), 0, ustrRsrc.Buffer);
1896 
1897  TRACE("Returning 0x%08x.\n", ret);
1898 
1899  return ret;
1900  }
1901 
1902  /* This is a regular copy */
1903  if (fuFlags & ~(LR_COPYDELETEORG | LR_SHARED))
1904  FIXME("Unimplemented flags: 0x%08x\n", fuFlags);
1905 
1906  if (!GetIconInfo(hicon, &ii))
1907  {
1908  ERR("GetIconInfo failed.\n");
1909  return NULL;
1910  }
1911 
1912  /* This is CreateIconIndirect with the LR_SHARED coat added */
1913  if (!CURSORICON_GetCursorDataFromIconInfo(&CursorData, &ii))
1914  goto Leave;
1915 
1916  if (fuFlags & LR_SHARED)
1917  CursorData.CURSORF_flags |= CURSORF_LRSHARED;
1918 
1920  if (!ret)
1921  goto Leave;
1922 
1923  if (!NtUserSetCursorIconData(ret, NULL, NULL, &CursorData))
1924  {
1925  NtUserDestroyCursor(ret, TRUE);
1926  goto Leave;
1927  }
1928 
1929 Leave:
1930  DeleteObject(ii.hbmMask);
1931  if (ii.hbmColor) DeleteObject(ii.hbmColor);
1932 
1933  if (ret && (fuFlags & LR_COPYDELETEORG))
1934  DestroyIcon(hicon);
1935 
1936  return ret;
1937 }
1938 
1940 User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength)
1941 {
1943  HANDLE Result;
1944  Common = (PCOPYIMAGE_CALLBACK_ARGUMENTS) Arguments;
1945 
1946  Result = CopyImage(Common->hImage,
1947  Common->uType,
1948  Common->cxDesired,
1949  Common->cyDesired,
1950  Common->fuFlags);
1951 
1952  return ZwCallbackReturn(&Result, sizeof(HANDLE), STATUS_SUCCESS);
1953 }
1954 
1955 
1956 /************* PUBLIC FUNCTIONS *******************/
1957 
1959  _In_ HANDLE hImage,
1960  _In_ UINT uType,
1961  _In_ int cxDesired,
1962  _In_ int cyDesired,
1963  _In_ UINT fuFlags
1964 )
1965 {
1966  TRACE("hImage=%p, uType=%u, cxDesired=%d, cyDesired=%d, fuFlags=%x\n",
1967  hImage, uType, cxDesired, cyDesired, fuFlags);
1968  switch(uType)
1969  {
1970  case IMAGE_BITMAP:
1971  return BITMAP_CopyImage(hImage, cxDesired, cyDesired, fuFlags);
1972  case IMAGE_CURSOR:
1973  case IMAGE_ICON:
1974  return CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, cxDesired, cyDesired, fuFlags);
1975  default:
1977  break;
1978  }
1979  return NULL;
1980 }
1981 
1983  _In_ HICON hIcon
1984 )
1985 {
1986  return CURSORICON_CopyImage(hIcon, FALSE, 0, 0, 0);
1987 }
1988 
1990  _In_ HDC hDC,
1991  _In_ int X,
1992  _In_ int Y,
1993  _In_ HICON hIcon
1994 )
1995 {
1996  return DrawIconEx(hDC, X, Y, hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
1997 }
1998 
2000  _In_ HDC hdc,
2001  _In_ int xLeft,
2002  _In_ int yTop,
2003  _In_ HICON hIcon,
2004  _In_ int cxWidth,
2005  _In_ int cyWidth,
2006  _In_ UINT istepIfAniCur,
2007  _In_opt_ HBRUSH hbrFlickerFreeDraw,
2008  _In_ UINT diFlags
2009 )
2010 {
2011  return NtUserDrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth,
2012  istepIfAniCur, hbrFlickerFreeDraw, diFlags,
2013  0, 0);
2014 }
2015 
2017  _In_ HICON hIcon,
2018  _Out_ PICONINFO piconinfo
2019 )
2020 {
2021  return NtUserGetIconInfo(hIcon, piconinfo, NULL, NULL, NULL, FALSE);
2022 }
2023 
2025  _In_ HICON hIcon
2026 )
2027 {
2028  return NtUserDestroyCursor(hIcon, FALSE);
2029 }
2030 
2033  _In_ LPCSTR lpIconName
2034 )
2035 {
2036  TRACE("%p, %s\n", hInstance, debugstr_a(lpIconName));
2037 
2038  return LoadImageA(hInstance,
2039  lpIconName,
2040  IMAGE_ICON,
2041  0,
2042  0,
2044 }
2045 
2048  _In_ LPCWSTR lpIconName
2049 )
2050 {
2051  TRACE("%p, %s\n", hInstance, debugstr_w(lpIconName));
2052 
2053  return LoadImageW(hInstance,
2054  lpIconName,
2055  IMAGE_ICON,
2056  0,
2057  0,
2059 }
2060 
2063  _In_ LPCSTR lpCursorName
2064 )
2065 {
2066  TRACE("%p, %s\n", hInstance, debugstr_a(lpCursorName));
2067 
2068  return LoadImageA(hInstance,
2069  lpCursorName,
2070  IMAGE_CURSOR,
2071  0,
2072  0,
2074 }
2075 
2078  _In_ LPCWSTR lpCursorName
2079 )
2080 {
2081  TRACE("%p, %s\n", hInstance, debugstr_w(lpCursorName));
2082 
2083  return LoadImageW(hInstance,
2084  lpCursorName,
2085  IMAGE_CURSOR,
2086  0,
2087  0,
2089 }
2090 
2093 )
2094 {
2095  TRACE("%s\n", debugstr_a(lpFileName));
2096 
2097  return LoadImageA(NULL,
2098  lpFileName,
2099  IMAGE_CURSOR,
2100  0,
2101  0,
2103 }
2104 
2107 )
2108 {
2109  TRACE("%s\n", debugstr_w(lpFileName));
2110 
2111  return LoadImageW(NULL,
2112  lpFileName,
2113  IMAGE_CURSOR,
2114  0,
2115  0,
2117 }
2118 
2121  _In_ LPCSTR lpBitmapName
2122 )
2123 {
2124  TRACE("%p, %s\n", hInstance, debugstr_a(lpBitmapName));
2125 
2126  return LoadImageA(hInstance,
2127  lpBitmapName,
2128  IMAGE_BITMAP,
2129  0,
2130  0,
2131  0);
2132 }
2133 
2136  _In_ LPCWSTR lpBitmapName
2137 )
2138 {
2139  TRACE("%p, %s\n", hInstance, debugstr_w(lpBitmapName));
2140 
2141  return LoadImageW(hInstance,
2142  lpBitmapName,
2143  IMAGE_BITMAP,
2144  0,
2145  0,
2146  0);
2147 }
2148 
2151  _In_ LPCSTR lpszName,
2152  _In_ UINT uType,
2153  _In_ int cxDesired,
2154  _In_ int cyDesired,
2155  _In_ UINT fuLoad
2156 )
2157 {
2158  HANDLE res;
2159  LPWSTR u_name;
2160  DWORD len;
2161 
2162  if (IS_INTRESOURCE(lpszName))
2163  return LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired, cyDesired, fuLoad);
2164 
2165  len = MultiByteToWideChar( CP_ACP, 0, lpszName, -1, NULL, 0 );
2166  u_name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2167  MultiByteToWideChar( CP_ACP, 0, lpszName, -1, u_name, len );
2168 
2169  res = LoadImageW(hinst, u_name, uType, cxDesired, cyDesired, fuLoad);
2170  HeapFree(GetProcessHeap(), 0, u_name);
2171  return res;
2172 }
2173 
2176  _In_ LPCWSTR lpszName,
2177  _In_ UINT uType,
2178  _In_ int cxDesired,
2179  _In_ int cyDesired,
2180  _In_ UINT fuLoad
2181 )
2182 {
2183  TRACE("hinst 0x%p, name %s, uType 0x%08x, cxDesired %d, cyDesired %d, fuLoad 0x%08x.\n",
2184  hinst, debugstr_w(lpszName), uType, cxDesired, cyDesired, fuLoad);
2185  /* Redirect to each implementation */
2186  switch(uType)
2187  {
2188  case IMAGE_BITMAP:
2189  return BITMAP_LoadImageW(hinst, lpszName, cxDesired, cyDesired, fuLoad);
2190  case IMAGE_CURSOR:
2191  case IMAGE_ICON:
2192  return CURSORICON_LoadImageW(hinst, lpszName, cxDesired, cyDesired, fuLoad, uType == IMAGE_ICON);
2193  default:
2195  break;
2196  }
2197  return NULL;
2198 }
2199 
2201  _In_ PBYTE presbits,
2202  _In_ BOOL fIcon
2203 )
2204 {
2205  return LookupIconIdFromDirectoryEx( presbits, fIcon,
2208 }
2209 
2211  _In_ PBYTE presbits,
2212  _In_ BOOL fIcon,
2213  _In_ int cxDesired,
2214  _In_ int cyDesired,
2215  _In_ UINT Flags
2216 )
2217 {
2218  WORD bppDesired;
2219  CURSORICONDIR* dir = (CURSORICONDIR*)presbits;
2221  int i, numMatch = 0, iIndex = -1;
2222  WORD width, height, BitCount = 0;
2223  BOOL notPaletted = FALSE;
2224  ULONG bestScore = 0xFFFFFFFF, score;
2225 
2226  TRACE("%p, %x, %i, %i, %x.\n", presbits, fIcon, cxDesired, cyDesired, Flags);
2227 
2228  if(!(dir && !dir->idReserved && (dir->idType & 3)))
2229  {
2230  WARN("Invalid resource.\n");
2231  return 0;
2232  }
2233 
2234  if(Flags & LR_MONOCHROME)
2235  bppDesired = 1;
2236  else
2237  {
2238  HDC icScreen;
2239  icScreen = CreateICW(DISPLAYW, NULL, NULL, NULL);
2240  if(!icScreen)
2241  return FALSE;
2242 
2243  bppDesired = GetDeviceCaps(icScreen, BITSPIXEL);
2244  DeleteDC(icScreen);
2245  }
2246 
2247  if(!cxDesired)
2248  cxDesired = Flags & LR_DEFAULTSIZE ? GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR) : 256;
2249  if(!cyDesired)
2250  cyDesired = Flags & LR_DEFAULTSIZE ? GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR) : 256;
2251 
2252  /* Find the best match for the desired size */
2253  for(i = 0; i < dir->idCount; i++)
2254  {
2255  entry = &dir->idEntries[i];
2256  width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2257  /* Height is twice as big in cursor resources */
2258  height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2259  /* 0 represents 256 */
2260  if(!width) width = 256;
2261  if(!height) height = 256;
2262  /* Calculate the "score" (lower is better) */
2263  score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2264  if( score > bestScore)
2265  continue;
2266  /* Bigger than requested lowers the score */
2267  if(width > cxDesired)
2268  score -= width - cxDesired;
2269  if(height > cyDesired)
2270  score -= height - cyDesired;
2271  if(score > bestScore)
2272  continue;
2273  if(score == bestScore)
2274  {
2275  if(entry->wBitCount > BitCount)
2276  BitCount = entry->wBitCount;
2277  numMatch++;
2278  continue;
2279  }
2280  iIndex = i;
2281  numMatch = 1;
2282  bestScore = score;
2283  BitCount = entry->wBitCount;
2284  }
2285 
2286  if(numMatch == 1)
2287  {
2288  /* Only one entry fits the asked dimensions */
2289  return dir->idEntries[iIndex].wResId;
2290  }
2291 
2292  /* Avoid paletted icons on non-paletted device */
2293  if (bppDesired > 8 && BitCount > 8)
2294  notPaletted = TRUE;
2295 
2296  BitCount = 0;
2297  iIndex = -1;
2298  /* Now find the entry with the best depth */
2299  for(i = 0; i < dir->idCount; i++)
2300  {
2301  entry = &dir->idEntries[i];
2302  width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2303  height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2304  /* 0 represents 256 */
2305  if(!width) width = 256;
2306  if(!height) height = 256;
2307  /* Check if this is the best match we had */
2308  score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2309  if(width > cxDesired)
2310  score -= width - cxDesired;
2311  if(height > cyDesired)
2312  score -= height - cyDesired;
2313  if(score != bestScore)
2314  continue;
2315  /* Exact match? */
2316  if(entry->wBitCount == bppDesired)
2317  return entry->wResId;
2318  /* We take the highest possible but smaller than the display depth */
2319  if((entry->wBitCount > BitCount) && (entry->wBitCount < bppDesired))
2320  {
2321  /* Avoid paletted icons on non paletted devices */
2322  if ((entry->wBitCount <= 8) && notPaletted)
2323  continue;
2324  iIndex = i;
2325  BitCount = entry->wBitCount;
2326  }
2327  }
2328 
2329  if(iIndex >= 0)
2330  return dir->idEntries[iIndex].wResId;
2331 
2332  /* No inferior or equal depth available. Get the smallest bigger one */
2333  BitCount = 0xFFFF;
2334  iIndex = -1;
2335  for(i = 0; i < dir->idCount; i++)
2336  {
2337  entry = &dir->idEntries[i];
2338  width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
2339  height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
2340  /* 0 represents 256 */
2341  if(!width) width = 256;
2342  if(!height) height = 256;
2343  /* Check if this is the best match we had */
2344  score = 2*(abs(width - cxDesired) + abs(height - cyDesired));
2345  if(width > cxDesired)
2346  score -= width - cxDesired;
2347  if(height > cyDesired)
2348  score -= height - cyDesired;
2349  if(score != bestScore)
2350  continue;
2351  /* Check the bit depth */
2352  if(entry->wBitCount < BitCount)
2353  {
2354  if((entry->wBitCount <= 8) && notPaletted)
2355  continue;
2356  iIndex = i;
2357  BitCount = entry->wBitCount;
2358  }
2359  }
2360  if (iIndex >= 0)
2361  return dir->idEntries[iIndex].wResId;
2362 
2363  return 0;
2364 }
2365 
2368  _In_ int nWidth,
2369  _In_ int nHeight,
2370  _In_ BYTE cPlanes,
2371  _In_ BYTE cBitsPixel,
2372  _In_ const BYTE *lpbANDbits,
2373  _In_ const BYTE *lpbXORbits
2374 )
2375 {
2376  ICONINFO iinfo;
2377  HICON hIcon;
2378 
2379  TRACE_(icon)("%dx%d, planes %d, bpp %d, xor %p, and %p\n",
2380  nWidth, nHeight, cPlanes, cBitsPixel, lpbXORbits, lpbANDbits);
2381 
2382  iinfo.fIcon = TRUE;
2383  iinfo.xHotspot = nWidth / 2;
2384  iinfo.yHotspot = nHeight / 2;
2385  if (cPlanes * cBitsPixel > 1)
2386  {
2387  iinfo.hbmColor = CreateBitmap( nWidth, nHeight, cPlanes, cBitsPixel, lpbXORbits );
2388  iinfo.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, lpbANDbits );
2389  }
2390  else
2391  {
2392  iinfo.hbmMask = CreateBitmap( nWidth, nHeight * 2, 1, 1, lpbANDbits );
2393  iinfo.hbmColor = NULL;
2394  }
2395 
2396  hIcon = CreateIconIndirect( &iinfo );
2397 
2398  DeleteObject( iinfo.hbmMask );
2399  if (iinfo.hbmColor) DeleteObject( iinfo.hbmColor );
2400 
2401  return hIcon;
2402 }
2403 
2405  _In_ PBYTE presbits,
2406  _In_ DWORD dwResSize,
2407  _In_ BOOL fIcon,
2408  _In_ DWORD dwVer
2409 )
2410 {
2411  return CreateIconFromResourceEx( presbits, dwResSize, fIcon, dwVer, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
2412 }
2413 
2415  _In_ PBYTE pbIconBits,
2416  _In_ DWORD cbIconBits,
2417  _In_ BOOL fIcon,
2418  _In_ DWORD dwVersion,
2419  _In_ int cxDesired,
2420  _In_ int cyDesired,
2421  _In_ UINT uFlags
2422 )
2423 {
2424  CURSORDATA cursorData;
2425  HICON hIcon;
2426  BOOL isAnimated;
2427 
2428  TRACE("%p, %lu, %lu, %lu, %i, %i, %lu.\n", pbIconBits, cbIconBits, fIcon, dwVersion, cxDesired, cyDesired, uFlags);
2429 
2430  if(uFlags & LR_DEFAULTSIZE)
2431  {
2432  if(!cxDesired) cxDesired = GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR);
2433  if(!cyDesired) cyDesired = GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR);
2434  }
2435 
2436  ZeroMemory(&cursorData, sizeof(cursorData));
2437  cursorData.cx = cxDesired;
2438  cursorData.cy = cyDesired;
2439  cursorData.rt = (USHORT)((ULONG_PTR)(fIcon ? RT_ICON : RT_CURSOR));
2440 
2441  /* Convert to win32k-ready data */
2442  if(!memcmp(pbIconBits, "RIFF", 4))
2443  {
2444  if(!CURSORICON_GetCursorDataFromANI(&cursorData, pbIconBits, cbIconBits, uFlags))
2445  {
2446  ERR("Could not get cursor data from .ani.\n");
2447  return NULL;
2448  }
2449  isAnimated = !!(cursorData.CURSORF_flags & CURSORF_ACON);
2450  }
2451  else
2452  {
2453  /* It is possible to pass Icon Directories to this API */
2454  int wResId = LookupIconIdFromDirectoryEx(pbIconBits, fIcon, cxDesired, cyDesired, uFlags);
2455  HANDLE ResHandle = NULL;
2456  if(wResId)
2457  {
2458  HINSTANCE hinst;
2459  HRSRC hrsrc;
2460  CURSORICONDIR* pCurIconDir = (CURSORICONDIR*)pbIconBits;
2461 
2462  TRACE("Pointer points to a directory structure.\n");
2463 
2464  /* So this is a pointer to an icon directory structure. Find the module */
2465  if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
2466  (LPCWSTR)pbIconBits,
2467  &hinst))
2468  {
2469  return NULL;
2470  }
2471 
2472  /* Check we were given the right type of resource */
2473  if((fIcon && pCurIconDir->idType == 2) || (!fIcon && pCurIconDir->idType == 1))
2474  {
2475  WARN("Got a %s directory pointer, but called for a %s", fIcon ? "cursor" : "icon", fIcon ? "icon" : "cursor");
2476  return NULL;
2477  }
2478 
2479  /* Get the relevant resource pointer */
2480  hrsrc = FindResourceW(
2481  hinst,
2482  MAKEINTRESOURCEW(wResId),
2483  fIcon ? RT_ICON : RT_CURSOR);
2484  if (!hrsrc)
2485  return NULL;
2486 
2487  ResHandle = LoadResource(hinst, hrsrc);
2488  if (!ResHandle)
2489  return NULL;
2490 
2491  pbIconBits = LockResource(ResHandle);
2492  if (!pbIconBits)
2493  {
2494  FreeResource(ResHandle);
2495  return NULL;
2496  }
2497  }
2498  if(!fIcon)
2499  {
2500  WORD* pt = (WORD*)pbIconBits;
2501  cursorData.xHotspot = *pt++;
2502  cursorData.yHotspot = *pt++;
2503  pbIconBits = (PBYTE)pt;
2504  }
2505 
2506  if (!CURSORICON_GetCursorDataFromBMI(&cursorData, (BITMAPINFO*)pbIconBits))
2507  {
2508  ERR("Couldn't fill the CURSORDATA structure.\n");
2509  if (ResHandle)
2510  FreeResource(ResHandle);
2511  return NULL;
2512  }
2513  if (ResHandle)
2514  FreeResource(ResHandle);
2515  isAnimated = FALSE;
2516  }
2517 
2518  if (uFlags & LR_SHARED)
2519  cursorData.CURSORF_flags |= CURSORF_LRSHARED;
2520 
2521  hIcon = NtUserxCreateEmptyCurObject(isAnimated);
2522  if (!hIcon)
2523  goto end_error;
2524 
2525  if(!NtUserSetCursorIconData(hIcon, NULL, NULL, &cursorData))
2526  {
2527  ERR("NtUserSetCursorIconData failed.\n");
2528  NtUserDestroyCursor(hIcon, TRUE);
2529  goto end_error;
2530  }
2531 
2532  if(isAnimated)
2533  HeapFree(GetProcessHeap(), 0, cursorData.aspcur);
2534 
2535  return hIcon;
2536 
2537  /* Clean up */
2538 end_error:
2539  if(isAnimated)
2540  HeapFree(GetProcessHeap(), 0, cursorData.aspcur);
2541  DeleteObject(cursorData.hbmMask);
2542  if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
2543  if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
2544 
2545  return NULL;
2546 }
2547 
2549  _In_ PICONINFO piconinfo
2550 )
2551 {
2552  /* As simple as creating a handle, and let win32k deal with the bitmaps */
2553  HICON hiconRet;
2554  CURSORDATA cursorData;
2555 
2556  TRACE("%p.\n", piconinfo);
2557 
2558  ZeroMemory(&cursorData, sizeof(cursorData));
2559 
2560  if(!CURSORICON_GetCursorDataFromIconInfo(&cursorData, piconinfo))
2561  return NULL;
2562 
2563  hiconRet = NtUserxCreateEmptyCurObject(FALSE);
2564  if(!hiconRet)
2565  goto end_error;
2566 
2567  if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, &cursorData))
2568  {
2569  NtUserDestroyCursor(hiconRet, FALSE);
2570  goto end_error;
2571  }
2572 
2573  TRACE("Returning 0x%08x.\n", hiconRet);
2574 
2575  return hiconRet;
2576 
2577 end_error:
2578  /* Clean up */
2579  DeleteObject(cursorData.hbmMask);
2580  if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
2581  if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
2582 
2583  return NULL;
2584 }
2585 
2588  _In_ int xHotSpot,
2589  _In_ int yHotSpot,
2590  _In_ int nWidth,
2591  _In_ int nHeight,
2592  _In_ const VOID *pvANDPlane,
2593  _In_ const VOID *pvXORPlane
2594 )
2595 {
2596  ICONINFO info;
2597  HCURSOR hCursor;
2598 
2599  TRACE_(cursor)("%dx%d spot=%d,%d xor=%p and=%p\n",
2600  nWidth, nHeight, xHotSpot, yHotSpot, pvXORPlane, pvANDPlane);
2601 
2602  info.fIcon = FALSE;
2603  info.xHotspot = xHotSpot;
2604  info.yHotspot = yHotSpot;
2605  info.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, pvANDPlane );
2606  info.hbmColor = CreateBitmap( nWidth, nHeight, 1, 1, pvXORPlane );
2607  hCursor = CreateIconIndirect( &info );
2608  DeleteObject( info.hbmMask );
2609  DeleteObject( info.hbmColor );
2610  return hCursor;
2611 }
2612 
2614  _In_ HCURSOR hcur,
2615  _In_ DWORD id
2616 )
2617 {
2618  if (hcur == NULL)
2619  {
2620  hcur = LoadImageW( 0, MAKEINTRESOURCE(id), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE );
2621  if (hcur == NULL)
2622  {
2623  return FALSE;
2624  }
2625  }
2626  return NtUserSetSystemCursor(hcur,id);
2627 }
2628 
2630  _In_ int X,
2631  _In_ int Y
2632 )
2633 {
2634  return NtUserxSetCursorPos(X,Y);
2635 }
2636 
2638  _Out_ LPPOINT lpPoint
2639 )
2640 {
2641  return NtUserxGetCursorPos(lpPoint);
2642 }
2643 
2645  _In_ BOOL bShow
2646 )
2647 {
2648  return NtUserxShowCursor(bShow);
2649 }
2650 
2652 {
2654 }
2655 
2657  _In_ HCURSOR hCursor
2658 )
2659 {
2660  return NtUserDestroyCursor(hCursor, FALSE);
2661 }
2662 
2663 HCURSOR
2664 WINAPI
2665 GetCursorFrameInfo(HCURSOR hCursor, DWORD reserved, DWORD istep, PINT rate_jiffies, DWORD *num_steps)
2666 {
2667  return NtUserGetCursorFrameInfo(hCursor, istep, rate_jiffies, num_steps);
2668 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define IDC_SIZEWE
Definition: winuser.h:689
NTSTATUS WINAPI User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: cursoricon.c:1940
HBITMAP hbmAlpha
Definition: ntuser.h:1127
int UINT uType
Definition: wglext.h:470
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
union CURSORICONDIRENTRY::@3918 ResInfo
HANDLE HGLOBAL
Definition: windef.h:266
#define HDC
Definition: msvc.h:22
#define RT_CURSOR
Definition: pedump.c:363
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:606
#define abs(i)
Definition: fconv.c:206
static BOOL CURSORICON_GetCursorDataFromBMI(_Inout_ CURSORDATA *pdata, _In_ const BITMAPINFO *pbmi)
Definition: cursoricon.c:585
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)
#define BITSPIXEL
Definition: wingdi.h:718
BYTE rgbtBlue
Definition: wingdi.h:1415
BITMAPINFOHEADER dsBmih
Definition: wingdi.h:1647
#define max(a, b)
Definition: svc.c:63
DWORD bpp
Definition: cursoricon.c:78
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:2586
#define RT_GROUP_ICON
Definition: pedump.c:375
unsigned short WORD
Definition: ntddk_ex.h:93
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:79
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
CURSORRESDIR cursor
Definition: ntusrtyp.h:89
#define CloseHandle
Definition: compat.h:398
#define LR_SHARED
Definition: winuser.h:1080
WINE_DECLARE_DEBUG_CHANNEL(icon)
#define IMAGE_ICON
Definition: winuser.h:212
ULONG CURSORF_flags
Definition: ntuser.h:1122
#define ANI_FLAG_ICON
Definition: cursoricon.c:829
BOOL WINAPI DestroyIcon(_In_ HICON hIcon)
Definition: cursoricon.c:2024
DWORD_PTR NTAPI NtUserGetThreadState(DWORD Routine)
Definition: misc.c:207
#define HBITMAP
Definition: msvc.h:28
EXTINLINE BOOL NtUserxSetCursorPos(INT x, INT y)
Definition: ntwrapper.h:676
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1453
#define MapViewOfFile
Definition: compat.h:402
DWORD header_size
Definition: cursoricon.c:73
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:275
#define error(str)
Definition: mkdosfs.c:1605
static BOOL is_dib_monochrome(const BITMAPINFO *info)
Definition: cursoricon.c:118
DWORD biClrImportant
Definition: amvideo.idl:40
struct _COPYIMAGE_CALLBACK_ARGUMENTS * PCOPYIMAGE_CALLBACK_ARGUMENTS
HICON WINAPI CreateIcon(_In_opt_ HINSTANCE hInstance, _In_ int nWidth, _In_ int nHeight, _In_ BYTE cPlanes, _In_ BYTE cBitsPixel, _In_ const BYTE *lpbANDbits, _In_ const BYTE *lpbXORbits)
Definition: cursoricon.c:2366
WORD idCount
Definition: ntusrtyp.h:101
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: bidi.c:75
HDC WINAPI GetDC(_In_opt_ HWND)
#define ANI_rate_ID
Definition: cursoricon.c:827
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
WINE_DEFAULT_DEBUG_CHANNEL(cursor)
struct tagCURSORDATA * aspcur
Definition: ntuser.h:1135
#define pt(x, y)
Definition: drawing.c:79
__wchar_t WCHAR
Definition: xmlstorage.h:180
static HBITMAP BITMAP_CopyImage(_In_ HBITMAP hnd, _In_ int desiredx, _In_ int desiredy, _In_ UINT flags)
Definition: cursoricon.c:1618
#define CURSORF_FROMRESOURCE
Definition: ntuser.h:1142
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO pbmi
Definition: ntgdi.h:2780
static void stretch_blt_icon(HDC hdc_dst, int dst_width, int dst_height, HBITMAP src)
Definition: cursoricon.c:209
return STATUS_SUCCESS
Definition: btrfs.c:2664
#define LR_LOADFROMFILE
Definition: winuser.h:1072
DWORD yHotspot
Definition: winuser.h:3068
LONG biXPelsPerMeter
Definition: amvideo.idl:37
#define CP_ACP
Definition: compat.h:99
struct tagBITMAPINFOHEADER BITMAPINFOHEADER
#define ANI_FLAG_SEQUENCE
Definition: cursoricon.c:830
static DWORD DWORD istep
Definition: cursoricon.c:1509
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:286
HCURSOR hcur
Definition: msvc.h:68
unsigned char * LPBYTE
Definition: typedefs.h:52
#define IMAGE_CURSOR
Definition: winuser.h:213
#define IDC_NO
Definition: winuser.h:692
uint8_t entry
Definition: isohybrid.c:63
#define WARN(fmt,...)
Definition: debug.h:111
DWORD dwFileSize
Definition: more.c:36
#define RT_GROUP_CURSOR
Definition: pedump.c:374
#define GetRValue(rgb)
Definition: wingdi.h:2912
#define SM_CYCURSOR
Definition: winuser.h:955
#define DI_COMPAT
Definition: wingdi.h:68
SHORT xHotspot
Definition: ntuser.h:1123
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
HANDLE WINAPI LoadImageA(_In_opt_ HINSTANCE hinst, _In_ LPCSTR lpszName, _In_ UINT uType, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuLoad)
Definition: cursoricon.c:2149
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ds
Definition: i386-dis.c:434
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1056
#define ZeroMemory
Definition: winbase.h:1621
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
#define Y(i)
Definition: t_vb_render.c:49
HBITMAP hbmMask
Definition: ntuser.h:1125
#define OCR_SIZEWE
Definition: winuser.h:1131
static int DIB_GetBitmapInfo(const BITMAPINFOHEADER *header, LONG *width, LONG *height, WORD *bpp, DWORD *compr)
Definition: cursoricon.c:181
HDC dc
Definition: cylfrac.c:34
HCURSOR WINAPI LoadCursorFromFileW(_In_ LPCWSTR lpFileName)
Definition: cursoricon.c:2105
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
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:2414
static void dump_ani_header(const ani_header *header)
Definition: cursoricon.c:851
GLuint GLuint end
Definition: gl.h:1545
static const WCHAR DISPLAYW[]
Definition: cursoricon.c:89
DWORD data_size
Definition: cursoricon.c:846
_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:426
HICON HCURSOR
Definition: windef.h:312
Definition: compobj.c:613
#define WCHAR
Definition: msvc.h:43
#define leave
Definition: cdprocs.h:1888
EXTINLINE BOOL NtUserxGetCursorPos(POINT *lpPoint)
Definition: ntwrapper.h:806
LONG biYPelsPerMeter
Definition: amvideo.idl:38
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:1411
#define DWORD
Definition: msvc.h:34
#define COLOR_WINDOW
Definition: winuser.h:898
#define IDC_SIZENESW
Definition: winuser.h:688
HINSTANCE User32Instance
Definition: dllmain.c:11
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
int32_t INT
Definition: typedefs.h:56
PSERVERINFO gpsi
Definition: main.c:27
#define ANI_LIST_ID
Definition: cursoricon.c:822
#define BI_BITFIELDS
Definition: mmreg.h:505
DWORD WINAPI GetSysColor(_In_ int)
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 OCR_ICON
Definition: winuser.h:1128
DWORD DWORD
Definition: winlogon.h:75
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
UCHAR rgbBlue
Definition: inbv.c:96
#define IDC_IBEAM
Definition: winuser.h:683
#define FILE_SHARE_READ
Definition: compat.h:125
#define _In_opt_
Definition: no_sal2.h:213
#define COLOR_3DSHADOW
Definition: winuser.h:911
#define IDC_SIZENS
Definition: winuser.h:690
EXTINLINE HICON NtUserxCreateEmptyCurObject(DWORD_PTR Param)
Definition: ntwrapper.h:616
#define ANI_anih_ID
Definition: cursoricon.c:824
WORD idReserved
Definition: ntusrtyp.h:99
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2032
#define CURSORF_ACONFRAME
Definition: ntuser.h:1147
HANDLE WINAPI CopyImage(_In_ HANDLE hImage, _In_ UINT uType, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuFlags)
Definition: cursoricon.c:1958
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSYSAPI NTSTATUS NTAPI ZwCallbackReturn(_In_ PVOID Result, _In_ ULONG ResultLength, _In_ NTSTATUS Status)
UCHAR rgbGreen
Definition: inbv.c:97
BOOL WINAPI GetIconInfo(_In_ HICON hIcon, _Out_ PICONINFO piconinfo)
Definition: cursoricon.c:2016
BOOL WINAPI SetSystemCursor(_In_ HCURSOR hcur, _In_ DWORD id)
Definition: cursoricon.c:2613
#define CBM_INIT
Definition: wingdi.h:363
#define GetGValue(rgb)
Definition: wingdi.h:2913
UCHAR rgbRed
Definition: inbv.c:98
#define IDC_UPARROW
Definition: winuser.h:686
GLuint const GLubyte GLvoid * src
Definition: s_context.h:57
#define CURSORF_ACON
Definition: ntuser.h:1145
#define LR_COPYRETURNORG
Definition: winuser.h:1070
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLenum GLclampf GLint i
Definition: glfuncs.h:14
HINSTANCE hInstance
Definition: charmap.c:19
#define COLOR_3DFACE
Definition: winuser.h:909
#define IDC_SIZENWSE
Definition: winuser.h:687
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define OCR_HELP
Definition: winuser.h:1137
int int int * err
Definition: fci.h:172
HANDLE hbmpOld
Definition: magnifier.c:53
long LONG
Definition: pedump.c:60
GLuint color
Definition: glext.h:6243
#define OCR_WAIT
Definition: winuser.h:1124
#define CURSORF_LRSHARED
Definition: ntuser.h:1144
EXTINLINE INT NtUserxShowCursor(BOOL bShow)
Definition: ntwrapper.h:606
short SHORT
Definition: pedump.c:59
NTSTATUS WINAPI User32SetupDefaultCursors(PVOID Arguments, ULONG ArgumentLength)
Definition: cursoricon.c:50
#define debugstr_w
Definition: kernel32.h:32
HBITMAP hbmMask
Definition: winuser.h:3069
HCURSOR WINAPI LoadCursorFromFileA(_In_ LPCSTR lpFileName)
Definition: cursoricon.c:2091
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
static const IUnknown void **static void **static RGBQUAD *static HINSTANCE hinst
Definition: imagelist.c:73
#define FIXME(fmt,...)
Definition: debug.h:110
BOOL WINAPI FreeResource(HGLOBAL handle)
Definition: res.c:559
DWORD biCompression
Definition: amvideo.idl:35
PIN_DIRECTION dir
Definition: strmbase.h:226
static PVOID ptr
Definition: dispmode.c:30
#define SM_CXICON
Definition: winuser.h:952
BYTE bReserved
Definition: ntusrtyp.h:64
#define OCR_NO
Definition: winuser.h:1134
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
HDC hdc
Definition: msvc.h:53
const unsigned char * data
Definition: cursoricon.c:847
#define OCR_SIZENESW
Definition: winuser.h:1130
smooth NULL
Definition: ftsmooth.c:557
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpCursorName)
Definition: cursoricon.c:2076
#define IDC_ICON
Definition: winuser.h:696
#define IDC_WAIT
Definition: winuser.h:684
#define _Out_
Definition: no_sal2.h:323
LONG cx
Definition: windef.h:347
HBITMAP hbmColor
Definition: winuser.h:3070
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpCursorName)
Definition: cursoricon.c:2061
#define DI_DEFAULTSIZE
Definition: wingdi.h:69
#define FILE_MAP_READ
Definition: compat.h:427
const char * LPCSTR
Definition: xmlstorage.h:183
DWORD height
Definition: cursoricon.c:77
#define OCR_UP
Definition: winuser.h:1126
static PROTOCOLDATA * pdata
Definition: protocol.c:159
#define OPEN_EXISTING
Definition: compat.h:426
DWORD num_planes
Definition: cursoricon.c:79
WORD wHeight
Definition: ntusrtyp.h:70
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpIconName)
Definition: cursoricon.c:2031
#define TRACE_(x)
Definition: compat.h:66
int WINAPI ShowCursor(_In_ BOOL bShow)
Definition: cursoricon.c:2644
BOOL fIcon
Definition: winuser.h:3066
#define IDC_HAND
Definition: winuser.h:693
HDC hDC
Definition: wglext.h:521
HCURSOR WINAPI GetCursorFrameInfo(HCURSOR hCursor, DWORD reserved, DWORD istep, PINT rate_jiffies, DWORD *num_steps)
Definition: cursoricon.c:2665
int * PINT
Definition: windef.h:200
#define TRACE(s)
Definition: solgame.cpp:4
#define FreeLibrary(x)
Definition: compat.h:405
unsigned int BOOL
Definition: ntddk_ex.h:94
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
GLint GLint GLsizei width
Definition: gl.h:1546
RGBQUAD bmiColors[1]
Definition: wingdi.h:1454
#define SM_CXCURSOR
Definition: winuser.h:954
#define LR_DEFAULTSIZE
Definition: winuser.h:1074
#define debugstr_a
Definition: kernel32.h:31
#define OCR_SIZE
Definition: winuser.h:1127
#define OCR_CROSS
Definition: winuser.h:1125
static int compr(const void *a, const void *b)
Definition: bidi.c:675
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:401
#define IDC_APPSTARTING
Definition: winuser.h:694
DWORD xHotspot
Definition: winuser.h:3067
VOID LoadSystemCursors(VOID)
Definition: cursoricon.c:23
GLfloat param
Definition: glext.h:5796
#define MAX_PATH
Definition: compat.h:26
DWORD num_steps
Definition: cursoricon.c:75
#define CopyMemory
Definition: winbase.h:1619
#define RT_ICON
Definition: pedump.c:365
int WINAPI GetSystemMetrics(_In_ int)
int WINAPI LookupIconIdFromDirectoryEx(_In_ PBYTE presbits, _In_ BOOL fIcon, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT Flags)
Definition: cursoricon.c:2210
DWORD biSizeImage
Definition: amvideo.idl:36
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:461
#define SetLastError(x)
Definition: compat.h:409
#define _Inout_
Definition: no_sal2.h:244
#define OCR_SIZEALL
Definition: winuser.h:1133
#define OCR_SIZENWSE
Definition: winuser.h:1129
#define LR_COPYDELETEORG
Definition: winuser.h:1071
#define GetObject
Definition: wingdi.h:4445
HBITMAP hbmColor
Definition: ntuser.h:1126
HBITMAP WINAPI LoadBitmapA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpBitmapName)
Definition: cursoricon.c:2119
GLbitfield flags
Definition: glext.h:7161
HICON WINAPI CreateIconIndirect(_In_ PICONINFO piconinfo)
Definition: cursoricon.c:2548
static BOOL CURSORICON_GetCursorDataFromIconInfo(_Out_ CURSORDATA *pCursorData, _In_ ICONINFO *pIconInfo)
Definition: cursoricon.c:735
#define LOAD_LIBRARY_AS_IMAGE_RESOURCE
Definition: winbase.h:338
HANDLE HINSTANCE
Definition: typedefs.h:75
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)
BOOL APIENTRY NtUserGetIconSize(HANDLE hCurIcon, UINT istepIfAniCur, PLONG plcx, PLONG plcy)
Definition: cursoricon.c:586
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
int ret
#define SM_CYICON
Definition: winuser.h:953
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:469
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:2174
static HANDLE CURSORICON_LoadFromFileW(_In_ LPCWSTR lpszName, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuLoad, _In_ BOOL bIcon)
Definition: cursoricon.c:1335
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define LR_LOADTRANSPARENT
Definition: winuser.h:1073
#define ANI_RIFF_ID
Definition: cursoricon.c:821
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define DI_NORMAL
Definition: wingdi.h:72
#define OCR_IBEAM
Definition: winuser.h:1123
GLenum GLsizei len
Definition: glext.h:6722
#define GENERIC_READ
Definition: compat.h:124
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpIconName)
Definition: cursoricon.c:2046
static int get_dib_image_size(int width, int height, int depth)
Definition: cursoricon.c:113
HICON WINAPI CreateIconFromResource(_In_ PBYTE presbits, _In_ DWORD dwResSize, _In_ BOOL fIcon, _In_ DWORD dwVer)
Definition: cursoricon.c:2404
HICON NTAPI NtUserFindExistingCursorIcon(_In_ PUNICODE_STRING pustrModule, _In_ PUNICODE_STRING pustrRsrc, _In_ FINDEXISTINGCURICONPARAM *param)
Definition: cursoricon.c:861
#define LR_LOADMAP3DCOLORS
Definition: winuser.h:1077
DWORD flags
Definition: cursoricon.c:81
_In_ HANDLE hFile
Definition: mswsock.h:90
#define WINAPI
Definition: msvc.h:20
#define COLOR_3DLIGHT
Definition: winuser.h:920
unsigned char BYTE
Definition: ntddk_ex.h:96
#define LR_MONOCHROME
Definition: winuser.h:1068
BOOL WINAPI DrawIcon(_In_ HDC hDC, _In_ int X, _In_ int Y, _In_ HICON hIcon)
Definition: cursoricon.c:1989
#define ERR(fmt,...)
Definition: debug.h:109
#define _In_
Definition: no_sal2.h:204
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:335
SHORT yHotspot
Definition: ntuser.h:1124
HCURSOR NTAPI NtUserGetCursorFrameInfo(HCURSOR hCursor, DWORD istep, INT *rate_jiffies, DWORD *num_steps)
Definition: cursoricon.c:2130
#define IDC_CROSS
Definition: winuser.h:685
#define OCR_HAND
Definition: winuser.h:1135
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
static void riff_find_chunk(DWORD chunk_id, DWORD chunk_type, const riff_chunk_t *parent_chunk, riff_chunk_t *chunk)
Definition: cursoricon.c:865
BOOL APIENTRY NtUserDestroyCursor(_In_ HANDLE hCurIcon, _In_ BOOL bForce)
Definition: cursoricon.c:793
const XML_Char XML_Encoding * info
Definition: expat.h:530
DWORD *typedef HANDLE
Definition: winlogon.h:52
#define LR_COPYFROMRESOURCE
Definition: winuser.h:1079
#define OCR_NORMAL
Definition: winuser.h:1122
HINSTANCE hInst
Definition: dxdiag.c:13
BOOL WINAPI SetCursorPos(_In_ int X, _In_ int Y)
Definition: cursoricon.c:2629
LONG NTSTATUS
Definition: DriverTester.h:11
#define ANI_seq__ID
Definition: cursoricon.c:825
static HICON CURSORICON_CopyImage(_In_ HICON hicon, _In_ BOOL bIcon, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuFlags)
Definition: cursoricon.c:1808
BYTE bColorCount
Definition: ntusrtyp.h:63
DWORD display_rate
Definition: cursoricon.c:80
const char cursor[]
Definition: icontest.c:13
BOOL APIENTRY NtUserSetSystemCursor(HCURSOR hcur, DWORD id)
Definition: cursoricon.c:2200
_In_ ULONG _In_ ULONG rgb
Definition: winddi.h:3520
BOOL WINAPI DeleteDC(_In_ HDC)
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
unsigned short USHORT
Definition: pedump.c:61
HICON hIcon
Definition: msconfig.c:44
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:555
USHORT rt
Definition: ntuser.h:1120
HCURSOR WINAPI GetCursor(void)
Definition: cursoricon.c:2651
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:2083
DWORD num_frames
Definition: cursoricon.c:74
GLsizeiptr size
Definition: glext.h:5919
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:197
struct tagBITMAPFILEHEADER BITMAPFILEHEADER
r reserved
Definition: btrfs.c:2594
Definition: bl.h:1253
#define IDC_SIZE
Definition: winuser.h:697
#define MAKEINTRESOURCE
Definition: cursoricon.c:19
#define LR_CREATEDIBSECTION
Definition: winuser.h:1078
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define IDC_SIZEALL
Definition: winuser.h:691
static HBITMAP create_bitmap(INT cx, INT cy, COLORREF color, const char *comment)
Definition: imagelist.c:880
BYTE rgbtRed
Definition: wingdi.h:1417
BITMAP dsBm
Definition: wingdi.h:1646
unsigned int UINT
Definition: ndis.h:50
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
#define PAGE_READONLY
Definition: compat.h:127
static BOOL bmi_has_alpha(const BITMAPINFO *info, const void *bits)
Definition: cursoricon.c:256
#define IMAGE_BITMAP
Definition: winuser.h:211
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
HCURSOR CursorIconToCursor(HICON hIcon, BOOL SemiTransparent)
Definition: cursoricon.c:81
BYTE bHeight
Definition: ntusrtyp.h:62
HDC WINAPI CreateICW(_In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_opt_ const DEVMODEW *)
#define MultiByteToWideChar
Definition: compat.h:100
HDC WINAPI CreateDCW(_In_opt_ LPCWSTR pszDriver, _In_opt_ LPCWSTR pszDevice, _In_opt_ LPCWSTR psz, _In_opt_ const DEVMODEW *pdmInit)
#define CreateFileW
Definition: compat.h:400
HANDLE HMODULE
Definition: typedefs.h:75
DWORD UINT uFlags
Definition: wglext.h:734
int WINAPI LookupIconIdFromDirectory(_In_ PBYTE presbits, _In_ BOOL fIcon)
Definition: cursoricon.c:2200
#define ANI_ACON_ID
Definition: cursoricon.c:823
HBITMAP WINAPI LoadBitmapW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpBitmapName)
Definition: cursoricon.c:2134
#define IDC_ARROW
Definition: winuser.h:682
__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
ULONG cy
Definition: ntuser.h:1132
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)
Definition: name.c:23
static HBITMAP BITMAP_LoadImageW(_In_opt_ HINSTANCE hinst, _In_ LPCWSTR lpszName, _In_ int cxDesired, _In_ int cyDesired, _In_ UINT fuLoad)
Definition: cursoricon.c:1069
#define OCR_SIZENS
Definition: winuser.h:1132
GLuint res
Definition: glext.h:9613
static int bitmap_info_size(const BITMAPINFO *info, WORD coloruse)
Definition: cursoricon.c:157
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
uint32_t * LPDWORD
Definition: typedefs.h:57
CURSORICONDIRENTRY idEntries[1]
Definition: ntusrtyp.h:102
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:114
BOOL WINAPI DestroyCursor(_In_ HCURSOR hCursor)
Definition: cursoricon.c:2656
#define GetBValue(rgb)
Definition: wingdi.h:2914
#define OCR_APPSTARTING
Definition: winuser.h:1136
DWORD bpp
Definition: surface.c:174
DWORD width
Definition: cursoricon.c:76
BYTE rgbtGreen
Definition: wingdi.h:1416
static BOOL CURSORICON_GetCursorDataFromANI(_Inout_ CURSORDATA *pCurData, _In_ const BYTE *pData, _In_ DWORD dwDataSize, _In_ DWORD fuLoad)
Definition: cursoricon.c:892
BYTE color_bits
Definition: swimpl.c:31
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
UCHAR rgbReserved
Definition: inbv.c:99
ICONRESDIR icon
Definition: ntusrtyp.h:88
ULONG cx
Definition: ntuser.h:1131
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
#define RT_BITMAP
Definition: pedump.c:364
#define DIB_RGB_COLORS
Definition: wingdi.h:365
BOOL get_icon_size(HICON hIcon, SIZE *size)
Definition: cursoricon.c:76
#define ANI_fram_ID
Definition: cursoricon.c:826
WORD wWidth
Definition: ntusrtyp.h:69
#define UnmapViewOfFile
Definition: compat.h:403
DWORD COLORREF
Definition: windef.h:313
WCHAR * LPWSTR
Definition: xmlstorage.h:184
HICON WINAPI CopyIcon(_In_ HICON hIcon)
Definition: cursoricon.c:1982
LONG cy
Definition: windef.h:348
BYTE * PBYTE
Definition: pedump.c:66
#define BI_RGB
Definition: precomp.h:35
BOOL WINAPI GetCursorPos(_Out_ LPPOINT lpPoint)
Definition: cursoricon.c:2637
#define HeapFree(x, y, z)
Definition: compat.h:394
#define SRCCOPY
Definition: wingdi.h:331
struct CFHEADER header
Definition: fdi.c:109
HDC hdcMem
Definition: welcome.c:104
DWORD dwBytesInRes
Definition: ntusrtyp.h:93
_In_ LPCSTR lpFileName
Definition: winbase.h:2959
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1203
static void * map_fileW(LPCWSTR name, LPDWORD filesize)
Definition: cursoricon.c:91
BYTE bWidth
Definition: ntusrtyp.h:61
#define IDC_HELP
Definition: winuser.h:695
BOOL WINAPI DrawIconEx(_In_ HDC hdc, _In_ int xLeft, _In_ int yTop, _In_ HICON hIcon, _In_ int cxWidth, _In_ int cyWidth, _In_ UINT istepIfAniCur, _In_opt_ HBRUSH hbrFlickerFreeDraw, _In_ UINT diFlags)
Definition: cursoricon.c:1999
#define FILE_FLAG_RANDOM_ACCESS
Definition: disk.h:44
HMODULE hModule
Definition: animate.c:43
#define PLANES
Definition: wingdi.h:719
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
static const BYTE masks[8]
Definition: dib.c:2769