/*********************************************************************** * CreateBrushIndirect (GDI32.@) * * Create a logical brush with a given style, color or pattern. * * PARAMS * brush [I] Pointer to a LOGBRUSH structure describing the desired brush. * * RETURNS * A handle to the created brush, or a NULL handle if the brush cannot be * created. * * NOTES * - The brush returned should be freed by the caller using DeleteObject() * when it is no longer required. * - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger * than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap * is used. */ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush ) { BRUSHOBJ * ptr; HBRUSH hbrush; if (!(ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(*ptr) ))) return 0; ptr->logbrush.lbStyle = brush->lbStyle; ptr->logbrush.lbColor = brush->lbColor; ptr->logbrush.lbHatch = brush->lbHatch; switch (ptr->logbrush.lbStyle) { case BS_PATTERN8X8: ptr->logbrush.lbStyle = BS_PATTERN; /* fall through */ case BS_PATTERN: ptr->logbrush.lbHatch = (ULONG_PTR)BITMAP_CopyBitmap( (HBITMAP) ptr->logbrush.lbHatch ); if (!ptr->logbrush.lbHatch) goto error; break; case BS_DIBPATTERNPT: ptr->logbrush.lbStyle = BS_DIBPATTERN; ptr->logbrush.lbHatch = (ULONG_PTR)dib_copy( (BITMAPINFO *) ptr->logbrush.lbHatch, ptr->logbrush.lbColor); if (!ptr->logbrush.lbHatch) goto error; break; case BS_DIBPATTERN8X8: case BS_DIBPATTERN: { BITMAPINFO* bmi; HGLOBAL h = (HGLOBAL)ptr->logbrush.lbHatch; ptr->logbrush.lbStyle = BS_DIBPATTERN; if (!(bmi = GlobalLock( h ))) goto error; ptr->logbrush.lbHatch = (ULONG_PTR)dib_copy( bmi, ptr->logbrush.lbColor); GlobalUnlock( h ); if (!ptr->logbrush.lbHatch) goto error; break; } default: if(ptr->logbrush.lbStyle > BS_MONOPATTERN) goto error; break; } if ((hbrush = alloc_gdi_handle( &ptr->header, OBJ_BRUSH, &brush_funcs ))) { TRACE("%p\n", hbrush); return hbrush; } error: if (ptr->logbrush.lbHatch) { if (ptr->logbrush.lbStyle == BS_PATTERN) DeleteObject( (HGDIOBJ)ptr->logbrush.lbHatch ); else if (ptr->logbrush.lbStyle == BS_DIBPATTERN) GlobalFree( (HGLOBAL)ptr->logbrush.lbHatch ); } HeapFree( GetProcessHeap(), 0, ptr ); return 0; }
/* * @implemented */ BOOL APIENTRY NtUserGetIconInfo( _In_ HANDLE hCurIcon, _Out_opt_ PICONINFO IconInfo, _Out_opt_ PUNICODE_STRING lpModule, // Optional _Out_opt_ PUNICODE_STRING lpResName, // Optional _Out_opt_ LPDWORD pbpp, // Optional _In_ BOOL bInternal) { ICONINFO ii; PCURICON_OBJECT CurIcon; NTSTATUS Status = STATUS_SUCCESS; BOOL Ret = FALSE; DWORD colorBpp = 0; TRACE("Enter NtUserGetIconInfo\n"); /* Check if something was actually asked */ if (!IconInfo && !lpModule && !lpResName) { WARN("Nothing to fill.\n"); EngSetLastError(ERROR_INVALID_PARAMETER); return FALSE; } UserEnterExclusive(); if (!(CurIcon = UserGetCurIconObject(hCurIcon))) { WARN("UserGetIconObject(0x%08x) Failed.\n", hCurIcon); UserLeave(); return FALSE; } /* Give back the icon information */ if(IconInfo) { PCURICON_OBJECT FrameCurIcon = CurIcon; if(CurIcon->CURSORF_flags & CURSORF_ACON) { /* Get information from first frame. */ FrameCurIcon = ((PACON)CurIcon)->aspcur[0]; } /* Fill data */ ii.fIcon = is_icon(FrameCurIcon); ii.xHotspot = FrameCurIcon->xHotspot; ii.yHotspot = FrameCurIcon->yHotspot; /* Copy bitmaps */ ii.hbmMask = BITMAP_CopyBitmap(FrameCurIcon->hbmMask); GreSetObjectOwner(ii.hbmMask, GDI_OBJ_HMGR_POWNED); ii.hbmColor = BITMAP_CopyBitmap(FrameCurIcon->hbmColor); GreSetObjectOwner(ii.hbmColor, GDI_OBJ_HMGR_POWNED); colorBpp = FrameCurIcon->bpp; /* Copy fields */ _SEH2_TRY { ProbeForWrite(IconInfo, sizeof(ICONINFO), 1); RtlCopyMemory(IconInfo, &ii, sizeof(ICONINFO)); if (pbpp) { ProbeForWrite(pbpp, sizeof(DWORD), 1); *pbpp = colorBpp; } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END if (!NT_SUCCESS(Status)) { WARN("Status: 0x%08x.\n", Status); SetLastNtError(Status); goto leave; } } /* Give back the module name */ if(lpModule) { ULONG BufLen = 0; if (!CurIcon->atomModName) goto leave; RtlQueryAtomInAtomTable(gAtomTable, CurIcon->atomModName, NULL, NULL, NULL, &BufLen); /* Get the module name from the atom table */ _SEH2_TRY { if (BufLen > (lpModule->MaximumLength * sizeof(WCHAR))) { lpModule->Length = 0; } else { ProbeForWrite(lpModule->Buffer, lpModule->MaximumLength, 1); BufLen = lpModule->MaximumLength * sizeof(WCHAR); RtlQueryAtomInAtomTable(gAtomTable, CurIcon->atomModName, NULL, NULL, lpModule->Buffer, &BufLen); lpModule->Length = BufLen/sizeof(WCHAR); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END if (!NT_SUCCESS(Status)) { SetLastNtError(Status); goto leave; } } if (lpResName) { if (!CurIcon->strName.Buffer) goto leave; /* Copy it */ _SEH2_TRY { ProbeForWrite(lpResName, sizeof(UNICODE_STRING), 1); if (IS_INTRESOURCE(CurIcon->strName.Buffer)) { lpResName->Buffer = CurIcon->strName.Buffer; lpResName->Length = 0; } else if (lpResName->MaximumLength < CurIcon->strName.Length) { lpResName->Length = 0; } else { ProbeForWrite(lpResName->Buffer, lpResName->MaximumLength * sizeof(WCHAR), 1); RtlCopyMemory(lpResName->Buffer, CurIcon->strName.Buffer, lpResName->Length); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END } if (!NT_SUCCESS(Status)) { SetLastNtError(Status); goto leave; } Ret = TRUE; leave: UserDereferenceObject(CurIcon); TRACE("Leave NtUserGetIconInfo, ret=%i\n", Ret); UserLeave(); return Ret; }