Пример #1
0
STATIC VOID FreeINI(PXINI pXIni)       // in: profile opened with xprfOpenProfile
{
    if (pXIni)
    {
        PLISTNODE pAppNode = lstQueryFirstNode(&pXIni->llApps);
        while (pAppNode)
        {
            PXINIAPPDATA pAppDataThis = (PXINIAPPDATA)pAppNode->pItemData;

            FreeApp(pAppDataThis);

            pAppNode = pAppNode->pNext;
        }

        lstClear(&pXIni->llApps);
        free(pXIni);
    }
}
Пример #2
0
STATIC VOID FreeApp(PXINIAPPDATA pAppDataThis)
{
    PLISTNODE pKeyNode = lstQueryFirstNode(&pAppDataThis->llKeys);
    while (pKeyNode)
    {
        PXINIKEYDATA pKeyDataThis = (PXINIKEYDATA)pKeyNode->pItemData;

        FreeKey(pKeyDataThis);

        pKeyNode = pKeyNode->pNext;
    }

    if (pAppDataThis->pszAppName)
        free(pAppDataThis->pszAppName);

    lstClear(&pAppDataThis->llKeys);

    free(pAppDataThis);
}
Пример #3
0
STATIC APIRET FindKey(PXINIAPPDATA pAppData,
                      const char *pcszKey,
                      PXINIKEYDATA *ppKeyData)
{
    PLISTNODE pKeyNode = lstQueryFirstNode(&pAppData->llKeys);
    while (pKeyNode)
    {
        PXINIKEYDATA pKeyDataThis = (PXINIKEYDATA)pKeyNode->pItemData;
        if (!strcmp(pKeyDataThis->pszKeyName, pcszKey))
        {
            *ppKeyData = pKeyDataThis;
            return NO_ERROR;
        }

        pKeyNode = pKeyNode->pNext;
    }

    return PRFERR_INVALID_KEY_NAME;
}
Пример #4
0
STATIC APIRET FindApp(PXINI pXIni,           // in: profile opened with xprfOpenProfile
                      const char *pcszApp,
                      PXINIAPPDATA *ppAppData)
{
    PLISTNODE pAppNode = lstQueryFirstNode(&pXIni->llApps);
    while (pAppNode)
    {
        PXINIAPPDATA pAppDataThis = (PXINIAPPDATA)pAppNode->pItemData;
        if (!strcmp(pAppDataThis->pszAppName, pcszApp))
        {
            *ppAppData = pAppDataThis;
            return NO_ERROR;
        }

        pAppNode = pAppNode->pNext;
    }

    return PRFERR_INVALID_APP_NAME;
}
Пример #5
0
BOOL MoveCurrentDesktop(HAB hab,
                        LONG dx,       // in: X delta
                        LONG dy)       // in: Y delta
{
    BOOL    brc = FALSE;

    LONG    cxEach = G_pHookData->szlEachDesktopFaked.cx,
            cDesktopsX = G_pHookData->PagerConfig.cDesktopsX,
            xCurrent = G_pHookData->ptlCurrentDesktop.x,
            xLimit = cDesktopsX * cxEach,
            xNew = xCurrent - dx;

    LONG    cyEach = G_pHookData->szlEachDesktopFaked.cy,
            cDesktopsY = G_pHookData->PagerConfig.cDesktopsY,
            yCurrent = G_pHookData->ptlCurrentDesktop.y,
            yLimit = cDesktopsY * cyEach,
            yNew = yCurrent - dy;

    ULONG   flPager = G_pHookData->PagerConfig.flPager;

    // bump X delta
    if (dx)
    {
        if (xNew < 0)
        {
            if (flPager & PGRFL_WRAPAROUND)
                dx = -((cDesktopsX - 1) * cxEach);
            else
                dx = 0;
        }
        else if ((xNew + cxEach) > xLimit)
        {
            if (flPager & PGRFL_WRAPAROUND)
                dx = (cDesktopsX - 1) * cxEach;
            else
                dx = 0;
        }
    }

    // bump Y delta
    if (dy)
    {
        if (yNew < 0)
        {
            if (flPager & PGRFL_WRAPAROUND)
                dy = -((cDesktopsY - 1) * cyEach);
            else
                dy = 0;
        }
        else if ((yNew + cyEach) > yLimit)
        {
            if (flPager & PGRFL_WRAPAROUND)
                dy = (cDesktopsY - 1) * cyEach;
            else
                dy = 0;
        }
    }

    if (    (dx)
         || (dy)
       )
    {
        BOOL    fAnythingMoved = TRUE;

        PSWP    paswpNew = NULL;
        ULONG   cSwpNewUsed = 0;

        HWND    *pahwndNoMoveWithOwner = NULL;
        ULONG   cNoMoveWithOwner = 0;

        if (pgrLockWinlist())
        {
            // allocate an array of SWP entries for moving all windows
            // at once... we'll allocate one SWP entry for each item
            // on the wininfo list, but we'll probably not use them
            // all. cSwpNewUsed will be incremented for each item that's
            // actually used. While we build that list, we check the
            // internal daemon winlist for sanity, since we sometimes
            // do not pick up all relevant changes such as "parent changed",
            // which will block the WinSetMultWindowPos otherwise.
            ULONG       cWinInfos,
                        cbSwpNew,
                        cbNoMoveWithOwner;

            if (    (cWinInfos = lstCountItems(&G_llWinInfos))
                 && (cbSwpNew = cWinInfos * sizeof(SWP))
                 && (cbNoMoveWithOwner  = cWinInfos * sizeof(HWND))
                 // allocate array of SWPs WinSetMultWindowPos:
                 && (paswpNew = (PSWP)malloc(cbSwpNew))
                 // allocate array of HWNDs for which we
                 // might disable FS_NOMOVEWITHOWNER:
                 && (pahwndNoMoveWithOwner  = (HWND*)malloc(cbNoMoveWithOwner))
               )
            {
                PLISTNODE    pNode, pNext;

                // now go thru all windows on the main list and copy them
                // to the move list, if necessary
                for (pNode = lstQueryFirstNode(&G_llWinInfos); pNode; pNode = pNext)
                {
                    PXWININFO pEntryThis = (PXWININFO)pNode->pItemData;

                    pNext = pNode->pNext;
                    if (    (!WinQueryWindowPos(pEntryThis->data.swctl.hwnd,
                                                &pEntryThis->data.swp))
                            // check if it's still a desktop child (fixes #524)
                         || (WinQueryWindow(pEntryThis->data.swctl.hwnd,QW_PARENT) != G_pHookData->hwndPMDesktop)
                       )
                        // window no longer valid:
                        // remove from the list NOW
                        WinPostMsg(G_pHookData->hwndDaemonObject,
                                   XDM_WINDOWCHANGE,
                                   (MPARAM)pEntryThis->data.swctl.hwnd,
                                   (MPARAM)WM_DESTROY);
                    else
                    {
                        BOOL fRefreshThis = FALSE;

                        // fix outdated minimize/maximize/hide flags
                        if (    (pEntryThis->data.bWindowType == WINDOW_MINIMIZE)
                             && (!(pEntryThis->data.swp.fl & SWP_MINIMIZE))
                           )
                            // no longer minimized:
                            fRefreshThis = TRUE;
                        else if (    (pEntryThis->data.bWindowType == WINDOW_MAXIMIZE)
                                  && (!(pEntryThis->data.swp.fl & SWP_MAXIMIZE))
                                )
                            // no longer minimized:
                            fRefreshThis = TRUE;

                        if (pEntryThis->data.bWindowType == WINDOW_NORMAL)
                        {
                            if (pEntryThis->data.swp.fl & SWP_HIDE)
                                fRefreshThis = TRUE;
                            else if (pEntryThis->data.swp.fl & SWP_MINIMIZE)
                                // now minimized:
                                pEntryThis->data.bWindowType = WINDOW_MINIMIZE;
                            else if (pEntryThis->data.swp.fl & SWP_MAXIMIZE)
                                // now maximized:
                                pEntryThis->data.bWindowType = WINDOW_MAXIMIZE;
                        }

                        if (fRefreshThis)
                        {
                            if (!pgrGetWinData(&pEntryThis->data,
                                               TRUE))       // quick check, we already have most data
                            {
                                // window no longer valid:
                                // remove from the list NOW
                                // V0.9.15 (2001-09-14) [umoeller]
                                WinPostMsg(G_pHookData->hwndDaemonObject,
                                           XDM_WINDOWCHANGE,
                                           (MPARAM)pEntryThis->data.swctl.hwnd,
                                           (MPARAM)WM_DESTROY);

                                // update pEntryThis so that we don't try to
                                // move it later
                                // V0.9.19 (2002-04-04) [lafaix]
                                pEntryThis = NULL;
                            }
                        }

                        // move the window if it is not sticky, minimized,
                        // hidden, or invisible
                        // V0.9.19 (2002-04-04) [lafaix]
                        if (    (pEntryThis)
                             && (    (pEntryThis->data.bWindowType == WINDOW_MAXIMIZE)
                                  || (    (pEntryThis->data.bWindowType == WINDOW_NORMAL)
                                       && (!(pEntryThis->data.swp.fl & SWP_HIDE))
                                     )
                                  || (    (pEntryThis->data.bWindowType == WINDOW_NIL)
                                       && (!(pEntryThis->data.swp.fl & SWP_HIDE))
                                       && (WinQueryWindowULong(pEntryThis->data.swctl.hwnd,
                                                               QWL_STYLE)
                                                   & WS_VISIBLE)
                                     )
                                )
                           )
                        {
                            // OK, window to be moved:

                            // default flags
                            ULONG   fl = SWP_MOVE | SWP_NOADJUST;
                                    // SWP_NOADJUST is required or the windows
                                    // will end up in the middle of nowhere

                            PSWP    pswpNewThis = &paswpNew[cSwpNewUsed];

                            // we have queried the window pos above
                            memcpy(pswpNewThis,
                                   &pEntryThis->data.swp,
                                   sizeof(SWP));

                            pswpNewThis->hwnd = pEntryThis->data.swctl.hwnd;
                            // add the delta for moving
                            pswpNewThis->x += dx;
                            pswpNewThis->y += dy;

                            pswpNewThis->fl = fl;

                            // use next entry in SWP array
                            cSwpNewUsed++;

                            // set FS_NOMOVEWITHOWNER temporarily
                            // (moved this down V1.0.3 (2004-03-11) [umoeller]
                            if (     (!strcmp(pEntryThis->data.szClassName, "#1")
                                  && (!(WinQueryWindowULong(pEntryThis->data.swctl.hwnd, QWL_STYLE)
                                                & FS_NOMOVEWITHOWNER))
                                     )
                               )
                            {
                                pahwndNoMoveWithOwner[cNoMoveWithOwner++] = pEntryThis->data.swctl.hwnd;
                                WinSetWindowBits(pEntryThis->data.swctl.hwnd,
                                                 QWL_STYLE,
                                                 FS_NOMOVEWITHOWNER,
                                                 FS_NOMOVEWITHOWNER);
                            }

                        } // end if (    (pEntryThis->bWindowType == WINDOW_MAXIMIZE)...
                    }
                } // end while (pNode)
            } // end if (paswpNew = (PSWP)malloc(cbSwpNew))) etc.

            if (paswpNew)
            {
                if (cSwpNewUsed)
                {
                    // disable message processing in the hook
                    if (pgrLockHook(__FILE__, __LINE__, __FUNCTION__))
                    {
                        // now set all windows at once, this saves a lot of
                        // repainting...
                        fAnythingMoved = WinSetMultWindowPos(hab,
                                                             paswpNew,
                                                             cSwpNewUsed);
                        pgrUnlockHook();
                    }
                }

                // clean up SWP array
                free(paswpNew);
            } // if (paswpNew)

            // unset FS_NOMOVEWITHOWNER for the windows where we set it above
            while (cNoMoveWithOwner)
                WinSetWindowBits(pahwndNoMoveWithOwner[--cNoMoveWithOwner],
                                 QWL_STYLE,
                                 0,
                                 FS_NOMOVEWITHOWNER);

            pgrUnlockWinlist();
        }

        if (pahwndNoMoveWithOwner)
            free(pahwndNoMoveWithOwner);

        if (fAnythingMoved)
        {
            G_pHookData->ptlCurrentDesktop.x -= dx;
            G_pHookData->ptlCurrentDesktop.y -= dy;

            WinPostMsg(G_pHookData->hwndPagerClient,
                       PGRM_REFRESHCLIENT,
                       (MPARAM)FALSE,
                       0);

            if (flPager & PGRFL_FLASHTOTOP)
                WinSetWindowPos(G_pHookData->hwndPagerFrame,
                                HWND_TOP,
                                0, 0, 0, 0,
                                SWP_ZORDER | SWP_SHOW | SWP_RESTORE);

            brc = TRUE;
        }
    }

    return brc;
}
Пример #6
0
APIRET xprfQueryProfileData(PXINI pXIni,          // in: profile opened with xprfOpenProfile
                            PCSZ pszAppName,      // in: application name
                            PCSZ pszKeyName,      // in: key name or NULL
                            PVOID pBuffer,        // in: buffer to receive data
                            PULONG pulBufferMax)  // in: buffer size, out: size of written data
{
    APIRET  arc = NO_ERROR;
    ULONG   ulDataLen = 0;

    if (!pszAppName)
    {
        PLISTNODE pAppNode = lstQueryFirstNode(&pXIni->llApps);
        PBYTE   pbTarget = (PBYTE)pBuffer;
        ULONG   cbCopied = 0;
        while (pAppNode)
        {
            PXINIAPPDATA pAppDataThis = (PXINIAPPDATA)pAppNode->pItemData;
            ULONG   cbThis = strlen(pAppDataThis->pszAppName) + 1;
            if (cbCopied + cbThis > *pulBufferMax)
                break;
            else
            {
                memcpy(pbTarget + cbCopied,
                       pAppDataThis->pszAppName,
                       cbThis);
                cbCopied += cbThis;
            }

            pAppNode = pAppNode->pNext;
        }

        // extra byte for terminating extra null
        pbTarget[cbCopied] = '\0';
        ulDataLen = cbCopied;       // PMREF says terminating null is not counted
    }
    else
    {
        // app specified:
        PXINIAPPDATA pAppData;

        if (!(arc = FindApp(pXIni,
                            pszAppName,
                            &pAppData)))
        {
            // app exists:

            if (!pszKeyName)
            {
                // app != NULL, but key == NULL:
                // return size of keys list
                PLISTNODE pKeyNode = lstQueryFirstNode(&pAppData->llKeys);
                PBYTE   pbTarget = (PBYTE)pBuffer;
                ULONG   cbCopied = 0;
                while (pKeyNode)
                {
                    PXINIKEYDATA pKeyDataThis = (PXINIKEYDATA)pKeyNode->pItemData;
                    ULONG   cbThis = strlen(pKeyDataThis->pszKeyName) + 1;
                    if (cbCopied + cbThis > *pulBufferMax)
                        break;
                    else
                    {
                        memcpy(pbTarget + cbCopied,
                               pKeyDataThis->pszKeyName,
                               cbThis);
                        cbCopied += cbThis;
                    }

                    pKeyNode = pKeyNode->pNext;
                }

                // extra byte for terminating extra null
                pbTarget[cbCopied] = '\0';
                ulDataLen = cbCopied;       // PMREF says terminating null is not counted
            }
            else
            {
                // both app and key specified:
                PXINIKEYDATA pKeyData;
                if (!(arc = FindKey(pAppData,
                                    pszKeyName,
                                    &pKeyData)))
                {
                    ulDataLen = __min(pKeyData->cbData,
                                    *pulBufferMax);
                    memcpy(pBuffer,
                           pKeyData->pbData,
                           ulDataLen);
                }
            }
        }
    }

    if (pulBufferMax)
        *pulBufferMax = ulDataLen;

    return arc;
}
Пример #7
0
APIRET xprfQueryProfileSize(PXINI pXIni,          // in: profile opened with xprfOpenProfile
                            PCSZ pszAppName,      // in: application name or NULL
                            PCSZ pszKeyName,      // in: key name or NULL
                            PULONG pulDataLen)    // out: size of requested data
{
    APIRET  arc = NO_ERROR;
    ULONG   ulDataLen = 0;

    if (!pszAppName)
    {
        PLISTNODE pAppNode = lstQueryFirstNode(&pXIni->llApps);
        while (pAppNode)
        {
            PXINIAPPDATA pAppDataThis = (PXINIAPPDATA)pAppNode->pItemData;
            ulDataLen += strlen(pAppDataThis->pszAppName) + 1;
            pAppNode = pAppNode->pNext;
        }

        // extra byte for terminating extra null
        ++ulDataLen;
    }
    else
    {
        // app specified:
        PXINIAPPDATA pAppData;

        if (!(arc = FindApp(pXIni,
                            pszAppName,
                            &pAppData)))
        {
            // app exists:

            if (!pszKeyName)
            {
                // app != NULL, but key == NULL:
                // return size of keys list
                PLISTNODE pKeyNode = lstQueryFirstNode(&pAppData->llKeys);
                while (pKeyNode)
                {
                    PXINIKEYDATA pKeyDataThis = (PXINIKEYDATA)pKeyNode->pItemData;
                    ulDataLen += strlen(pKeyDataThis->pszKeyName) + 1;
                    pKeyNode = pKeyNode->pNext;
                }

                // extra byte for terminating extra null
                ++ulDataLen;
            }
            else
            {
                // both app and key specified:
                PXINIKEYDATA pKeyData;
                if (!(arc = FindKey(pAppData,
                                    pszKeyName,
                                    &pKeyData)))
                    ulDataLen = pKeyData->cbData;
            }
        }
    }

    if (pulDataLen)
        *pulDataLen = ulDataLen;

    return arc;
}
Пример #8
0
STATIC APIRET WriteINI(PXINI pXIni)      // in: profile opened with xprfOpenProfile
{
    APIRET  arc = NO_ERROR;
    ULONG   ulTotalFileSize = sizeof(INIFILE_HEADER);
    ULONG   ulSet = 0;
    PBYTE   pbData2Write = NULL;

    // check how much memory we'll need:
    // one INIFILE_HEADER
    // + for each app: one INIFILE_APP plus app name length
    // + for each key: one INIFILE_KEY plus key name length plus data length

    // go thru all apps
    PLISTNODE pAppNode = lstQueryFirstNode(&pXIni->llApps);

    while (pAppNode)
    {
        PLISTNODE pKeyNode;

        PXINIAPPDATA pAppDataThis = (PXINIAPPDATA)pAppNode->pItemData;

        // one INIFILE_APP plus app name length for each app
        ulTotalFileSize +=   sizeof(INIFILE_APP)
                           + strlen(pAppDataThis->pszAppName)
                           + 1;         // null terminator

        // for each app, go thru all keys
        pKeyNode = lstQueryFirstNode(&pAppDataThis->llKeys);
        while (pKeyNode)
        {
            PXINIKEYDATA pKeyDataThis = (PXINIKEYDATA)pKeyNode->pItemData;
            ulTotalFileSize +=   sizeof(INIFILE_KEY)
                               + strlen(pKeyDataThis->pszKeyName)
                               + pKeyDataThis->cbData
                               + 1;         // null terminator

            pKeyNode = pKeyNode->pNext;
        }

        pAppNode = pAppNode->pNext;
    }

    // allocate buffer for total size
    if (pbData2Write = (PBYTE)malloc(ulTotalFileSize))
    {
        // set header in buffer
        PINIFILE_HEADER pHeader = (PINIFILE_HEADER)pbData2Write;
        // pointer into buffer for current write
        // (used below)
        ULONG   ulCurOfs = sizeof(INIFILE_HEADER);

        // 1) set up header

        pHeader->magic = 0xFFFFFFFF;
        if (lstCountItems(&pXIni->llApps))
            // we have any applications:
            pHeader->offFirstApp = sizeof(INIFILE_HEADER);
                     // offset of first application in file
        else
            // empty INI file:
            pHeader->offFirstApp = 0;
        pHeader->lenFile = ulTotalFileSize;
        pHeader->filler1 = 0;
        pHeader->filler2 = 0;

        // 2) for-all-applications loop

        pAppNode = lstQueryFirstNode(&pXIni->llApps);
        while (pAppNode)
        {
            PXINIAPPDATA pAppDataThis = (PXINIAPPDATA)pAppNode->pItemData;
            ULONG       cbAppName = strlen(pAppDataThis->pszAppName) + 1;

            // layout of application entry in file:
            // -- struct PINIFILE_APP       (ulCurOfs right now)
            // -- application name (null-terminated)
            // --   INIFILE_KEY 1
            // --   INIFILE_KEY 2 ...
            // -- next struct PINIFILE_APP

            // make pointer to application entry
            PINIFILE_APP pIniAppCurrent = (PINIFILE_APP)(pbData2Write + ulCurOfs);

            // write out application entry
            // pIniAppCurrent->offNextApp = 0;
            // pIniAppCurrent->offFirstKeyInApp = ulCurOfs + cbAppName;
            pIniAppCurrent->filler1 = 0;
            pIniAppCurrent->lenAppName
                = pIniAppCurrent->_lenAppName
                = cbAppName;
            // set offset to application name: put this right after the application
            ulCurOfs += sizeof(INIFILE_APP);
            pIniAppCurrent->offAppName = ulCurOfs;

            // write app name (null-terminated)
            memcpy(pbData2Write + ulCurOfs,
                   pAppDataThis->pszAppName,
                   cbAppName);
            ulCurOfs += cbAppName;

            // ulCurOfs points to INIFILE_KEY entry now
            if (pAppDataThis->cKeys)
            {
                // we have keys:
                PLISTNODE pKeyNode = lstQueryFirstNode(&pAppDataThis->llKeys);
                pIniAppCurrent->offFirstKeyInApp = ulCurOfs;

                // 3) for-all-keys loop per application

                while (pKeyNode)
                {
                    PXINIKEYDATA pKeyDataThis = (PXINIKEYDATA)pKeyNode->pItemData;
                    ULONG       cbKeyName = strlen(pKeyDataThis->pszKeyName) + 1;

                    PINIFILE_KEY pIniKeyCurrent = (PINIFILE_KEY)(pbData2Write + ulCurOfs);
                    pIniKeyCurrent->filler1 = 0;
                    ulCurOfs += sizeof(INIFILE_KEY);
                            // has offset to key name now

                    // a) key name
                    pIniKeyCurrent->lenKeyName
                        = pIniKeyCurrent->_lenKeyName
                        = cbKeyName;
                    pIniKeyCurrent->offKeyName = ulCurOfs;
                    memcpy(pbData2Write + ulCurOfs,
                           pKeyDataThis->pszKeyName,
                           cbKeyName);
                    ulCurOfs += cbKeyName;
                            // has offset to data now

                    // b) data
                    pIniKeyCurrent->lenKeyData
                        = pIniKeyCurrent->_lenKeyData
                        = pKeyDataThis->cbData;
                    pIniKeyCurrent->offKeyData = ulCurOfs;
                    memcpy(pbData2Write + ulCurOfs,
                           pKeyDataThis->pbData,
                           pKeyDataThis->cbData);
                    ulCurOfs += pKeyDataThis->cbData;
                            // points to after all key data now;
                            // this receives either the next key/data block
                            // or the next application or nothing

                    // ofs of next key:
                    if (pKeyNode->pNext)
                        pIniKeyCurrent->offNextKeyInApp = ulCurOfs;
                    else
                        // last key:
                        pIniKeyCurrent->offNextKeyInApp = 0;

                    pKeyNode = pKeyNode->pNext;
                }

                // ulCurOfs points to after the last keys entry now
            }
            else
                // no keys:
                pIniAppCurrent->offFirstKeyInApp = 0;

            // done with keys (there may be none!);
            // now set offset to next app in current application
            if (pAppNode->pNext)
                pIniAppCurrent->offNextApp = ulCurOfs;
            else
                // this was the last one:
                pIniAppCurrent->offNextApp = 0;

            // next app
            pAppNode = pAppNode->pNext;
        }

        // write out everything
        if (!(arc = DosSetFilePtr(pXIni->hFile,
                                  0,
                                  FILE_BEGIN,
                                  &ulSet)))
        {
            ULONG cbWritten = 0;
            if (!(arc = DosWrite(pXIni->hFile,
                                 pbData2Write,
                                 ulTotalFileSize,
                                 &cbWritten)))
            {
                if (!(arc = DosSetFileSize(pXIni->hFile,
                                           ulTotalFileSize)))
                    ;
            }
        }

        free(pbData2Write);
    }

    return arc;
}