/*********************************************************************** * FindAtomW (KERNEL32.@) * * Unicode version of FindAtomA. */ ATOM WINAPI FindAtomW( LPCWSTR str ) { ATOM atom = 0; NTSTATUS status; RTL_ATOM_TABLE table; if ((table = get_local_table( 0 ))) { status = RtlLookupAtomInAtomTable( table, str, &atom ); if (status) { SetLastError( RtlNtStatusToDosError( status ) ); atom = 0; } } return atom; }
/*********************************************************************** * FindAtomA (KERNEL32.@) * * Get the atom associated with a string. * * RETURNS * Success: The associated atom. * Failure: 0. */ ATOM WINAPI FindAtomA( LPCSTR str /* [in] Pointer to string to find */ ) { ATOM atom = 0; if (!check_integral_atom( str, &atom )) { WCHAR buffer[MAX_ATOM_LEN + 1]; DWORD len; RTL_ATOM_TABLE table; len = MultiByteToWideChar( CP_ACP, 0, str, -1, buffer, MAX_ATOM_LEN + 1 ); if (!len) SetLastError( ERROR_INVALID_PARAMETER ); else if ((table = get_local_table( 0 ))) { NTSTATUS status = RtlLookupAtomInAtomTable( table, buffer, &atom ); if (status) { SetLastError( RtlNtStatusToDosError( status ) ); atom = 0; } } } return atom; }
ATOM WINAPI InternalFindAtom(BOOLEAN Local, BOOLEAN Unicode, LPCSTR AtomName) { NTSTATUS Status; ANSI_STRING AnsiString; UNICODE_STRING UnicodeString; PUNICODE_STRING AtomNameString; ATOM Atom = INVALID_ATOM; /* Check if it's an integer atom */ if ((ULONG_PTR)AtomName <= 0xFFFF) { /* Convert the name to an atom */ Atom = (ATOM)PtrToShort((PVOID)AtomName); if (Atom >= MAXINTATOM) { /* Fail, atom number too large */ BaseSetLastNTError(STATUS_INVALID_PARAMETER); DPRINT1("Invalid atom\n"); } /* Return it */ return Atom; } else { /* Check if this is a unicode atom */ if (Unicode) { /* Use a unicode string */ AtomNameString = &UnicodeString; RtlInitUnicodeString(AtomNameString, (LPWSTR)AtomName); Status = STATUS_SUCCESS; } else { /* Use an ansi string */ RtlInitAnsiString(&AnsiString, AtomName); /* Check if we can abuse the TEB */ if (AnsiString.MaximumLength > 260) { /* We can't, allocate a new string */ AtomNameString = &UnicodeString; Status = RtlAnsiStringToUnicodeString(AtomNameString, &AnsiString, TRUE); } else { /* We can! Get the TEB String */ AtomNameString = &NtCurrentTeb()->StaticUnicodeString; /* Convert it into the TEB */ Status = RtlAnsiStringToUnicodeString(AtomNameString, &AnsiString, FALSE); } } /* Check for failure */ if (!NT_SUCCESS(Status)) { DPRINT1("Failed\n"); BaseSetLastNTError(Status); return Atom; } } /* Check if we're doing local lookup */ if (Local) { /* Do a local lookup */ Status = RtlLookupAtomInAtomTable(InternalInitAtomTable(), AtomNameString->Buffer, &Atom); } else { /* Do a global search */ if (!AtomNameString->Length) { /* This is illegal in win32 */ DPRINT1("No name given\n"); Status = STATUS_OBJECT_NAME_NOT_FOUND; } else { /* Call the global function */ Status = NtFindAtom(AtomNameString->Buffer, AtomNameString->Length, &Atom); } } /* Check for failure */ if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status); /* Check if we were non-static ANSI */ if (!(Unicode) && (AtomNameString == &UnicodeString)) { /* Free the allocated buffer */ RtlFreeUnicodeString(AtomNameString); } /* Return the atom */ return Atom; }
/* * @implemented */ HICON NTAPI NtUserFindExistingCursorIcon( _In_ PUNICODE_STRING pustrModule, _In_ PUNICODE_STRING pustrRsrc, _In_ FINDEXISTINGCURICONPARAM* param) { PCURICON_OBJECT CurIcon; HICON Ret = NULL; UNICODE_STRING ustrModuleSafe, ustrRsrcSafe; FINDEXISTINGCURICONPARAM paramSafe; NTSTATUS Status; PPROCESSINFO pProcInfo = PsGetCurrentProcessWin32Process(); RTL_ATOM atomModName; TRACE("Enter NtUserFindExistingCursorIcon\n"); _SEH2_TRY { ProbeForRead(param, sizeof(*param), 1); RtlCopyMemory(¶mSafe, param, sizeof(paramSafe)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END /* Capture resource name (it can be an INTRESOURCE == ATOM) */ Status = ProbeAndCaptureUnicodeStringOrAtom(&ustrRsrcSafe, pustrRsrc); if(!NT_SUCCESS(Status)) return NULL; Status = ProbeAndCaptureUnicodeString(&ustrModuleSafe, UserMode, pustrModule); if(!NT_SUCCESS(Status)) goto done; Status = RtlLookupAtomInAtomTable(gAtomTable, ustrModuleSafe.Buffer, &atomModName); ReleaseCapturedUnicodeString(&ustrModuleSafe, UserMode); if(!NT_SUCCESS(Status)) { /* The module is not in the atom table. No chance to find the cursor */ goto done; } UserEnterExclusive(); CurIcon = pProcInfo->pCursorCache; while(CurIcon) { /* Icon/cursor */ if (paramSafe.bIcon != is_icon(CurIcon)) { CurIcon = CurIcon->pcurNext; continue; } /* See if module names match */ if (atomModName == CurIcon->atomModName) { /* They do. Now see if this is the same resource */ if (IS_INTRESOURCE(CurIcon->strName.Buffer) != IS_INTRESOURCE(ustrRsrcSafe.Buffer)) { /* One is an INT resource and the other is not -> no match */ CurIcon = CurIcon->pcurNext; continue; } if (IS_INTRESOURCE(CurIcon->strName.Buffer)) { if (CurIcon->strName.Buffer == ustrRsrcSafe.Buffer) { /* INT resources match */ break; } } else if (RtlCompareUnicodeString(&ustrRsrcSafe, &CurIcon->strName, TRUE) == 0) { /* Resource name strings match */ break; } } CurIcon = CurIcon->pcurNext; } if(CurIcon) Ret = CurIcon->head.h; UserLeave(); done: if(!IS_INTRESOURCE(ustrRsrcSafe.Buffer)) ExFreePoolWithTag(ustrRsrcSafe.Buffer, TAG_STRING); return Ret; }