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