Beispiel #1
0
/*
 * @implemented
 */
BOOL
APIENTRY
NtUserGetIconSize(
    HANDLE hCurIcon,
    UINT istepIfAniCur,
    PLONG plcx,       // &size.cx
    PLONG plcy)       // &size.cy
{
    PCURICON_OBJECT CurIcon;
    NTSTATUS Status = STATUS_SUCCESS;
    BOOL bRet = FALSE;

    TRACE("Enter NtUserGetIconSize\n");
    UserEnterExclusive();

    if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
    {
        goto cleanup;
    }

    if(CurIcon->CURSORF_flags & CURSORF_ACON)
    {
        /* Use first frame for animated cursors */
        PACON AniCurIcon = (PACON)CurIcon;
        CurIcon = AniCurIcon->aspcur[0];
        UserDereferenceObject(AniCurIcon);
        UserReferenceObject(CurIcon);
    }

    _SEH2_TRY
    {
        ProbeForWrite(plcx, sizeof(LONG), 1);
        *plcx = CurIcon->cx;
        ProbeForWrite(plcy, sizeof(LONG), 1);
        *plcy = CurIcon->cy;
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END

    if (NT_SUCCESS(Status))
        bRet = TRUE;
    else
        SetLastNtError(Status); // Maybe not, test this

    UserDereferenceObject(CurIcon);

cleanup:
    TRACE("Leave NtUserGetIconSize, ret=%i\n", bRet);
    UserLeave();
    return bRet;
}
Beispiel #2
0
static
BOOL
FASTCALL
RemoveTimer(PTIMER pTmr)
{
  BOOL Ret = FALSE;
  if (pTmr)
  {
     /* Set the flag, it will be removed when ready */
     RemoveEntryList(&pTmr->ptmrList);
     if ((pTmr->pWnd == NULL) && (!(pTmr->flags & TMRF_SYSTEM))) // System timers are reusable.
     {
        UINT_PTR IDEvent;

        IDEvent = NUM_WINDOW_LESS_TIMERS - pTmr->nID;
        IntLockWindowlessTimerBitmap();
        RtlClearBit(&WindowLessTimersBitMap, IDEvent);
        IntUnlockWindowlessTimerBitmap();
     }
     UserDereferenceObject(pTmr);
     Ret = UserDeleteObject( UserHMGetHandle(pTmr), otTimer);
  }
  if (!Ret) ERR("Warning: Unable to delete timer\n");

  return Ret;
}
Beispiel #3
0
/*
 * co_UserActivateKbl
 *
 * Activates given layout in specified thread
 */
static PKL
co_UserActivateKbl(PTHREADINFO pti, PKL pKl, UINT Flags)
{
    PKL pklPrev;

    pklPrev = pti->KeyboardLayout;
    if (pklPrev)
        UserDereferenceObject(pklPrev);

    pti->KeyboardLayout = pKl;
    pti->pClientInfo->hKL = pKl->hkl;
    UserReferenceObject(pKl);

    if (Flags & KLF_SETFORPROCESS)
    {
        // FIXME
    }

    // Send WM_INPUTLANGCHANGE to thread's focus window
    co_IntSendMessage(pti->MessageQueue->spwndFocus ? UserHMGetHandle(pti->MessageQueue->spwndFocus) : 0,
                      WM_INPUTLANGCHANGE,
                      (WPARAM)pKl->iBaseCharset, // FIXME: How to set it?
                      (LPARAM)pKl->hkl); // hkl

    return pklPrev;
}
Beispiel #4
0
/* IntDestroyMonitorObject
 *
 * Destroys a MONITOR
 * You have to be the owner of the monitors lock to safely destroy it.
 *
 * Arguments
 *
 *   pMonitor
 *      Pointer to the MONITOR which shall be deleted
 */
static
void
IntDestroyMonitorObject(IN PMONITOR pMonitor)
{
    RtlFreeUnicodeString(&pMonitor->DeviceName);
    UserDereferenceObject(pMonitor);
}
Beispiel #5
0
/*
 * UserLoadKbdLayout
 *
 * Loads keyboard layout and creates KL object
 */
static PKL
UserLoadKbdLayout(PUNICODE_STRING pwszKLID, HKL hKL)
{
    LCID lCid;
    CHARSETINFO cs;
    PKL pKl;

    /* Create keyboard layout object */
    pKl = UserCreateObject(gHandleTable, NULL, NULL, NULL, TYPE_KBDLAYOUT, sizeof(KL));
    if (!pKl)
    {
        ERR("Failed to create object!\n");
        return NULL;
    }

    pKl->hkl = hKL;
    pKl->spkf = UserLoadKbdFile(pwszKLID);

    /* Dereference keyboard layout */
    UserDereferenceObject(pKl);

    /* If we failed, remove KL object */
    if (!pKl->spkf)
    {
        ERR("UserLoadKbdFile(%wZ) failed!\n", pwszKLID);
        UserDeleteObject(pKl->head.h, TYPE_KBDLAYOUT);
        return NULL;
    }

    // Up to Language Identifiers..
    RtlUnicodeStringToInteger(pwszKLID, (ULONG)16, (PULONG)&lCid);
    TRACE("Language Identifiers %wZ LCID 0x%x\n", pwszKLID, lCid);
    if (co_IntGetCharsetInfo(lCid, &cs))
    {
       pKl->iBaseCharset = cs.ciCharset;
       pKl->dwFontSigs = cs.fs.fsCsb[0];
       pKl->CodePage = (USHORT)cs.ciACP;
       TRACE("Charset %u Font Sig %lu CodePage %u\n", pKl->iBaseCharset, pKl->dwFontSigs, pKl->CodePage);
    }
    else
    {
       pKl->iBaseCharset = ANSI_CHARSET;
       pKl->dwFontSigs = FS_LATIN1;
       pKl->CodePage = CP_ACP;
    }

    // Set initial system character set and font signature.
    if (gSystemFS == 0)
    {
       gSystemCPCharSet = pKl->iBaseCharset;
       gSystemFS = pKl->dwFontSigs;
    }

    return pKl;
}
static VOID NTAPI
IntAddSynthesizedFormats(PWINSTATION_OBJECT pWinStaObj)
{
    PCLIP pTextEl, pUniTextEl, pOemTextEl, pLocaleEl, pBmEl, pDibEl;

    pTextEl = IntIsFormatAvailable(pWinStaObj, CF_TEXT);
    pOemTextEl = IntIsFormatAvailable(pWinStaObj, CF_OEMTEXT);
    pUniTextEl = IntIsFormatAvailable(pWinStaObj, CF_UNICODETEXT);
    pLocaleEl = IntIsFormatAvailable(pWinStaObj, CF_LOCALE);
    pBmEl = IntIsFormatAvailable(pWinStaObj, CF_BITMAP);
    pDibEl = IntIsFormatAvailable(pWinStaObj, CF_DIB);

    /* Add CF_LOCALE format if we have CF_TEXT */
    if (!pLocaleEl && pTextEl)
    {
        PCLIPBOARDDATA pMemObj;
        HANDLE hMem;

        pMemObj = (PCLIPBOARDDATA)UserCreateObject(gHandleTable, NULL, NULL, &hMem, TYPE_CLIPDATA,
                                                   sizeof(CLIPBOARDDATA) + sizeof(LCID));
        if (pMemObj)
        {
            pMemObj->cbData = sizeof(LCID);
            *((LCID*)pMemObj->Data) = NtCurrentTeb()->CurrentLocale;
            IntAddFormatedData(pWinStaObj, CF_LOCALE, hMem, TRUE, TRUE);

            /* Release the extra reference (UserCreateObject added 2 references) */
            UserDereferenceObject(pMemObj);
        }
    }

    /* Add CF_TEXT. Note: it is synthesized in user32.dll */
    if (!pTextEl && (pUniTextEl || pOemTextEl))
        IntAddFormatedData(pWinStaObj, CF_TEXT, DATA_SYNTH_USER, FALSE, TRUE);

    /* Add CF_OEMTEXT. Note: it is synthesized in user32.dll */
    if (!pOemTextEl && (pUniTextEl || pTextEl))
        IntAddFormatedData(pWinStaObj, CF_OEMTEXT, DATA_SYNTH_USER, FALSE, TRUE);

    /* Add CF_UNICODETEXT. Note: it is synthesized in user32.dll */
    if (!pUniTextEl && (pTextEl || pOemTextEl))
        IntAddFormatedData(pWinStaObj, CF_UNICODETEXT, DATA_SYNTH_USER, FALSE, TRUE);

    /* Add CF_BITMAP. Note: it is synthesized on demand */
    if (!pBmEl && pDibEl)
        IntAddFormatedData(pWinStaObj, CF_BITMAP, DATA_SYNTH_KRNL, FALSE, TRUE);

    /* Note: We need to render the DIB or DIBV5 format as soon as possible
       because pallette information may change */
    if (!pDibEl && pBmEl)
        IntSynthesizeDib(pWinStaObj, pBmEl->hData);
}
Beispiel #7
0
/* IntAttachMonitor
 *
 * Creates a new MONITOR and appends it to the list of monitors.
 *
 * Arguments
 *
 *   pGdiDevice     Pointer to the PDEVOBJ onto which the monitor was attached
 *   DisplayNumber  Display Number (starting with 0)
 *
 * Return value
 *   Returns a NTSTATUS
 */
NTSTATUS
IntAttachMonitor(IN PDEVOBJ *pGdiDevice,
                 IN ULONG DisplayNumber)
{
    PMONITOR Monitor;
    WCHAR Buffer[CCHDEVICENAME];

    TRACE("Attaching monitor...\n");

    /* create new monitor object */
    Monitor = IntCreateMonitorObject();
    if (Monitor == NULL)
    {
        TRACE("Couldnt create monitor object\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    _snwprintf(Buffer, CCHDEVICENAME, L"\\\\.\\DISPLAY%d", DisplayNumber + 1);
    if (!RtlCreateUnicodeString(&Monitor->DeviceName, Buffer))
    {
        TRACE("Couldn't duplicate monitor name!\n");
        UserDereferenceObject(Monitor);
        UserDeleteObject(UserHMGetHandle(Monitor), otMonitor);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    Monitor->GdiDevice = pGdiDevice;
    Monitor->cWndStack = 0;

    if (gMonitorList == NULL)
    {
        TRACE("Primary monitor is beeing attached\n");
        Monitor->IsPrimary = TRUE;
        gMonitorList = Monitor;
    }
    else
    {
        PMONITOR p;
        TRACE("Additional monitor is beeing attached\n");
        for (p = gMonitorList; p->Next != NULL; p = p->Next)
        {
            p->Next = Monitor;
        }
        Monitor->Prev = p;
    }

    IntUpdateMonitorSize(pGdiDevice);

    return STATUS_SUCCESS;
}
Beispiel #8
0
/* IntDestroyMonitorObject
 *
 * Destroys a MONITOR
 * You have to be the owner of the monitors lock to safely destroy it.
 *
 * Arguments
 *
 *   pMonitor
 *      Pointer to the MONITOR which shall be deleted
 */
static
void
IntDestroyMonitorObject(IN PMONITOR pMonitor)
{
    /* Remove monitor region */
    if (pMonitor->hrgnMonitor)
    {
        GreSetObjectOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_POWNED);
        GreDeleteObject(pMonitor->hrgnMonitor);
    }

    /* Destroy monitor object */
    UserDereferenceObject(pMonitor);
    UserDeleteObject(UserHMGetHandle(pMonitor), TYPE_MONITOR);
}
Beispiel #9
0
/*
 * @implemented
 */
HCURSOR
APIENTRY
NtUserSetCursor(
    HCURSOR hCursor)
{
    PCURICON_OBJECT pcurOld, pcurNew;
    HCURSOR hOldCursor = NULL;

    TRACE("Enter NtUserSetCursor\n");
    UserEnterExclusive();

    if (hCursor)
    {
        pcurNew = UserGetCurIconObject(hCursor);
        if (!pcurNew)
        {
            EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
            goto leave;
        }
        pcurNew->CURSORF_flags |= CURSORF_CURRENT;
    }
    else
    {
        pcurNew = NULL;
    }

    pcurOld = UserSetCursor(pcurNew, FALSE);
    if (pcurOld)
    {
        hOldCursor = pcurOld->head.h;
        pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
        if(UserObjectInDestroy(hOldCursor))
        {
            /* Destroy it once and for all */
            IntDestroyCurIconObject(pcurOld, TRUE);
            hOldCursor = NULL;
        }
        else
        {
            UserDereferenceObject(pcurOld);
        }
    }

leave:
    UserLeave();
    return hOldCursor;
}
Beispiel #10
0
HANDLE APIENTRY
NtUserConvertMemHandle(
   PVOID pData,
   DWORD cbData)
{
    HANDLE hMem = NULL;
    PCLIPBOARDDATA pMemObj;

    UserEnterExclusive();

    /* Create Clipboard data object */
    pMemObj = UserCreateObject(gHandleTable, NULL, NULL, &hMem, TYPE_CLIPDATA, sizeof(CLIPBOARDDATA) + cbData);
    if (!pMemObj)
        goto cleanup;

    pMemObj->cbData = cbData;

    /* Copy data */
    _SEH2_TRY
    {
        ProbeForRead(pData, cbData, 1);
        memcpy(pMemObj->Data, pData, cbData);
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        pMemObj = NULL;
    }
    _SEH2_END;

    /* Release the extra reference (UserCreateObject added 2 references) */
    UserDereferenceObject(pMemObj);

    /* If we failed to copy data, remove handle */
    if (!pMemObj)
    {
        UserDeleteObject(hMem, TYPE_CLIPDATA);
        hMem = NULL;
    }

cleanup:
    UserLeave();

    return hMem;
}
Beispiel #11
0
/*
 * @implemented
 */
BOOL
APIENTRY
NtUserDrawIconEx(
    HDC hdc,
    int xLeft,
    int yTop,
    HICON hIcon,
    int cxWidth,
    int cyHeight,
    UINT istepIfAniCur,
    HBRUSH hbrFlickerFreeDraw,
    UINT diFlags,
    BOOL bMetaHDC, // When TRUE, GDI functions need to be handled in User32!
    PVOID pDIXData)
{
    PCURICON_OBJECT pIcon;
    BOOL Ret;

    TRACE("Enter NtUserDrawIconEx\n");
    UserEnterExclusive();

    if (!(pIcon = UserGetCurIconObject(hIcon)))
    {
        ERR("UserGetCurIconObject(0x%08x) failed!\n", hIcon);
        UserLeave();
        return FALSE;
    }

    Ret = UserDrawIconEx(hdc,
                         xLeft,
                         yTop,
                         pIcon,
                         cxWidth,
                         cyHeight,
                         istepIfAniCur,
                         hbrFlickerFreeDraw,
                         diFlags);

    UserDereferenceObject(pIcon);

    UserLeave();
    return Ret;
}
Beispiel #12
0
HANDLE
IntCreateCurIconHandle(BOOLEAN Animated)
{
    PCURICON_OBJECT CurIcon;
    HANDLE hCurIcon;

    CurIcon = UserCreateObject(
        gHandleTable,
        NULL,
        NULL,
        &hCurIcon,
        TYPE_CURSOR,
        Animated ? sizeof(ACON) : sizeof(CURICON_OBJECT));

    if (!CurIcon)
    {
        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    UserDereferenceObject(CurIcon);

    return hCurIcon;
}
Beispiel #13
0
/*
 * UserLoadKbdFile
 *
 * Loads keyboard layout DLL and creates KBDFILE object
 */
static PKBDFILE
UserLoadKbdFile(PUNICODE_STRING pwszKLID)
{
    PKBDFILE pkf, pRet = NULL;
    NTSTATUS Status;
    ULONG cbSize;
    HKEY hKey = NULL;
    WCHAR wszLayoutPath[MAX_PATH] = L"\\SystemRoot\\System32\\";
    WCHAR wszLayoutRegKey[256] = L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet\\"
                                 L"Control\\Keyboard Layouts\\";

    /* Create keyboard layout file object */
    pkf = UserCreateObject(gHandleTable, NULL, NULL, NULL, TYPE_KBDFILE, sizeof(KBDFILE));
    if (!pkf)
    {
        ERR("Failed to create object!\n");
        return NULL;
    }

    /* Set keyboard layout name */
    swprintf(pkf->awchKF, L"%wZ", pwszKLID);

    /* Open layout registry key */
    RtlStringCbCatW(wszLayoutRegKey, sizeof(wszLayoutRegKey), pkf->awchKF);
    Status = RegOpenKey(wszLayoutRegKey, &hKey);
    if (!NT_SUCCESS(Status))
    {
        ERR("Failed to open keyboard layouts registry key %ws (%lx)\n", wszLayoutRegKey, Status);
        goto cleanup;
    }

    /* Read filename of layout DLL */
    cbSize = sizeof(wszLayoutPath) - wcslen(wszLayoutPath)*sizeof(WCHAR);
    Status = RegQueryValue(hKey,
                           L"Layout File",
                           REG_SZ,
                           wszLayoutPath + wcslen(wszLayoutPath),
                           &cbSize);

    if (!NT_SUCCESS(Status))
    {
        ERR("Can't get layout filename for %wZ (%lx)\n", pwszKLID, Status);
        goto cleanup;
    }

    /* Load keyboard file now */
    if (!UserLoadKbdDll(wszLayoutPath, &pkf->hBase, &pkf->pKbdTbl))
    {
        ERR("Failed to load %ws dll!\n", wszLayoutPath);
        goto cleanup;
    }

    /* Update next field */
    pkf->pkfNext = gpkfList;
    gpkfList = pkf;

    /* Return keyboard file */
    pRet = pkf;

cleanup:
    if (hKey)
        ZwClose(hKey);
    if (pkf)
        UserDereferenceObject(pkf); // we dont need ptr anymore
    if (!pRet)
    {
        /* We have failed - destroy created object */
        if (pkf)
            UserDeleteObject(pkf->head.h, TYPE_KBDFILE);
    }

    return pRet;
}
Beispiel #14
0
static VOID NTAPI
IntSynthesizeDib(
    PWINSTATION_OBJECT pWinStaObj,
    HBITMAP hbm)
{
    HDC hdc;
    ULONG cjInfoSize, cjDataSize;
    PCLIPBOARDDATA pClipboardData;
    HANDLE hMem;
    INT iResult;
    struct
    {
        BITMAPINFOHEADER bmih;
        RGBQUAD rgbColors[256];
    } bmiBuffer;
    PBITMAPINFO pbmi = (PBITMAPINFO)&bmiBuffer;

    /* Get the display DC */
    hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE);
    if (!hdc)
    {
        return;
    }

    /* Get information about the bitmap format */
    iResult = GreGetDIBitsInternal(hdc,
                                   hbm,
                                   0,
                                   0,
                                   NULL,
                                   pbmi,
                                   DIB_RGB_COLORS,
                                   0,
                                   sizeof(bmiBuffer));
    if (iResult == 0)
    {
       goto cleanup;
    }

    /* Get the size for a full BITMAPINFO */
    cjInfoSize = DIB_BitmapInfoSize(pbmi, DIB_RGB_COLORS);

    /* Calculate the size of the clipboard data, which is a packed DIB */
    cjDataSize = cjInfoSize + pbmi->bmiHeader.biSizeImage;

    /* Create the clipboard data */
    pClipboardData = (PCLIPBOARDDATA)UserCreateObject(gHandleTable,
                                                      NULL,
                                                      NULL,
                                                      &hMem,
                                                      TYPE_CLIPDATA,
                                                      cjDataSize);
    if (!pClipboardData)
    {
        goto cleanup;
    }

    /* Set the data size */
    pClipboardData->cbData = cjDataSize;

    /* Copy the BITMAPINFOHEADER */
    memcpy(pClipboardData->Data, pbmi, sizeof(BITMAPINFOHEADER));

    /* Get the bitmap bits and the color table */
    iResult = GreGetDIBitsInternal(hdc,
                                   hbm,
                                   0,
                                   abs(pbmi->bmiHeader.biHeight),
                                   (LPBYTE)pClipboardData->Data + cjInfoSize,
                                   (LPBITMAPINFO)pClipboardData->Data,
                                   DIB_RGB_COLORS,
                                   pbmi->bmiHeader.biSizeImage,
                                   cjInfoSize);

    /* Add the clipboard data */
    IntAddFormatedData(pWinStaObj, CF_DIB, hMem, TRUE, TRUE);

    /* Release the extra reference (UserCreateObject added 2 references) */
    UserDereferenceObject(pClipboardData);

cleanup:
    UserReleaseDC(NULL, hdc, FALSE);
}
Beispiel #15
0
HWINEVENTHOOK
APIENTRY
NtUserSetWinEventHook(
   UINT eventMin,
   UINT eventMax,
   HMODULE hmodWinEventProc,
   PUNICODE_STRING puString,
   WINEVENTPROC lpfnWinEventProc,
   DWORD idProcess,
   DWORD idThread,
   UINT dwflags)
{
   PEVENTHOOK pEH;
   HWINEVENTHOOK Ret = NULL;
   NTSTATUS Status;
   HANDLE Handle;
   PETHREAD Thread = NULL;

   TRACE("NtUserSetWinEventHook hmod 0x%x, pfn 0x%x\n",hmodWinEventProc, lpfnWinEventProc);

   UserEnterExclusive();

   if ( !GlobalEvents )
   {
      GlobalEvents = ExAllocatePoolWithTag(PagedPool, sizeof(EVENTTABLE), TAG_HOOK);
      if (GlobalEvents == NULL)
      {
         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         goto SetEventExit;
      }
      GlobalEvents->Counts = 0;      
      InitializeListHead(&GlobalEvents->Events);
   }

   if (eventMin > eventMax)
   {
      EngSetLastError(ERROR_INVALID_HOOK_FILTER);
      goto SetEventExit;
   }

   if (!lpfnWinEventProc)
   {
      EngSetLastError(ERROR_INVALID_FILTER_PROC);
      goto SetEventExit;
   }

   if ((dwflags & WINEVENT_INCONTEXT) && !hmodWinEventProc)
   {
      EngSetLastError(ERROR_HOOK_NEEDS_HMOD);
      goto SetEventExit;
   }

   if (idThread)
   {
      Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)idThread, &Thread);
      if (!NT_SUCCESS(Status))
      {   
         EngSetLastError(ERROR_INVALID_THREAD_ID);
         goto SetEventExit;
      }
   }
   // Creator, pti is set here.
   pEH = UserCreateObject(gHandleTable, NULL, &Handle, otEvent, sizeof(EVENTHOOK));
   if (pEH)
   {
      InsertTailList(&GlobalEvents->Events, &pEH->Chain);
      GlobalEvents->Counts++;

      UserHMGetHandle(pEH) = Handle;
      pEH->eventMin  = eventMin;
      pEH->eventMax  = eventMax;
      pEH->idProcess = idProcess; // These are cmp'ed
      pEH->idThread  = idThread;  //  "
      pEH->Flags     = dwflags;
    /*
       If WINEVENT_INCONTEXT, set offset from hmod and proc. Save ihmod from
       the atom index table where the hmod data is saved to be recalled later
       if fSync set by WINEVENT_INCONTEXT.
       If WINEVENT_OUTOFCONTEXT just use proc..
       Do this instead....
     */
      if (NULL != hmodWinEventProc)
      {
         pEH->offPfn = (ULONG_PTR)((char *)lpfnWinEventProc - (char *)hmodWinEventProc);
         pEH->ihmod = (INT)hmodWinEventProc;
         pEH->Proc = lpfnWinEventProc;
      }
      else
         pEH->Proc = lpfnWinEventProc;

      UserDereferenceObject(pEH);

      Ret = Handle;
      IntSetSrvEventMask( eventMin, eventMax);
   }

SetEventExit:
   if (Thread) ObDereferenceObject(Thread);
   UserLeave();
   return Ret;
}
Beispiel #16
0
VOID
FASTCALL
IntNotifyWinEvent(
   DWORD Event,
   PWND  pWnd,
   LONG  idObject,
   LONG  idChild,
   DWORD flags)
{
   PEVENTHOOK pEH;
   PLIST_ENTRY pLE;
   PTHREADINFO pti, ptiCurrent;

   TRACE("IntNotifyWinEvent GlobalEvents = 0x%x pWnd 0x%x\n",GlobalEvents, pWnd);

   if (!GlobalEvents || !GlobalEvents->Counts) return;

   if (pWnd && pWnd->state & WNDS_DESTROYED) return;

   ptiCurrent = PsGetCurrentThreadWin32Thread();

   if (pWnd && flags & WEF_SETBYWNDPTI)
      pti = pWnd->head.pti;
   else
      pti = ptiCurrent;

   pLE = GlobalEvents->Events.Flink;
   pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain);
   do
   {
     if (!pEH) break;
     UserReferenceObject(pEH);
     // Must be inside the event window.
     if ( (pEH->eventMin <= Event) && (pEH->eventMax >= Event))
     {
// if all process || all thread || other thread same process
// if ^skip own thread && ((Pid && CPid == Pid && ^skip own process) || all process)
        if ( (!pEH->idProcess || pEH->idProcess == PtrToUint(pti->pEThread->Cid.UniqueProcess)) &&
             (!(pEH->Flags & WINEVENT_SKIPOWNPROCESS) || pEH->head.pti->ppi != pti->ppi) &&
             (!pEH->idThread  || pEH->idThread == PtrToUint(pti->pEThread->Cid.UniqueThread)) &&
             (!(pEH->Flags & WINEVENT_SKIPOWNTHREAD)  || pEH->head.pti != pti) &&
               pEH->head.pti->rpdesk == ptiCurrent->rpdesk ) // Same as hooks.
        {
           // Send message to the thread if pEH is not current.
           if (pEH->head.pti != ptiCurrent)
           {
              ERR("Global Event 0x%x, idObject %d\n", Event, idObject);
              IntCallLowLevelEvent( pEH,
                                    Event,
                                    UserHMGetHandle(pWnd),
                                    idObject,
                                    idChild);
           }
           else
           {
              ERR("Local Event 0x%x, idObject %d\n", Event, idObject);
              co_IntCallEventProc( UserHMGetHandle(pEH),
                                   Event,
                                   UserHMGetHandle(pWnd),
                                   idObject,
                                   idChild,
                                   PtrToUint(NtCurrentTeb()->ClientId.UniqueThread),
                                  (DWORD)EngGetTickCount(),
                                   pEH->Proc);
           }
        }        
     }
     UserDereferenceObject(pEH);
     pLE = pEH->Chain.Flink;
     pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain);
   } while (pLE != &GlobalEvents->Events);
}            
Beispiel #17
0
/*
 * @unimplemented
 */
HCURSOR
NTAPI
NtUserGetCursorFrameInfo(
    HCURSOR hCursor,
    DWORD istep,
    INT* rate_jiffies,
    DWORD* num_steps)
{
    PCURICON_OBJECT CurIcon;
    HCURSOR ret;
    INT jiffies = 0;
    DWORD steps = 1;
    NTSTATUS Status = STATUS_SUCCESS;

    TRACE("Enter NtUserGetCursorFrameInfo\n");
    UserEnterExclusive();

    if (!(CurIcon = UserGetCurIconObject(hCursor)))
    {
        UserLeave();
        return NULL;
    }

    ret = CurIcon->head.h;

    if(CurIcon->CURSORF_flags & CURSORF_ACON)
    {
        PACON AniCurIcon = (PACON)CurIcon;
        if(istep >= AniCurIcon->cicur)
        {
            UserDereferenceObject(CurIcon);
            UserLeave();
            return NULL;
        }
        jiffies = AniCurIcon->ajifRate[istep];
        steps = AniCurIcon->cicur;
        ret = AniCurIcon->aspcur[AniCurIcon->aicur[istep]]->head.h;
    }

    _SEH2_TRY
    {
        ProbeForWrite(rate_jiffies, sizeof(INT), 1);
        ProbeForWrite(num_steps, sizeof(DWORD), 1);
        *rate_jiffies = jiffies;
        *num_steps = steps;
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END

    if (!NT_SUCCESS(Status))
    {
        WARN("Status: 0x%08x.\n", Status);
        SetLastNtError(Status);
        ret = NULL;
    }

    UserDereferenceObject(CurIcon);
    UserLeave();

    TRACE("Leaving NtUserGetCursorFrameInfo, ret = 0x%08x\n", ret);

    return ret;
}
Beispiel #18
0
/*
 * @implemented
 */
DWORD_PTR
APIENTRY
NtUserCallOneParam(
   DWORD_PTR Param,
   DWORD Routine)
{
   DECLARE_RETURN(DWORD_PTR);

   TRACE("Enter NtUserCallOneParam\n");

   UserEnterExclusive();

   switch(Routine)
   {
      case ONEPARAM_ROUTINE_POSTQUITMESSAGE:
          {
                PTHREADINFO pti;
                pti = PsGetCurrentThreadWin32Thread();
                MsqPostQuitMessage(pti->MessageQueue, Param);
                RETURN(TRUE);
          }

      case ONEPARAM_ROUTINE_BEGINDEFERWNDPOS:
         {
             PSMWP psmwp;
             HDWP hDwp = NULL;
             INT count = (INT)Param;

             if (count < 0)
             {
                EngSetLastError(ERROR_INVALID_PARAMETER);
                RETURN(0);
             }
             /* Windows allows zero count, in which case it allocates context for 8 moves */
             if (count == 0) count = 8;

             psmwp = (PSMWP) UserCreateObject( gHandleTable,
                                               NULL,
                                              (PHANDLE)&hDwp,
                                               otSMWP,
                                               sizeof(SMWP));
             if (!psmwp) RETURN(0);
             psmwp->acvr = ExAllocatePoolWithTag(PagedPool, count * sizeof(CVR), USERTAG_SWP);
             if (!psmwp->acvr)
             {
                UserDeleteObject(hDwp, otSMWP);
                RETURN(0);
             }
             RtlZeroMemory(psmwp->acvr, count * sizeof(CVR));
             psmwp->bHandle = TRUE;
             psmwp->ccvr = 0;          // actualCount
             psmwp->ccvrAlloc = count; // suggestedCount             
             RETURN((DWORD_PTR)hDwp);
         }

      case ONEPARAM_ROUTINE_SHOWCURSOR:
         RETURN( (DWORD_PTR)UserShowCursor((BOOL)Param) );

      case ONEPARAM_ROUTINE_GETDESKTOPMAPPING:
         {
             PTHREADINFO ti;
             ti = GetW32ThreadInfo();
             if (ti != NULL)
             {
                /* Try convert the pointer to a user mode pointer if the desktop is
                   mapped into the process */
                RETURN((DWORD_PTR)DesktopHeapAddressToUser((PVOID)Param));
             }
             else
             {
                RETURN(0);
             }
         }

      case ONEPARAM_ROUTINE_WINDOWFROMDC:
         RETURN( (DWORD_PTR)IntWindowFromDC((HDC)Param));

      case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON:
         {
            DWORD_PTR Result;

            Result = gspv.bMouseBtnSwap;
            gspv.bMouseBtnSwap = Param ? TRUE : FALSE;
            gpsi->aiSysMet[SM_SWAPBUTTON] = gspv.bMouseBtnSwap;
            RETURN(Result);
         }

      case ONEPARAM_ROUTINE_SWITCHCARETSHOWING:
         RETURN( (DWORD_PTR)IntSwitchCaretShowing((PVOID)Param));

      case ONEPARAM_ROUTINE_SETCARETBLINKTIME:
         RETURN( (DWORD_PTR)IntSetCaretBlinkTime((UINT)Param));

      case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO:
         RETURN( (DWORD_PTR)MsqSetMessageExtraInfo((LPARAM)Param));

      case ONEPARAM_ROUTINE_CREATEEMPTYCUROBJECT:
         {
            PCURICON_OBJECT CurIcon;
			DWORD_PTR Result ;

            if (!(CurIcon = IntCreateCurIconHandle()))
            {
               EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
               RETURN(0);
            }

            Result = (DWORD_PTR)CurIcon->Self;
			UserDereferenceObject(CurIcon);
			RETURN(Result);
         }

      case ONEPARAM_ROUTINE_GETCURSORPOSITION:
         {
             BOOL ret = TRUE;

            _SEH2_TRY
            {
               ProbeForWrite((POINT*)Param,sizeof(POINT),1);
               RtlCopyMemory((POINT*)Param,&gpsi->ptCursor,sizeof(POINT));
            }
            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
            {
                SetLastNtError(_SEH2_GetExceptionCode());
                ret = FALSE;
            }
            _SEH2_END;

            RETURN (ret);
         }

      case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING:
         {
            BOOL Enable;
            PPROCESSINFO Process = PsGetCurrentProcessWin32Process();

            if(Process != NULL)
            {
               Enable = (BOOL)(Param != 0);

               if(Enable)
               {
                  Process->W32PF_flags &= ~W32PF_NOWINDOWGHOSTING;
               }
               else
               {
                  Process->W32PF_flags |= W32PF_NOWINDOWGHOSTING;
               }

               RETURN( TRUE);
            }

            RETURN( FALSE);
         }

      case ONEPARAM_ROUTINE_GETINPUTEVENT:
         RETURN( (DWORD_PTR)IntMsqSetWakeMask(Param));

      case ONEPARAM_ROUTINE_GETKEYBOARDTYPE:
         RETURN( UserGetKeyboardType(Param));

      case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT:
         RETURN( (DWORD_PTR)UserGetKeyboardLayout(Param));

      case ONEPARAM_ROUTINE_RELEASEDC:
         RETURN (UserReleaseDC(NULL, (HDC) Param, FALSE));

      case ONEPARAM_ROUTINE_REALIZEPALETTE:
         RETURN (UserRealizePalette((HDC) Param));

      case ONEPARAM_ROUTINE_GETQUEUESTATUS:
      {
         RETURN (IntGetQueueStatus((DWORD)Param));
      }
      case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS:
         /* FIXME: Should use UserEnterShared */
         RETURN(IntEnumClipboardFormats(Param));

      case ONEPARAM_ROUTINE_CSRSS_GUICHECK:
          IntUserManualGuiCheck(Param);
          RETURN(TRUE);

      case ONEPARAM_ROUTINE_GETCURSORPOS:
      {
          BOOL Ret = TRUE;
          PPOINTL pptl;
          PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
          if (pti->hdesk != InputDesktopHandle) RETURN(FALSE);
          _SEH2_TRY
          {
             pptl = (PPOINTL)Param;
             *pptl = gpsi->ptCursor;
          }
          _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
          {
             Ret = FALSE;
          }
          _SEH2_END;
          RETURN(Ret);
      }
      case ONEPARAM_ROUTINE_SETPROCDEFLAYOUT:
      {
          PPROCESSINFO ppi;
          if (Param & LAYOUT_ORIENTATIONMASK)
          {
             ppi = PsGetCurrentProcessWin32Process();
             ppi->dwLayout = Param;
             RETURN(TRUE);
          }
          EngSetLastError(ERROR_INVALID_PARAMETER);
          RETURN(FALSE);
      }
      case ONEPARAM_ROUTINE_GETPROCDEFLAYOUT:
      {
          BOOL Ret = TRUE;
          PPROCESSINFO ppi;
          PDWORD pdwLayout;
          if ( PsGetCurrentProcess() == CsrProcess)
          {
             EngSetLastError(ERROR_INVALID_ACCESS);
             RETURN(FALSE);
          }
          ppi = PsGetCurrentProcessWin32Process();
          _SEH2_TRY
          {
             pdwLayout = (PDWORD)Param;
             *pdwLayout = ppi->dwLayout;
          }
          _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
          {
             SetLastNtError(_SEH2_GetExceptionCode());
             Ret = FALSE;
          }
          _SEH2_END;
          RETURN(Ret);
      }
      case ONEPARAM_ROUTINE_REPLYMESSAGE:
          RETURN (co_MsqReplyMessage((LRESULT) Param));
      case ONEPARAM_ROUTINE_MESSAGEBEEP:
          RETURN ( UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, Param) );
		  /* TODO: Implement sound sentry */
   }
   ERR("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
           Routine, Param);
   EngSetLastError(ERROR_INVALID_PARAMETER);
   RETURN( 0);

CLEANUP:
   TRACE("Leave NtUserCallOneParam, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
Beispiel #19
0
BOOLEAN FASTCALL
IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, BOOLEAN bForce)
{
    if(CurIcon->CURSORF_flags & CURSORF_CURRENT)
    {
        /* Mark the object as destroyed, and fail, as per tests */
        TRACE("Cursor is current, marking as destroyed.\n");
        UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
        return FALSE;
    }

    if(CurIcon->head.ppi != PsGetCurrentProcessWin32Process())
    {
        /* This object doesn't belong to the current process */
        WARN("Trying to delete foreign cursor!\n");
        UserDereferenceObject(CurIcon);
        EngSetLastError(ERROR_DESTROY_OBJECT_OF_OTHER_THREAD);
        return FALSE;
    }
    
    /* Do not destroy it if it is shared. (And we're not forced to) */
    if((CurIcon->CURSORF_flags & CURSORF_LRSHARED) && !bForce)
    {
        /* Tests show this is a valid call */
        WARN("Trying to destroy shared cursor!\n");
        UserDereferenceObject(CurIcon);
        return TRUE;
    }

    if(!(CurIcon->CURSORF_flags & CURSORF_ACON))
    {
        HBITMAP bmpMask = CurIcon->hbmMask;
        HBITMAP bmpColor = CurIcon->hbmColor;
        HBITMAP bmpAlpha = CurIcon->hbmAlpha;

        /* Delete bitmaps */
        if (bmpMask)
        {
            GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED);
            GreDeleteObject(bmpMask);
            CurIcon->hbmMask = NULL;
        }
        if (bmpColor)
        {
            GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED);
            GreDeleteObject(bmpColor);
            CurIcon->hbmColor = NULL;
        }
        if (bmpAlpha)
        {
            GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED);
            GreDeleteObject(bmpAlpha);
            CurIcon->hbmAlpha = NULL;
        }
    }
    else
    {
        PACON AniCurIcon = (PACON)CurIcon;
        UINT i;

        for(i = 0; i < AniCurIcon->cpcur; i++)
            IntDestroyCurIconObject(AniCurIcon->aspcur[i], TRUE);
        ExFreePoolWithTag(AniCurIcon->aspcur, USERTAG_CURSOR);
    }

    if (CurIcon->CURSORF_flags & CURSORF_LRSHARED)
    {
        if (!IS_INTRESOURCE(CurIcon->strName.Buffer))
            ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING);
        if (CurIcon->atomModName)
            RtlDeleteAtomFromAtomTable(gAtomTable, CurIcon->atomModName);
        CurIcon->strName.Buffer = NULL;
        CurIcon->atomModName = 0;
    }

    /* We were given a pointer, no need to keep the reference any longer! */
    UserDereferenceObject(CurIcon);
    return UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
}
Beispiel #20
0
/*
 * @implemented
 */
BOOL
APIENTRY
NtUserSetCursorIconData(
  _In_     HCURSOR Handle,
  _In_opt_ PUNICODE_STRING pustrModule,
  _In_opt_ PUNICODE_STRING pustrRsrc,
  _In_     const CURSORDATA* pCursorData)
{
    PCURICON_OBJECT CurIcon;
    NTSTATUS Status = STATUS_SUCCESS;
    BOOLEAN Ret = FALSE;
    BOOLEAN IsShared = FALSE, IsAnim = FALSE;
    DWORD numFrames;
    UINT i = 0;
    
    TRACE("Enter NtUserSetCursorIconData\n");
    
    UserEnterExclusive();

    if (!(CurIcon = UserGetCurIconObject(Handle)))
    {
        UserLeave();
        EngSetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    _SEH2_TRY
    {
        ProbeForRead(pCursorData, sizeof(*pCursorData), 1);
        if(pCursorData->CURSORF_flags & CURSORF_ACON)
        {
            /* This is an animated cursor */
            PACON AniCurIcon = (PACON)CurIcon;
            DWORD numSteps;

            numFrames = AniCurIcon->cpcur = pCursorData->cpcur;
            numSteps = AniCurIcon->cicur = pCursorData->cicur;
            AniCurIcon->iicur = pCursorData->iicur;
            AniCurIcon->rt = pCursorData->rt;

            /* Calculate size: one cursor object for each frame, and a frame index and jiffies for each "step" */
            AniCurIcon->aspcur = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE, /* Let SEH catch allocation failures */
                numFrames * sizeof(CURICON_OBJECT*) + numSteps * (sizeof(DWORD) + sizeof(INT)),
                USERTAG_CURSOR);
            AniCurIcon->aicur = (DWORD*)(AniCurIcon->aspcur + numFrames);
            AniCurIcon->ajifRate = (INT*)(AniCurIcon->aicur + numSteps);

            RtlZeroMemory(AniCurIcon->aspcur, numFrames * sizeof(CURICON_OBJECT*));

            ProbeForRead(pCursorData->aicur, numSteps * sizeof(DWORD), 1);
            RtlCopyMemory(AniCurIcon->aicur, pCursorData->aicur, numSteps * sizeof(DWORD));
            ProbeForRead(pCursorData->ajifRate, numSteps * sizeof(INT), 1);
            RtlCopyMemory(AniCurIcon->ajifRate, pCursorData->ajifRate, numSteps * sizeof(INT));
            
            AniCurIcon->CURSORF_flags = pCursorData->CURSORF_flags;
            pCursorData = pCursorData->aspcur;

            IsAnim = TRUE;
        }
        else
        {
            CurIcon->xHotspot = pCursorData->xHotspot;
            CurIcon->yHotspot = pCursorData->yHotspot;
            CurIcon->cx = pCursorData->cx;
            CurIcon->cy = pCursorData->cy;
            CurIcon->rt = pCursorData->rt;
            CurIcon->bpp = pCursorData->bpp;
            CurIcon->hbmMask = pCursorData->hbmMask;
            CurIcon->hbmColor = pCursorData->hbmColor;
            CurIcon->hbmAlpha = pCursorData->hbmAlpha;
            CurIcon->CURSORF_flags = pCursorData->CURSORF_flags;
        }
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END
    
    if (!NT_SUCCESS(Status))
    {
        SetLastNtError(Status);
        goto done;
    }

    if(IsAnim)
    {
        PACON AniCurIcon = (PACON)CurIcon;
        /* This is an animated cursor. Create a cursor object for each frame and set up the data */
        for(i = 0; i < numFrames; i++)
        {
            HANDLE hCurFrame = IntCreateCurIconHandle(FALSE);
            if(!NtUserSetCursorIconData(hCurFrame, NULL, NULL, pCursorData))
                goto done;
            AniCurIcon->aspcur[i] = UserGetCurIconObject(hCurFrame);
            if(!AniCurIcon->aspcur[i])
                goto done;
            pCursorData++;
        }
    }
    
    if(CurIcon->CURSORF_flags & CURSORF_LRSHARED)
    {
        IsShared = TRUE;
        if(pustrRsrc && pustrModule)
        {
            UNICODE_STRING ustrModuleSafe;
            /* We use this convenient function, because INTRESOURCEs and ATOMs are the same */
            Status = ProbeAndCaptureUnicodeStringOrAtom(&CurIcon->strName, pustrRsrc);
            if(!NT_SUCCESS(Status))
                goto done;
            Status = ProbeAndCaptureUnicodeString(&ustrModuleSafe, UserMode, pustrModule);
            if(!NT_SUCCESS(Status))
                goto done;
            Status = RtlAddAtomToAtomTable(gAtomTable, ustrModuleSafe.Buffer, &CurIcon->atomModName);
            ReleaseCapturedUnicodeString(&ustrModuleSafe, UserMode);
            if(!NT_SUCCESS(Status))
                goto done;
        }
    }

    if(!CurIcon->hbmMask)
    {
        ERR("NtUserSetCursorIconData was got no hbmMask.\n");
        EngSetLastError(ERROR_INVALID_PARAMETER);
        goto done;
    }

    GreSetObjectOwner(CurIcon->hbmMask, GDI_OBJ_HMGR_PUBLIC);

    if(CurIcon->hbmColor)
        GreSetObjectOwner(CurIcon->hbmColor, GDI_OBJ_HMGR_PUBLIC);
    
    if(CurIcon->hbmAlpha)
        GreSetObjectOwner(CurIcon->hbmAlpha, GDI_OBJ_HMGR_PUBLIC);

    if(IsShared)
    {
        /* Update process cache in case of shared cursor */
        PPROCESSINFO ppi = CurIcon->head.ppi;
        UserReferenceObject(CurIcon);
        CurIcon->pcurNext = ppi->pCursorCache;
        ppi->pCursorCache = CurIcon;
    }
    
    Ret = TRUE;

done:
    if(!Ret && IsShared)
    {
        if(!IS_INTRESOURCE(CurIcon->strName.Buffer))
            ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING);
    }

    if(!Ret && IsAnim)
    {
        PACON AniCurIcon = (PACON)CurIcon;
        for(i = 0; i < numFrames; i++)
        {
            if(AniCurIcon->aspcur[i])
                IntDestroyCurIconObject(AniCurIcon->aspcur[i], TRUE);
        }
        AniCurIcon->cicur = 0;
        AniCurIcon->cpcur = 0;
        ExFreePoolWithTag(AniCurIcon->aspcur, USERTAG_CURSOR);
        AniCurIcon->aspcur = NULL;
        AniCurIcon->aicur = NULL;
        AniCurIcon->ajifRate = NULL;
    }

    UserDereferenceObject(CurIcon);
    TRACE("Leave NtUserSetCursorIconData, ret=%i\n",Ret);
    UserLeave();

    return Ret;
}
Beispiel #21
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;
}
Beispiel #22
0
HACCEL
APIENTRY
NtUserCreateAcceleratorTable(
    LPACCEL Entries,
    ULONG EntriesCount)
{
    PACCELERATOR_TABLE Accel;
    HACCEL hAccel;
    ULONG Index;
    NTSTATUS Status = STATUS_SUCCESS;
    DECLARE_RETURN(HACCEL);

    TRACE("Enter NtUserCreateAcceleratorTable(Entries %p, EntriesCount %u)\n",
          Entries, EntriesCount);
    UserEnterExclusive();

    if (!Entries || EntriesCount <= 0)
    {
        SetLastNtError(STATUS_INVALID_PARAMETER);
        RETURN( (HACCEL) NULL );
    }

    Accel = UserCreateObject(gHandleTable, NULL, NULL, (PHANDLE)&hAccel, TYPE_ACCELTABLE, sizeof(ACCELERATOR_TABLE));

    if (Accel == NULL)
    {
        SetLastNtError(STATUS_NO_MEMORY);
        RETURN( (HACCEL) NULL );
    }

    Accel->Count = EntriesCount;
    Accel->Table = ExAllocatePoolWithTag(PagedPool, EntriesCount * sizeof(ACCEL), USERTAG_ACCEL);
    if (Accel->Table == NULL)
    {
        UserDereferenceObject(Accel);
        UserDeleteObject(hAccel, TYPE_ACCELTABLE);
        SetLastNtError(STATUS_NO_MEMORY);
        RETURN( (HACCEL) NULL);
    }

    _SEH2_TRY
    {
        ProbeForRead(Entries, EntriesCount * sizeof(ACCEL), 4);

        for (Index = 0; Index < EntriesCount; Index++)
        {
            Accel->Table[Index].fVirt = Entries[Index].fVirt & FVIRT_MASK;
            if(Accel->Table[Index].fVirt & FVIRTKEY)
            {
                Accel->Table[Index].key = Entries[Index].key;
            }
            else
            {
                RtlMultiByteToUnicodeN(&Accel->Table[Index].key,
                sizeof(WCHAR),
                NULL,
                (PCSTR)&Entries[Index].key,
                sizeof(CHAR));
            }

            Accel->Table[Index].cmd = Entries[Index].cmd;
        }
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END;

    if (!NT_SUCCESS(Status))
    {
        ExFreePoolWithTag(Accel->Table, USERTAG_ACCEL);
        UserDereferenceObject(Accel);
        UserDeleteObject(hAccel, TYPE_ACCELTABLE);
        SetLastNtError(Status);
        RETURN( (HACCEL) NULL);
    }

    /* FIXME: Save HandleTable in a list somewhere so we can clean it up again */

    RETURN(hAccel);

CLEANUP:
    TRACE("Leave NtUserCreateAcceleratorTable(Entries %p, EntriesCount %u) = %p\n",
          Entries, EntriesCount, _ret_);
    UserLeave();
    END_CLEANUP;
}
Beispiel #23
0
NTSTATUS
NTAPI
UserDestroyThreadInfo(struct _ETHREAD *Thread)
{
    PTHREADINFO *ppti;
    PSINGLE_LIST_ENTRY psle;
    PPROCESSINFO ppiCurrent;
    struct _EPROCESS *Process;
    PTHREADINFO ptiCurrent;

    Process = Thread->ThreadsProcess;

    /* Get the Win32 Thread */
    ptiCurrent = PsGetThreadWin32Thread(Thread);

    ASSERT(ptiCurrent);

    TRACE_CH(UserThread,"Destroying pti 0x%p eThread 0x%p\n", ptiCurrent, Thread);

    ptiCurrent->TIF_flags |= TIF_INCLEANUP;
    ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;

    ppiCurrent = ptiCurrent->ppi;
    ASSERT(ppiCurrent);

    IsRemoveAttachThread(ptiCurrent);

    ptiCurrent->TIF_flags |= TIF_DONTATTACHQUEUE;
    ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;

    /* Decrement thread count and check if its 0 */
    ppiCurrent->cThreads--;

    if(ptiCurrent->TIF_flags & TIF_GUITHREADINITIALIZED)
    {
        /* Do now some process cleanup that requires a valid win32 thread */
        if(ptiCurrent->ppi->cThreads == 0)
        {
            /* Check if we have registered the user api hook */
            if(ptiCurrent->ppi == ppiUahServer)
            {
                /* Unregister the api hook */
                UserUnregisterUserApiHook();
            }

            /* Notify logon application to restart shell if needed */
            if(ptiCurrent->pDeskInfo)
            {
                if(ptiCurrent->pDeskInfo->ppiShellProcess == ppiCurrent)
                {
                    DWORD ExitCode = PsGetProcessExitStatus(Process);

                    TRACE_CH(UserProcess, "Shell process is exiting (%lu)\n", ExitCode);

                    UserPostMessage(hwndSAS,
                                    WM_LOGONNOTIFY,
                                    LN_SHELL_EXITED,
                                    ExitCode);

                    ptiCurrent->pDeskInfo->ppiShellProcess = NULL;
                }
            }
        }

        DceFreeThreadDCE(ptiCurrent);
        HOOK_DestroyThreadHooks(Thread);
        EVENT_DestroyThreadEvents(Thread);
        DestroyTimersForThread(ptiCurrent);
        KeSetEvent(ptiCurrent->pEventQueueServer, IO_NO_INCREMENT, FALSE);
        UnregisterThreadHotKeys(ptiCurrent);
        /*
                if (IsListEmpty(&ptiCurrent->WindowListHead))
                {
                   ERR_CH(UserThread,"Thread Window List is Empty!\n");
                }
        */
        co_DestroyThreadWindows(Thread);

        if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling &&
                ppiCurrent->W32PF_flags & W32PF_CLASSESREGISTERED)
        {
            TRACE_CH(UserThread,"DestroyProcessClasses\n");
            /* no process windows should exist at this point, or the function will assert! */
            DestroyProcessClasses(ppiCurrent);
            ppiCurrent->W32PF_flags &= ~W32PF_CLASSESREGISTERED;
        }

        IntBlockInput(ptiCurrent, FALSE);
        IntCleanupThreadCallbacks(ptiCurrent);

        /* cleanup user object references stack */
        psle = PopEntryList(&ptiCurrent->ReferencesList);
        while (psle)
        {
            PUSER_REFERENCE_ENTRY ref = CONTAINING_RECORD(psle, USER_REFERENCE_ENTRY, Entry);
            TRACE_CH(UserThread,"thread clean: remove reference obj 0x%p\n",ref->obj);
            UserDereferenceObject(ref->obj);

            psle = PopEntryList(&ptiCurrent->ReferencesList);
        }
    }

    /* Find the THREADINFO in the PROCESSINFO's list */
    ppti = &ppiCurrent->ptiList;
    while (*ppti != NULL && *ppti != ptiCurrent)
    {
        ppti = &((*ppti)->ptiSibling);
    }

    /* we must have found it */
    ASSERT(*ppti == ptiCurrent);

    /* Remove it from the list */
    *ppti = ptiCurrent->ptiSibling;

    if (ptiCurrent->KeyboardLayout)
        UserDereferenceObject(ptiCurrent->KeyboardLayout);

    if (gptiForeground == ptiCurrent)
    {
//       IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
//       IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, NULL, OBJID_WINDOW, CHILDID_SELF, 0);

        gptiForeground = NULL;
    }

    // Fixes CORE-6384 & CORE-7030.
    /*    if (ptiLastInput == ptiCurrent)
        {
           if (!ppiCurrent->ptiList)
              ptiLastInput = gptiForeground;
           else
              ptiLastInput = ppiCurrent->ptiList;
           ERR_CH(UserThread,"DTI: ptiLastInput is Cleared!!\n");
        }
    */
    TRACE_CH(UserThread,"Freeing pti 0x%p\n", ptiCurrent);

    /* Free the THREADINFO */
    IntDereferenceThreadInfo(ptiCurrent);

    return STATUS_SUCCESS;
}