/*********************************************************************** * GetAtomNameW (KERNEL32.@) * * Unicode version of GetAtomNameA. */ UINT WINAPI GetAtomNameW( ATOM atom, LPWSTR buffer, INT count ) { NTSTATUS status; RTL_ATOM_TABLE table; DWORD length; WCHAR tmp[MAX_ATOM_LEN + 1]; if (count <= 0) { SetLastError( ERROR_MORE_DATA ); return 0; } if (!(table = get_local_table( 0 ))) return 0; length = sizeof(tmp); status = RtlQueryAtomInAtomTable( table, atom, NULL, NULL, tmp, &length ); if (status) { SetLastError( RtlNtStatusToDosError( status ) ); return 0; } length = min(length, (count - 1) * sizeof(WCHAR)); if (length) memcpy(buffer, tmp, length); else SetLastError( ERROR_INSUFFICIENT_BUFFER ); length /= sizeof(WCHAR); buffer[length] = '\0'; return length; }
ULONG FASTCALL IntGetAtomName(RTL_ATOM nAtom, LPWSTR lpBuffer, ULONG nSize) { NTSTATUS Status = STATUS_SUCCESS; PTHREADINFO pti; ULONG Size = nSize; pti = PsGetCurrentThreadWin32Thread(); if (pti->rpdesk == NULL) { SetLastNtError(Status); return 0; } Status = RtlQueryAtomInAtomTable(gAtomTable, nAtom, NULL, NULL, lpBuffer, &Size); if (Size < nSize) *(lpBuffer + Size) = 0; if (!NT_SUCCESS(Status)) { SetLastNtError(Status); return 0; } return Size; }
UINT WINAPI InternalGetAtomName(BOOLEAN Local, BOOLEAN Unicode, ATOM Atom, LPSTR AtomName, DWORD Size) { NTSTATUS Status; DWORD RetVal = 0; ANSI_STRING AnsiString; UNICODE_STRING UnicodeString; PVOID TempBuffer = NULL; PWSTR AtomNameString; ULONG AtomInfoLength; ULONG AtomNameLength; PATOM_BASIC_INFORMATION AtomInfo; /* Normalize the size as not to overflow */ if (!Unicode && Size > 0x7000) Size = 0x7000; /* Make sure it's valid too */ if (!Size) { BaseSetLastNTError(STATUS_BUFFER_OVERFLOW); return 0; } if (!Atom) { BaseSetLastNTError(STATUS_INVALID_PARAMETER); return 0; } /* Check if this is a global query */ if (Local) { /* Set the query length */ AtomNameLength = Size * sizeof(WCHAR); /* If it's unicode, just keep the name */ if (Unicode) { AtomNameString = (PWSTR)AtomName; } else { /* Allocate memory for the ansi buffer */ TempBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, AtomNameLength); AtomNameString = TempBuffer; } /* Query the name */ Status = RtlQueryAtomInAtomTable(InternalInitAtomTable(), Atom, NULL, NULL, AtomNameString, &AtomNameLength); } else { /* We're going to do a global query, so allocate a buffer */ AtomInfoLength = sizeof(ATOM_BASIC_INFORMATION) + (Size * sizeof(WCHAR)); AtomInfo = TempBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, AtomInfoLength); if (!AtomInfo) { BaseSetLastNTError(STATUS_NO_MEMORY); return 0; } /* Query the name */ Status = NtQueryInformationAtom(Atom, AtomBasicInformation, AtomInfo, AtomInfoLength, &AtomInfoLength); if (NT_SUCCESS(Status)) { /* Success. Update the length and get the name */ AtomNameLength = (ULONG)AtomInfo->NameLength; AtomNameString = AtomInfo->Name; } } /* Check for global success */ if (NT_SUCCESS(Status)) { /* Check if it was unicode */ if (Unicode) { /* We return the length in chars */ RetVal = AtomNameLength / sizeof(WCHAR); /* Copy the memory if this was a global query */ if (AtomNameString != (PWSTR)AtomName) { RtlMoveMemory(AtomName, AtomNameString, AtomNameLength); } /* And null-terminate it if the buffer was too large */ if (RetVal < Size) { ((PWCHAR)AtomName)[RetVal] = UNICODE_NULL; } } else { /* First create a unicode string with our data */ UnicodeString.Buffer = AtomNameString; UnicodeString.Length = (USHORT)AtomNameLength; UnicodeString.MaximumLength = (USHORT)(UnicodeString.Length + sizeof(WCHAR)); /* Now prepare an ansi string for conversion */ AnsiString.Buffer = AtomName; AnsiString.Length = 0; AnsiString.MaximumLength = (USHORT)Size; /* Convert it */ Status = RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE); /* Return the length */ if (NT_SUCCESS(Status)) RetVal = AnsiString.Length; } } /* Free the temporary buffer if we have one */ if (TempBuffer) RtlFreeHeap(RtlGetProcessHeap(), 0, TempBuffer); /* Check for failure */ if (!NT_SUCCESS(Status)) { /* Fail */ DPRINT("Failed: %lx\n", Status); BaseSetLastNTError(Status); } /* Return length */ return RetVal; }
/* * @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; }