Example #1
0
VOID DestroyThreadsHotKeys()
{
    PHOTKEY *pphk;
    PHOTKEY phk;
    PTHREADINFO ptiCurrent = PtiCurrent();

    pphk = &gphkFirst;
    while (*pphk) {
        if ((*pphk)->pti == ptiCurrent) {
            phk = *pphk;
            *pphk = (*pphk)->phkNext;

            /*
             * Unlock the object stored here.
             */
            if ((phk->spwnd != PWND_FOCUS) && (phk->spwnd != PWND_INPUTOWNER)) {
                Unlock(&phk->spwnd);
            }

            UserFreePool(phk);
        } else {
            pphk = &((*pphk)->phkNext);
        }
    }
}
Example #2
0
/***************************************************************************\
* MNFreePopup
*
\***************************************************************************/
VOID MNFreePopup(
    PPOPUPMENU ppopupmenu)
{
    PMENU pmenu;
    PMENU pmenuSys;

#ifdef DEBUG
    Validateppopupmenu(ppopupmenu);
#endif

    if (IsRootPopupMenu(ppopupmenu)) {
        MNFlushDestroyedPopups (ppopupmenu, TRUE);
    }

    /*
     * This app is finished using the global system menu: unlock any objects
     * it is using!
     *
     * NOTE: This global system menu thing doesn't work: two apps can use
     *       it at the same time: which would be a disasterous bug!
     */
    if (ppopupmenu->spwndNotify != NULL) {
        pmenuSys = ppopupmenu->spwndNotify->head.rpdesk->spmenuSys;
        if (pmenuSys != NULL) {
            Unlock(&pmenuSys->spwndNotify);
            if ((pmenu = _GetSubMenu(pmenuSys, 0)) != NULL)
                Unlock(&pmenu->spwndNotify);
        }

        Unlock(&ppopupmenu->spwndNotify);
    }

    Unlock(&ppopupmenu->spwndPopupMenu);

    Unlock(&ppopupmenu->spwndNextPopup);
    Unlock(&ppopupmenu->spwndPrevPopup);
    Unlock(&ppopupmenu->spmenu);
    Unlock(&ppopupmenu->spmenuAlternate);
    Unlock(&ppopupmenu->spwndActivePopup);

#ifdef DEBUG
   ppopupmenu->fFreed = TRUE;
#endif

    if (ppopupmenu == &gpopupMenu) {
        UserAssert(gfPopupInUse);
        gfPopupInUse = FALSE;
    } else {
        UserFreePool(ppopupmenu);
    }
}
Example #3
0
BOOL xxxRegisterUserHungAppHandlers(
    PFNW32ET pfnW32EndTask,
    HANDLE   hEventWowExec)
{
    BOOL   bRetVal;
    PPROCESSINFO    ppi;
    PWOWPROCESSINFO pwpi;

    //
    //  Allocate the per wow process info stuff
    //  ensuring the memory is Zero init.
    //
    pwpi = (PWOWPROCESSINFO) UserAllocPoolWithQuota(sizeof(WOWPROCESSINFO), TAG_WOW);
    if (!pwpi)
        return FALSE;
    RtlZeroMemory(pwpi, sizeof(*pwpi));

    //
    // Reference the WowExec event for kernel access
    //
    bRetVal = NT_SUCCESS(ObReferenceObjectByHandle(
                 hEventWowExec,
                 EVENT_ALL_ACCESS,
                 NULL,
                 UserMode,
                 &pwpi->pEventWowExec,
                 NULL
                 ));

    //
    //  if sucess then intialize the pwpi, ppi structs
    //  else free allocated memory
    //
    if (bRetVal) {
        pwpi->hEventWowExecClient = hEventWowExec;
        pwpi->lpfnWowExitTask = (DWORD)pfnW32EndTask;
        ppi = PpiCurrent();
        ppi->pwpi = pwpi;

        // add to the list, order doesn't matter
        pwpi->pwpiNext = gpwpiFirstWow;
        gpwpiFirstWow  = pwpi;

        }
    else {
        UserFreePool(pwpi);
        }

   return bRetVal;
}
Example #4
0
VOID DestroyWindowsHotKeys(
    PWND pwnd)
{
    PHOTKEY *pphk;
    PHOTKEY phk;

    pphk = &gphkFirst;
    while (*pphk) {
        if ((*pphk)->spwnd == pwnd) {
            phk = *pphk;
            *pphk = (*pphk)->phkNext;

            Unlock(&phk->spwnd);
            UserFreePool(phk);
        } else {
            pphk = &((*pphk)->phkNext);
        }
    }
}
Example #5
0
BOOL _DestroyCursor(
    PCURSOR pcur,
    DWORD   cmdDestroy)
{
    PPROCESSINFO ppi;
    PPROCESSINFO ppiCursor;
    int          i;
    extern BOOL DestroyAniIcon(PACON pacon);

    if (pcur == NULL) {
        UserAssert(FALSE);
        return(TRUE);
    }
    ppi = PpiCurrent();
    ppiCursor = GETPPI(pcur);

    /*
     * Remove this icon from the caption icon cache.
     */
    for (i = 0; i < CCACHEDCAPTIONS; i++) {
        if (cachedCaptions[i].spcursor == pcur) {
            Unlock( &(cachedCaptions[i].spcursor) );
        }
    }

    /*
     * First step in destroying an cursor
     */
    switch (cmdDestroy) {

    case CURSOR_ALWAYSDESTROY:

        /*
         * Always destroy? then don't do any checking...
         */
        break;

    case CURSOR_CALLFROMCLIENT:

        /*
         * Can't destroy public cursors/icons.
         */
        if (ppiCursor == NULL)
            /*
             * Fake success if its a resource loaded icon because
             * this is how win95 responded.
             */
            return !!(pcur->CURSORF_flags & CURSORF_FROMRESOURCE);

        /*
         * If this cursor was loaded from a resource, don't free it till the
         * process exits.  This is the way we stay compatible with win3.0's
         * cursors which were actually resources.  Resources under win3 have
         * reference counting and other "features" like handle values that
         * never change.  Read more in the comment in
         * ServerLoadCreateCursorIcon().
         */
        if (pcur->CURSORF_flags & (CURSORF_LRSHARED | CURSORF_SECRET)) {
            return TRUE;
        }

        /*
         * One thread can't destroy the objects created by another.
         */
        if (ppiCursor != ppi) {
            RIPERR0(ERROR_DESTROY_OBJECT_OF_OTHER_THREAD, RIP_VERBOSE, "");
            return FALSE;
        }

        /*
         * fall through.
         */

    case CURSOR_THREADCLEANUP:

        /*
         * Don't destroy public objects either (pretend it worked though).
         */
        if (ppiCursor == NULL)
            return TRUE;
        break;
    }

    /*
     * First mark the object for destruction.  This tells the locking code that
     * we want to destroy this object when the lock count goes to 0.  If this
     * returns FALSE, we can't destroy the object yet.
     */
    if (!HMMarkObjectDestroy((PHEAD)pcur))
        return FALSE;

    if (pcur->strName.Length != 0) {
        UserFreePool((LPSTR)pcur->strName.Buffer);
    }

    if (pcur->atomModName != 0) {
        DeleteAtom(pcur->atomModName);
    }

    /*
     * If this is an ACON call its special routine to destroy it.
     */
    if (pcur->CURSORF_flags & CURSORF_ACON) {
        DestroyAniIcon((PACON)pcur);
    } else {
        if (pcur->hbmMask != NULL) {
            GreDeleteObject(pcur->hbmMask);
        }
        if (pcur->hbmColor != NULL) {
            GreDeleteObject(pcur->hbmColor);
        }
    }

    /*
     * Ok to destroy...  Free the handle (which will free the object and the
     * handle).
     */
    DestroyEmptyCursorObject(pcur);
    return TRUE;
}
Example #6
0
PHOTKEY FindHotKey(
    PTHREADINFO ptiCurrent,
    PWND pwnd,
    int id,
    UINT fsModifiers,
    UINT vk,
    BOOL fUnregister,
    PBOOL pfKeysExist)
{
    PHOTKEY phk, phkRet, phkPrev;

    /*
     * Initialize out 'return' values.
     */
    *pfKeysExist = FALSE;
    phkRet = NULL;

    phk = gphkFirst;

    while (phk) {

        /*
         * If all this matches up then we've found it.
         */
        if ((phk->pti == ptiCurrent) && (phk->spwnd == pwnd) && (phk->id == id)) {
            if (fUnregister) {

                /*
                 * Unlink the HOTKEY from the list.
                 */
                if (phk == gphkFirst) {
                    gphkFirst = phk->phkNext;
                } else {
                    phkPrev->phkNext = phk->phkNext;
                }

                if ((pwnd != PWND_FOCUS) && (pwnd != PWND_INPUTOWNER)) {
                    Unlock(&phk->spwnd);
                }
                UserFreePool((PVOID)phk);

                return((PHOTKEY)1);
            }
            phkRet = phk;
        }

        /*
         * If the key is already registered, set the exists flag so
         * the app knows it can't use this hotkey sequence.
         */
        if ((phk->fsModifiers == fsModifiers) && (phk->vk == vk)) {

            /*
             * In the case of PWND_FOCUS, we need to check that the queues
             * are the same since PWND_FOCUS is local to the queue it was
             * registered under.
             */
            if (phk->spwnd == PWND_FOCUS) {
                if (phk->pti == ptiCurrent) {
                    *pfKeysExist = TRUE;
                }
            } else {
                *pfKeysExist = TRUE;
            }
        }

        phkPrev = phk;
        phk = phk->phkNext;
    }

    return phkRet;
}
Example #7
0
/***************************************************************************\
* xxxCsEvent
*
* Description:
*   Handles broadcasting of all types of DDEML events.
*
* History:
* 11-1-91   sanfords    Created.
* 10-28-97  FritzS    added cbEventData as a passed-in parameter.  This was
                      done because the EVENT_PACKET may be client-side and
                      we capture the count to keep a hostile app from changing
                      the size after data probing.
\***************************************************************************/
DWORD xxxCsEvent(
PEVENT_PACKET pep, WORD cbEventData)
{
    PSVR_INSTANCE_INFO psiiT;
    PEVENT_PACKET pep2;
    HWND *ahwndEvent = NULL;
    PWND pwnd;
    int cHwndAllocated, i, cTargets;
    TL tlpwnd;
    TL tlpep2;
    TL tlahwndEvent;
    ULONG cbEventPacket;
    PTHREADINFO pti = PtiCurrent();

    CheckCritIn();

    /*
     * Copy pep info to a server side stable area
     */
    cbEventPacket = cbEventData + sizeof(EVENT_PACKET) - sizeof(DWORD);
    pep2 = (PEVENT_PACKET)UserAllocPoolWithQuota(cbEventPacket, TAG_DDE5);
    if (pep2 == NULL) {
        return DMLERR_MEMORY_ERROR;
    }
    try {
        RtlCopyMemory((LPSTR)pep2, (LPSTR)pep, cbEventPacket);
    } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
        UserFreePool(pep2);
        return DMLERR_INVALIDPARAMETER;
    }

    pep2->cbEventData = cbEventData;
    cTargets = 0;
    cHwndAllocated = 0;

    for (psiiT = psiiList; psiiT != NULL; psiiT =  psiiT->next) {
        //
        // Don't bother with event windows for instances who's flags
        // indicate they're not interrested in the event.
        //
        if (((psiiT->afCmd & pep2->EventType) && !pep2->fSense) ||
                (!(psiiT->afCmd & pep2->EventType) && pep2->fSense)) {
            continue;
        }

        if (cTargets >= cHwndAllocated) {
            if (ahwndEvent == NULL) {
                cHwndAllocated = 8;
                ahwndEvent = (HWND *)UserAllocPoolWithQuota(
                        sizeof(HWND) * cHwndAllocated,
                        TAG_DDE6);
            } else {
                DWORD dwSize = cHwndAllocated * sizeof(HWND);
                HWND *ahwndEventT = ahwndEvent;

                cHwndAllocated += 8;
                ahwndEvent = (HWND *)UserReAllocPoolWithQuota(ahwndEvent, dwSize,
                        sizeof(HWND) * cHwndAllocated, TAG_DDE7);
                if (ahwndEvent == NULL) {
                    UserFreePool(ahwndEventT);
                }
            }
            if (ahwndEvent == NULL) {
                UserFreePool(pep2);
                return DMLERR_MEMORY_ERROR;
            }
        }
        ahwndEvent[cTargets++] = PtoH(psiiT->spwndEvent);
    }

    ThreadLockPool(pti, pep2, &tlpep2);
    if (ahwndEvent != NULL) {
        ThreadLockPool(pti, ahwndEvent, &tlahwndEvent);
        for (i = 0; i < cTargets; i++) {
            /*
             * We need to change contexts for the callback
             */
            pwnd = ValidateHwnd(ahwndEvent[i]);
            if (pwnd != NULL) {
                ThreadLockAlwaysWithPti(pti, pwnd, &tlpwnd);
                xxxSendMessage(pwnd, WM_DDEMLEVENT, 0, (LPARAM)pep2);
                ThreadUnlock(&tlpwnd);
            }
        }
        ThreadUnlockAndFreePool(pti, &tlahwndEvent);
    }
    ThreadUnlockAndFreePool(pti, &tlpep2);

    return DMLERR_NO_ERROR;
}
Example #8
0
HPALETTE CreatePaletteFromBitmap(
    HBITMAP hbm)
{
    HPALETTE     hpal;
    LPLOGPALETTE ppal;
    HBITMAP      hbmT;
    DWORD        size;
    int          i;

    /*
     * Make room for temp logical palette of max size.
     */
    size = sizeof(LOGPALETTE) + (MAXPAL * sizeof(PALETTEENTRY));

    ppal = (LPLOGPALETTE)UserAllocPool(size, TAG_SYSTEM);
    if (!ppal)
        return NULL;

    /*
     * Retrieve the palette from the DIB(Section).  The method of calling
     * GreGetDIBColorTable() can only be done on sections or REAL-Dibs.
     */
    hbmT = GreSelectBitmap(ghdcMem, hbm);
    ppal->palVersion    = 0x300;
    ppal->palNumEntries = (WORD)GreGetDIBColorTable(ghdcMem,
                                              0,
                                              MAXPAL,
                                              (LPRGBQUAD)ppal->palPalEntry);
    GreSelectBitmap(ghdcMem, hbmT);

    /*
     * Create a halftone-palette if their are no entries.  Otherwise,
     * swap the RGB values to be palentry-compatible and create us a
     * palette.
     */
    if (ppal->palNumEntries == 0) {
        hpal = GreCreateHalftonePalette(gpDispInfo->hdcScreen);
    } else {

        BYTE tmpR;

        /*
         * Swap red/blue because a RGBQUAD and PALETTEENTRY dont get along.
         */
        for (i=0; i < (int)ppal->palNumEntries; i++) {
            tmpR                         = ppal->palPalEntry[i].peRed;
            ppal->palPalEntry[i].peRed   = ppal->palPalEntry[i].peBlue;
            ppal->palPalEntry[i].peBlue  = tmpR;
            ppal->palPalEntry[i].peFlags = 0;
        }

        /*
         * If the Bitmap only has VGA colors in it we dont want to
         * use a palette.  It just causes unessesary palette flashes.
         */
        hpal = TestVGAColors(ppal) ? NULL : GreCreatePalette(ppal);
    }

    UserFreePool(ppal);

    /*
     * Make this palette public.
     */
    if (hpal)
        GreSetPaletteOwner(hpal, OBJECT_OWNER_PUBLIC);

    return hpal;
}
Example #9
0
LPWSTR GetDeskWallpaperName(PUNICODE_STRING pProfileUserName,
        LPWSTR       lpszFile
        )
{
    WCHAR  wszKey[GDWPN_KEYSIZE];
    WCHAR  wszNone[GDWPN_KEYSIZE];
    LPWSTR lpszBitmap = NULL;

    /*
     * Load the none-string.  This will be used for comparisons later.
     */
    ServerLoadString(hModuleWin, STR_NONE, wszNone, ARRAY_SIZE(wszNone));

    if ((lpszFile == NULL)                 ||
        (lpszFile == SETWALLPAPER_DEFAULT) ||
        (lpszFile == SETWALLPAPER_METRICS)) {

        /*
         * Allocate a buffer for the wallpaper.  We will assume
         * a default-size in this case.
         */
        lpszBitmap = UserAllocPool(GDWPN_BITSIZE * sizeof(WCHAR), TAG_SYSTEM);
        if (lpszBitmap == NULL)
            return NULL;

        /*
         * Get the "Wallpaper" string from WIN.INI's [Desktop] section.  The
         * section name is not localized, so hard code it.  If the string
         * returned is Empty, then set it up for a none-wallpaper.
         */
        if (!FastGetProfileStringFromIDW(pProfileUserName,
                                            PMAP_DESKTOP,
                                            STR_DTBITMAP,
                                            wszNone,
                                            lpszBitmap,
                                            GDWPN_BITSIZE
                                            )) {
            wcscpy(lpszBitmap, wszNone);
        }

    } else {

        UINT uLen;

        uLen = wcslen(lpszFile) + 1;
        uLen = max(uLen, GDWPN_BITSIZE);

        /*
         * Allocate enough space to store the name passed in.  Returning
         * NULL will allow the wallpaper to redraw.  As well, if we're
         * out of memory, then no need to load a wallpaper anyway.
         */
        lpszBitmap = UserAllocPool(uLen * sizeof(WCHAR), TAG_SYSTEM);
        if (lpszBitmap == NULL)
            return NULL;

        wcscpy(lpszBitmap, lpszFile);
    }

    /*
     * No bitmap if NULL passed in or if (NONE) in win.ini entry.  We
     * return NULL to force the redraw of the wallpaper in the kernel.
     */
    if ((*lpszBitmap == (WCHAR)0) || (_wcsicmp(lpszBitmap, wszNone) == 0)) {
        UserFreePool(lpszBitmap);
        return NULL;
    }

    /*
     * If bitmap name set to (DEFAULT) then set it to the system bitmap.
     */
    ServerLoadString(hModuleWin, STR_DEFAULT, wszKey, ARRAY_SIZE(wszKey));

    if (_wcsicmp(lpszBitmap, wszKey) == 0) {
        GetDefaultWallpaperName(lpszBitmap);
    }


    return lpszBitmap;
}
Example #10
0
BOOL xxxSetDeskWallpaper(PUNICODE_STRING pProfileUserName,
    LPWSTR lpszFile)
{
    BITMAP       bm;
    UINT         WallpaperStyle2;
    PWND         pwndShell;
    TL           tl;
    PTHREADINFO  ptiCurrent = PtiCurrent();
    PDESKTOP     pdesk;
    BOOL         fRet = FALSE;
    HBITMAP      hbmOld;

    PROFINTINFO  apsi[] = {
        {PMAP_DESKTOP, (LPWSTR)STR_TILEWALL , 0, &gwWPStyle    },
        {PMAP_DESKTOP, (LPWSTR)STR_DTSTYLE  , 0, &WallpaperStyle2   },
        {PMAP_DESKTOP, (LPWSTR)STR_DTORIGINX, 0, &gsrcWallpaper.x },
        {PMAP_DESKTOP, (LPWSTR)STR_DTORIGINY, 0, &gsrcWallpaper.y },
        {0,            NULL,                  0, NULL               }
    };

    pdesk = ptiCurrent->rpdesk;
    hbmOld = ghbmWallpaper;

    /*
     * Get the shell-window.  This could be NULL on system
     * initialization.  We will use this to do palette realization.
     */
    pwndShell = (pdesk ? pdesk->pDeskInfo->spwndShell : NULL);

    if ((lpszFile == SETWALLPAPER_METRICS) && !(gwWPStyle & DTF_STRETCH)) {

        gsrcWallpaper.x = 0;
        gsrcWallpaper.y = 0;

        if (ghbmWallpaper)
            goto CreateNewWallpaper;

        goto Metric_Change;
    }

CreateNewWallpaper:

    /*
     * Delete the old wallpaper and palette if the exist.
     */
    if (ghpalWallpaper) {
        GreDeleteObject(ghpalWallpaper);
        ghpalWallpaper = NULL;
    }

    if (ghbmWallpaper) {
        GreDeleteObject(ghbmWallpaper);
        ghbmWallpaper = NULL;
    }

    /*
     * Kill any SPBs no matter what.
     * Works if we're switching from/to palettized wallpaper.
     * Fixes a lot of problems because palette doesn't change, shell
     * paints funny on desktop, etc.
     */
    FreeAllSpbs();

    /*
     * If this is a metric-change (and stretched), then we need to
     * reload it.  However, since we are called from the winlogon process
     * during a desktop-switch, we would be mapped to the wrong Luid
     * when we attempt to grab the name from GetDeskWallpaperName.  This
     * would use the Luid from the DEFAULT user rather than the current
     * logged on user.  In order to avoid this, we cache the wallpaer
     * name so that on METRIC-CHANGES we use the current-user's wallpaper.
     *
     * NOTE: we assume that prior to any METRIC change, we have already
     * setup the ghbmWallpaper and lpszCached.  This is usually done
     * either on logon or during user desktop-changes through conrol-Panel.
     */
    if (lpszFile == SETWALLPAPER_METRICS) {

        UserAssert(gpszWall != NULL);

        goto LoadWallpaper;
    }

    /*
     * Free the cached handle.
     */
    if (gpszWall) {
        UserFreePool(gpszWall);
        gpszWall = NULL;
    }

    /*
     * Load the wallpaper-name.  If this returns FALSE, then
     * the user specified (None).  We will return true to force
     * the repainting of the desktop.
     */
    gpszWall = GetDeskWallpaperName(pProfileUserName,lpszFile);
    if (!gpszWall) {
        fRet = TRUE;
        goto SDW_Exit;
    }

    /*
     * Retrieve the default settings from the registry.
     *
     * If tile is indicated, then normalize style to not include
     * FIT/STRETCH which are center-only styles.  Likewise, if
     * we are centered, then normalize out the TILE bit.
     */
    FastGetProfileIntsW(pProfileUserName, apsi);

    gwWPStyle &= DTF_TILE;
    if (!(gwWPStyle & DTF_TILE)) {
        gwWPStyle = WallpaperStyle2 & DTF_STRETCH;
    }

    /*
     * Load the wallpaper.  This makes a callback to the client to
     * perform the bitmap-creation.
     */

LoadWallpaper:

    if (xxxLoadDesktopWallpaper(gpszWall) == FALSE) {
        gwWPStyle = 0;
        goto SDW_Exit;
    }

    /*
     * If we have a palette, then we need to do the correct realization and
     * notification.
     */
    if (ghpalWallpaper != NULL) {
        PWND pwndSend;

        if (pwndShell) {
            pwndSend = pwndShell;
        } else {
            pwndSend = (pdesk ? pdesk->pDeskInfo->spwnd : NULL);
        }

        /*
         * Update the desktop with the new bitmap.  This cleans
         * out the system-palette so colors can be realized.
         */
        GreRealizeDefaultPalette(gpDispInfo->hdcScreen, TRUE);

        /*
         * Don't broadcast if system initialization is occuring.  Otherwise
         * this gives the shell first-crack at realizing its colors
         * correctly.
         */
        if (pwndSend) {
            HWND hwnd = HW(pwndSend);

            ThreadLockAlways(pwndSend, &tl);
            xxxSendNotifyMessage(pwndSend, WM_PALETTECHANGED, (WPARAM)hwnd, 0);
            ThreadUnlock(&tl);
        }
    }

Metric_Change:
    if (fRet = GreExtGetObjectW(ghbmWallpaper, sizeof(bm), (PBITMAP)&bm)) {
        gsrcWallpaper.cx = bm.bmWidth;
        gsrcWallpaper.cy = bm.bmHeight;
    }
    // fall-through

SDW_Exit:

    /*
     * Notify the shell-window that the wallpaper changed.
     */
    if ((pwndShell != NULL) &&
        ((hbmOld && !ghbmWallpaper) || (!hbmOld && ghbmWallpaper))) {

        ThreadLockAlways(pwndShell, &tl);
        xxxSendNotifyMessage(pwndShell,
                             WM_SHELLNOTIFY,
                             SHELLNOTIFY_WALLPAPERCHANGED,
                             (LPARAM)ghbmWallpaper);
        ThreadUnlock(&tl);
    }

    return fRet;
}
Example #11
0
BOOL xxxSnapWindow(
    PWND pwnd)
{
    PTHREADINFO    ptiCurrent;
    RECT           rc;
    HDC            hdcScr = NULL;
    HDC            hdcMem = NULL;
    BOOL           fRet;
    HBITMAP        hbmOld;
    HBITMAP        hbm;
    HANDLE         hPal;
    LPLOGPALETTE   lppal;
    int            palsize;
    int            iFixedPaletteEntries;
    BOOL           fSuccess;
    PWND           pwndT;
    TL             tlpwndT;
    PWINDOWSTATION pwinsta;
    TL             tlpwinsta;

    CheckLock(pwnd);
    UserAssert(pwnd);

    ptiCurrent = PtiCurrent();

    /*
     * If this is a thread of winlogon, don't do the snapshot.
     */
    if (GetCurrentProcessId() == gpidLogon)
        return FALSE;

    /*
     * Get the affected windowstation
     */
    if (!NT_SUCCESS(ReferenceWindowStation(
            PsGetCurrentThread(),
            NULL,
            WINSTA_READSCREEN,
            &pwinsta,
            TRUE)) ||
            pwinsta->dwWSF_Flags & WSF_NOIO) {
        return FALSE;
    }

    /*
     * If the window is on another windowstation, do nothing
     */
    if (pwnd->head.rpdesk->rpwinstaParent != pwinsta)
        return FALSE;

    /*
     * Get the parent of any child windows.
     */
    while ((pwnd != NULL) && TestWF(pwnd, WFCHILD)) {
        pwnd = pwnd->spwndParent;
    }

    /*
     * Lock the windowstation before we leave the critical section
     */
    ThreadLockWinSta(ptiCurrent, pwinsta, &tlpwinsta);

    /*
     * Open the clipboard and empty it.
     *
     * pwndDesktop is made the owner of the clipboard, instead of the
     * currently active window; -- SANKAR -- 20th July, 1989 --
     */
    pwndT = ptiCurrent->rpdesk->pDeskInfo->spwnd;
    ThreadLockWithPti(ptiCurrent, pwndT, &tlpwndT);
    fSuccess = xxxOpenClipboard(pwndT, NULL);
    ThreadUnlock(&tlpwndT);

    if (!fSuccess) {
        ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
        return FALSE;
    }

    xxxEmptyClipboard(pwinsta);

    /*
     * Use the whole window.
     */
    CopyRect(&rc, &pwnd->rcWindow);

    /*
     * Only snap what is on the screen.
     */
    if (!IntersectRect(&rc, &rc, &gpDispInfo->rcScreen)) {
        fRet = FALSE;
        goto SnapExit;
    }

    rc.right -= rc.left;
    rc.bottom -= rc.top;

    /*
     * Figure out how far offset from window origin visible part is
     */
    if (pwnd != PWNDDESKTOP(pwnd)) {
        rc.left -= pwnd->rcWindow.left;
        rc.top -= pwnd->rcWindow.top;
    }

    /*
     * Get the entire window's DC.
     */
    hdcScr = _GetWindowDC(pwnd);
    if (!hdcScr)
        goto MemoryError;

    /*
     * Create the memory DC.
     */
    hdcMem = GreCreateCompatibleDC(hdcScr);
    if (!hdcMem)
        goto MemoryError;

    /*
     * Create the destination bitmap.  If it fails, then attempt
     * to create a monochrome bitmap.
     * Did we have enough memory?
     */

    if (SYSMET(SAMEDISPLAYFORMAT)) {
        hbm = GreCreateCompatibleBitmap(hdcScr, rc.right, rc.bottom);
    } else {
        hbm = GreCreateBitmap(rc.right, rc.bottom, 1, gpDispInfo->BitCountMax, NULL);
    }

    if (!hbm) {
        hbm = GreCreateBitmap(rc.right, rc.bottom, 1, 1, NULL);
        if (!hbm)
            goto MemoryError;
    }

    /*
     * Select the bitmap into the memory DC.
     */
    hbmOld = GreSelectBitmap(hdcMem, hbm);

    /*
     * Snap!!!
     * Check the return value because the process taking the snapshot
     * may not have access to read the screen.
     */
    fRet = GreBitBlt(hdcMem, 0, 0, rc.right, rc.bottom, hdcScr, rc.left, rc.top, SRCCOPY | CAPTUREBLT, 0);

    /*
     * Restore the old bitmap into the memory DC.
     */
    GreSelectBitmap(hdcMem, hbmOld);

    /*
     * If the blt failed, leave now.
     */
    if (!fRet)
        goto SnapExit;

    _SetClipboardData(CF_BITMAP, hbm, FALSE, TRUE);

    /*
     * If this is a palette device, let's throw the current system palette
     * into the clipboard also.  Useful if the user just snapped a window
     * containing palette colors...
     */
    if (TEST_PUSIF(PUSIF_PALETTEDISPLAY)) {

        int i;
        int iPalSize;

        palsize = GreGetDeviceCaps(hdcScr, SIZEPALETTE);

        /*
         * Determine the number of system colors.
         */
        if (GreGetSystemPaletteUse(hdcScr) == SYSPAL_STATIC)
            iFixedPaletteEntries = GreGetDeviceCaps(hdcScr, NUMRESERVED);
        else
            iFixedPaletteEntries = 2;

        lppal = (LPLOGPALETTE)UserAllocPoolWithQuota(
                (LONG)(sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * palsize),
                TAG_CLIPBOARD);

        if (lppal != NULL) {
            lppal->palVersion = 0x300;
            lppal->palNumEntries = (WORD)palsize;

            if (GreGetSystemPaletteEntries(hdcScr,
                                           0,
                                           palsize,
                                           lppal->palPalEntry)) {

                iPalSize = palsize - iFixedPaletteEntries / 2;

                for (i = iFixedPaletteEntries / 2; i < iPalSize; i++) {

                    /*
                     * Any non system palette enteries need to have the NOCOLLAPSE
                     * flag set otherwise bitmaps containing different palette
                     * indices but same colors get messed up.
                     */
                    lppal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
                }

                if (hPal = GreCreatePalette(lppal))
                    _SetClipboardData(CF_PALETTE, hPal, FALSE, TRUE);
            }

            UserFreePool(lppal);
        }
    }
    PlayEventSound(USER_SOUND_SNAPSHOT);

    fRet = TRUE;

SnapExit:

    /*
     * Release the window/client DC.
     */
     if (hdcScr) {
         _ReleaseDC(hdcScr);
     }

    xxxCloseClipboard(pwinsta);
    Unlock(&pwinsta->spwndClipOwner);

    /*
     * Delete the memory DC.
     */
    if (hdcMem) {
        GreDeleteDC(hdcMem);
    }

    ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);

    return fRet;

MemoryError:
    /*
     * Display an error message box.
     */
    ClientNoMemoryPopup();
    fRet = FALSE;
    goto SnapExit;
}
Example #12
0
//
// Insert/remove the specified IME hotkey into/from 
// the IME hotkey list (gpImeHotKeyListHeader).
// 
BOOL 
SetImeHotKey(
    DWORD  dwHotKeyID,
    UINT   uModifiers,
    UINT   uVKey,
    HKL    hKL,
    DWORD  dwAction )
{
    PIMEHOTKEYOBJ ph;

    switch ( dwAction ) {
    case ISHK_REMOVE:
        ph = FindImeHotKeyByID( gpImeHotKeyListHeader, dwHotKeyID );
        if ( ph != NULL ) {
            if ( DeleteImeHotKey( &gpImeHotKeyListHeader, ph ) == ph ) {
                UserFreePool( ph );
                return ( TRUE );
            } else {
                RIPMSG0( RIP_ERROR, "IME hotkey list is messed up" );
                return ( FALSE );
            }
        } else { 
            RIPERR0( ERROR_INVALID_PARAMETER, 
                     RIP_WARNING, 
                     "no such IME hotkey registered");
            return ( FALSE );     
        }
        break;

    case ISHK_INITIALIZE:
        ph = gpImeHotKeyListHeader;
        while ( ph != NULL ) {
            PIMEHOTKEYOBJ phNext;

            phNext = ph->pNext;
            UserFreePool( ph );
            ph = phNext;
        }
        gpImeHotKeyListHeader = NULL;
        return TRUE;

    case ISHK_ADD:
        ph = FindImeHotKeyByKey( gpImeHotKeyListHeader,
                                 uModifiers & MOD_MODIFY_KEYS,
                                 uModifiers & MOD_BOTH_SIDES, 
                                 uVKey );
        if ( ph != NULL ) {    
            if ( ph->hk.dwHotKeyID != dwHotKeyID ) {
                RIPERR0( ERROR_HOTKEY_ALREADY_REGISTERED, 
                         RIP_WARNING, 
                         "There is an IME hotkey that has the same vkey/modifiers");
                return ( FALSE );
            } 
            // So far we found a hotkey that has the 
            // same vkey and same ID. 
            // But because modifiers may be slightly 
            // different, so go ahead and change it.
        } else {
            //
            // the specified vkey/modifiers combination cound not be found
            // in the hotkey list. The caller may want to change the key
            // assignment of an existing hotkey or add a new hotkey.
            //
            ph = FindImeHotKeyByID( gpImeHotKeyListHeader, dwHotKeyID );
        }

        if ( ph == NULL ) {         
        //
        // adding a new hotkey
        //
            ph = (PIMEHOTKEYOBJ)UserAllocPool( sizeof(IMEHOTKEY), TAG_IMEHOTKEY );
            if ( ph == NULL ) {
                RIPERR0( ERROR_OUTOFMEMORY,
                         RIP_WARNING,
                        "Memory allocation failed in SetImeHotKey");
                return ( FALSE );
            }
            ph->hk.dwHotKeyID = dwHotKeyID;
            ph->hk.uModifiers = uModifiers;
            ph->hk.uVKey = uVKey;
            ph->hk.hKL = hKL;
            ph->pNext = NULL;
            AddImeHotKey( &gpImeHotKeyListHeader, ph );

        } else {
        //
        // changing an existing hotkey
        //
            ph->hk.uModifiers = uModifiers;
            ph->hk.uVKey = uVKey;
            ph->hk.hKL = hKL;

        }
        return ( TRUE );
        break;
    };
}
Example #13
0
UINT DWP_SetHotKey(
    PWND  pwnd,
    DWORD dwKey)
{
    PHOTKEYSTRUCT phk;
    BOOL          fKeyExists = FALSE;
    PWND          pwndTemp;

    /*
     * Filter out invalid hotkeys
     */
    if (LOBYTE(dwKey) == VK_ESCAPE ||
        LOBYTE(dwKey) == VK_SPACE ||
        LOBYTE(dwKey) == VK_TAB ||
        LOBYTE(dwKey) == VK_PACKET) {

        return (UINT)-1;
    }

    /*
     * Don't allow hotkeys for children
     */
    if (TestWF(pwnd, WFCHILD))
        return 0;

    /*
     * Check if the hot key exists and is assigned to a different pwnd
     */
    if (dwKey != 0) {

        pwndTemp = HotKeyToWindow(dwKey);

        if ((pwndTemp != NULL) && (pwndTemp != pwnd))
            fKeyExists = TRUE;
    }

    /*
     * Get the hotkey assigned to the window, if any
     */
    if ((phk = HotKeyHelper(pwnd)) == NULL) {

        /*
         * Window doesn't exist in the hotkey list and key is being set
         * to zero, so just return.
         */
        if (dwKey == 0)
            return 1;

        /*
         * Allocate and point to a spot for the new hotkey
         */
        if (gcHotKey >= gcHotKeyAlloc) {

            if (gcHotKeyAlloc) {

                phk = (PHOTKEYSTRUCT)UserReAllocPool(
                        (HANDLE)gpHotKeyList,
                        gcHotKeyAlloc * sizeof(HOTKEYSTRUCT),
                        (gcHotKey + 1) * sizeof(HOTKEYSTRUCT), TAG_HOTKEY);

                if (phk != NULL) {

                    gpHotKeyList = phk;
                    phk = &gpHotKeyList[gcHotKey++];
                    gcHotKeyAlloc = gcHotKey;

                } else {

                    return 0;
                }

            } else {

                UserAssert(gpHotKeyList == NULL);
                UserAssert(gcHotKey == 0);

                phk = (PHOTKEYSTRUCT)UserAllocPool(sizeof(HOTKEYSTRUCT),
                                                   TAG_HOTKEY);

                if (phk != NULL) {

                    gpHotKeyList = phk;
                    gcHotKey = 1;
                    gcHotKeyAlloc = 1;

                } else {

                    return 0;
                }
            }

        } else {
            phk = &gpHotKeyList[gcHotKey++];
        }
    }

    if (dwKey == 0) {

        /*
         * The hotkey for this window is being deleted. Copy the last item
         * on the list on top of the one being deleted.
         */
        if (--gcHotKey) {

            Lock(&phk->spwnd, gpHotKeyList[gcHotKey].spwnd);
            Unlock(&gpHotKeyList[gcHotKey].spwnd);

            phk->key = gpHotKeyList[gcHotKey].key;
            phk = (PHOTKEYSTRUCT)UserReAllocPool((HANDLE)gpHotKeyList,
                gcHotKeyAlloc * sizeof(HOTKEYSTRUCT),
                gcHotKey * sizeof(HOTKEYSTRUCT), TAG_HOTKEY);

            if (phk != NULL) {
                gpHotKeyList = phk;
                gcHotKeyAlloc = gcHotKey;
            }

        } else {

            Unlock(&gpHotKeyList[gcHotKey].spwnd);
            UserFreePool((HANDLE)gpHotKeyList);
            gpHotKeyList = NULL;
            gcHotKeyAlloc = 0;
        }

    } else {

        /*
         * Add the window and key to the list
         */
        phk->spwnd = NULL;
        Lock(&phk->spwnd, pwnd);
        phk->key = dwKey;
    }

    return fKeyExists ? 2 : 1;
}