ReactOS  0.4.13-dev-563-g0561610
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 
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 );
228  info->bmiHeader.biCompression = BI_RGB;
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  ULONG 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;
318  info->bmiHeader.biCompression = BI_RGB;
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 
326  if(!bits)
327  {
329  goto done;
330  }
331  if(!GetDIBits( hdc, color, 0, bm.bmHeight, bits, info, DIB_RGB_COLORS ))
332  {
334  goto done;
335  }
336  if (!bmi_has_alpha( info, bits ))
337  {
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). */
353 
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);
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;
413  if(!hbmpOld)
414  {
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  {
424  hbmpOld = NULL;
426  alpha = NULL;
427  }
428  else
429  {
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 {
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 +
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);
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 */
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)
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");
1306  DeleteObject(hbmpRet);
1307  hbmpRet = NULL;
1308  goto end;
1309  }
1310 
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:
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);
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)
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);
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 
1545  if(!bits)
1546  {
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 
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 
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 */
1880  hModule,
1881  ustrRsrc.Buffer,
1882  cxDesired,
1883  cyDesired,
1884  fuFlags & (LR_DEFAULTSIZE | LR_SHARED),
1885  bIcon);
1886 
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  {
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");
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 }
#define IDC_SIZEWE
Definition: winuser.h:689
NTSTATUS WINAPI User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: cursoricon.c:1938
HBITMAP hbmAlpha
Definition: ntuser.h:1133
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define RT_CURSOR
Definition: pedump.c:363
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:607
#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:719
BYTE rgbtBlue
Definition: wingdi.h:1416
GLint GLint GLsizei width
Definition: gl.h:1546
#define max(a, b)
Definition: svc.c:63
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
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:1090
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:231
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:1454
#define MapViewOfFile
Definition: compat.h:402
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
#define Y(I)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
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
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
#define LR_LOADFROMFILE
Definition: winuser.h:1082
DWORD yHotspot
Definition: winuser.h:3078
#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
#define IMAGE_CURSOR
Definition: winuser.h:213
#define IDC_NO
Definition: winuser.h:692
#define WARN(fmt,...)
Definition: debug.h:111
LONG NTSTATUS
Definition: precomp.h:26
DWORD dwFileSize
Definition: more.c:36
#define RT_GROUP_CURSOR
Definition: pedump.c:374
static HDC
Definition: imagelist.c:92
#define GetRValue(rgb)
Definition: wingdi.h:2913
#define SM_CYCURSOR
Definition: winuser.h:965
#define DI_COMPAT
Definition: wingdi.h:68
SHORT xHotspot
Definition: ntuser.h:1129
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:1059
#define ZeroMemory
Definition: winbase.h:1635
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HBITMAP hbmMask
Definition: ntuser.h:1131
#define OCR_SIZEWE
Definition: winuser.h:1141
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
HICON HCURSOR
Definition: windef.h:284
UINT uFlags
Definition: api.c:60
EXTINLINE BOOL NtUserxGetCursorPos(POINT *lpPoint)
Definition: ntwrapper.h:811
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 COLOR_WINDOW
Definition: winuser.h:908
#define IDC_SIZENESW
Definition: winuser.h:688
HINSTANCE User32Instance
Definition: dllmain.c:27
#define DWORD
Definition: nt_native.h:44
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:1138
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
UCHAR rgbBlue
Definition: inbv.c:122
#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:921
#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
struct _test_info info[]
Definition: SetCursorPos.c:19
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:123
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:364
#define GetGValue(rgb)
Definition: wingdi.h:2914
UCHAR rgbRed
Definition: inbv.c:124
#define IDC_UPARROW
Definition: winuser.h:686
#define CURSORF_ACON
Definition: ntuser.h:1151
#define LR_COPYRETURNORG
Definition: winuser.h:1080
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HINSTANCE hInstance
Definition: charmap.c:20
#define COLOR_3DFACE
Definition: winuser.h:919
unsigned char * LPBYTE
Definition: typedefs.h:52
#define IDC_SIZENWSE
Definition: winuser.h:687
#define UNICODE_NULL
#define OCR_HELP
Definition: winuser.h:1147
unsigned int BOOL
Definition: ntddk_ex.h:94
HANDLE hbmpOld
Definition: magnifier.c:54
long LONG
Definition: pedump.c:60
GLuint color
Definition: glext.h:6243
#define OCR_WAIT
Definition: winuser.h:1134
#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:3079
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
static PVOID ptr
Definition: dispmode.c:27
r reserved
Definition: btrfs.c:2704
#define SM_CXICON
Definition: winuser.h:962
BYTE bReserved
Definition: ntusrtyp.h:64
#define OCR_NO
Definition: winuser.h:1144
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
const unsigned char * data
Definition: cursoricon.c:845
#define OCR_SIZENESW
Definition: winuser.h:1140
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
_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
#define _Out_
Definition: no_sal2.h:323
HBITMAP hbmColor
Definition: winuser.h:3080
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
unsigned int dir
Definition: maze.c:112
const char * LPCSTR
Definition: xmlstorage.h:183
DWORD height
Definition: cursoricon.c:77
#define OCR_UP
Definition: winuser.h:1136
static PROTOCOLDATA * pdata
Definition: protocol.c:157
#define OPEN_EXISTING
Definition: compat.h:426
union CURSORICONDIRENTRY::@4118 ResInfo
WORD wHeight
Definition: ntusrtyp.h:70
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpIconName)
Definition: cursoricon.c:2029
#define TRACE_(x)
Definition: compat.h:66
int WINAPI ShowCursor(_In_ BOOL bShow)
Definition: cursoricon.c:2642
BOOL fIcon
Definition: winuser.h:3076
#define IDC_HAND
Definition: winuser.h:693
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
GLsizeiptr size
Definition: glext.h:5919
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
RGBQUAD bmiColors[1]
Definition: wingdi.h:1455
#define SM_CXCURSOR
Definition: winuser.h:964
#define LR_DEFAULTSIZE
Definition: winuser.h:1084
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define debugstr_a
Definition: kernel32.h:31
#define OCR_SIZE
Definition: winuser.h:1137
#define OCR_CROSS
Definition: winuser.h:1135
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:401
#define IDC_APPSTARTING
Definition: winuser.h:694
DWORD COLORREF
Definition: windef.h:285
DWORD xHotspot
Definition: winuser.h:3077
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 WINAPI
Definition: msvc.h:8
#define CopyMemory
Definition: winbase.h:1633
#define RT_ICON
Definition: pedump.c:365
unsigned short WORD
Definition: ntddk_ex.h:93
int WINAPI GetSystemMetrics(_In_ int)
unsigned long DWORD
Definition: ntddk_ex.h:95
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:1143
#define OCR_SIZENWSE
Definition: winuser.h:1139
#define LR_COPYDELETEORG
Definition: winuser.h:1081
#define GetObject
Definition: wingdi.h:4446
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
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:963
static const WCHAR L[]
Definition: oid.c:1250
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
HDC hdc
Definition: main.c:9
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:1083
#define ANI_RIFF_ID
Definition: cursoricon.c:819
uint32_t entry
Definition: isohybrid.c:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
#define DI_NORMAL
Definition: wingdi.h:72
unsigned char BYTE
Definition: mem.h:68
#define OCR_IBEAM
Definition: winuser.h:1133
#define GENERIC_READ
Definition: compat.h:124
HICON WINAPI LoadIconW(_In_opt_ HINSTANCE hInstance, _In_ LPCWSTR lpIconName)
Definition: cursoricon.c:2044
GLenum src
Definition: glext.h:6340
static int get_dib_image_size(int width, int height, int depth)
Definition: cursoricon.c:111
#define err(...)
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:1087
DWORD flags
Definition: cursoricon.c:81
_In_ HANDLE hFile
Definition: mswsock.h:90
#define COLOR_3DLIGHT
Definition: winuser.h:930
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
#define LR_MONOCHROME
Definition: winuser.h:1078
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:1145
static HDC hDC
Definition: 3dtext.c:33
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
#define LR_COPYFROMRESOURCE
Definition: winuser.h:1089
#define OCR_NORMAL
Definition: winuser.h:1132
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
Definition: bl.h:1331
#define IDC_SIZE
Definition: winuser.h:697
#define MAKEINTRESOURCE
Definition: cursoricon.c:17
#define LR_CREATEDIBSECTION
Definition: winuser.h:1088
#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:940
unsigned int UINT
Definition: ndis.h:50
#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
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:1142
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:2915
#define OCR_APPSTARTING
Definition: winuser.h:1146
DWORD bpp
Definition: surface.c:181
DWORD width
Definition: cursoricon.c:76
static HBITMAP
Definition: button.c:44
static BOOL CURSORICON_GetCursorDataFromANI(_Inout_ CURSORDATA *pCurData, _In_ const BYTE *pData, _In_ DWORD dwDataSize, _In_ DWORD fuLoad)
Definition: cursoricon.c:890
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
UCHAR rgbReserved
Definition: inbv.c:125
ICONRESDIR icon
Definition: ntusrtyp.h:88
ULONG cx
Definition: ntuser.h:1137
WCHAR * LPWSTR
Definition: xmlstorage.h:184
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:366
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
return STATUS_SUCCESS
Definition: btrfs.c:2777
#define UnmapViewOfFile
Definition: compat.h:403
HICON WINAPI CopyIcon(_In_ HICON hIcon)
Definition: cursoricon.c:1980
BYTE * PBYTE
Definition: pedump.c:66
#define BI_RGB
Definition: precomp.h:34
BOOL WINAPI GetCursorPos(_Out_ LPPOINT lpPoint)
Definition: cursoricon.c:2635
#define HeapFree(x, y, z)
Definition: compat.h:394
#define SRCCOPY
Definition: wingdi.h:332
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:1188
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:720
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