Beispiel #1
0
ULONG_PTR _GetClassData(
    PCLS pcls,
    PWND pwnd,   // used for transition to kernel-mode for GCL_WNDPROC
    int index,
    BOOL bAnsi)
{
    KERNEL_ULONG_PTR dwData;
    DWORD dwCPDType = 0;

    index -= INDEX_OFFSET;

    if (index < 0) {
        RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, "");
        return 0;
    }

    UserAssert(index >= 0);
    UserAssert(index < sizeof(afClassDWord));
    UserAssert(sizeof(afClassDWord) == sizeof(aiClassOffset));
    if (afClassDWord[index] == sizeof(DWORD)) {
        dwData = *(DWORD *)(((BYTE *)pcls) + aiClassOffset[index]);
    } else if (afClassDWord[index] == sizeof(KERNEL_ULONG_PTR)) {
        dwData = *(KERNEL_ULONG_PTR *)(((BYTE *)pcls) + aiClassOffset[index]);
    } else {
        dwData = (DWORD)*(WORD *)(((BYTE *)pcls) + aiClassOffset[index]);
    }

    index += INDEX_OFFSET;

    /*
     * If we're returning an icon or cursor handle, do the reverse
     * mapping here.
     */
    switch(index) {
    case GCLP_MENUNAME:
        if (IS_PTR(pcls->lpszMenuName)) {
            /*
             * The Menu Name is a real string: return the client-side address.
             * (If the class was registered by another app this returns an
             * address in that app's addr. space, but it's the best we can do)
             */
            dwData = bAnsi ?
                    (ULONG_PTR)pcls->lpszClientAnsiMenuName :
                    (ULONG_PTR)pcls->lpszClientUnicodeMenuName;
        }
        break;

    case GCLP_HICON:
    case GCLP_HCURSOR:
    case GCLP_HICONSM:
        /*
         * We have to go to the kernel to convert the pcursor to a handle because
         * cursors are allocated out of POOL, which is not accessable from the client.
         */
        if (dwData) {
            dwData = NtUserCallHwndParam(PtoH(pwnd), index, SFI_GETCLASSICOCUR);
        }
        break;

    case GCLP_WNDPROC:
        {

        /*
         * Always return the client wndproc in case this is a server
         * window class.
         */

        if (pcls->CSF_flags & CSF_SERVERSIDEPROC) {
            dwData = MapServerToClientPfn(dwData, bAnsi);
        } else {
            KERNEL_ULONG_PTR dwT = dwData;

            dwData = MapClientNeuterToClientPfn(pcls, dwT, bAnsi);

            /*
             * If the client mapping didn't change the window proc then see if
             * we need a callproc handle.
             */
            if (dwData == dwT) {
                /*
                 * Need to return a CallProc handle if there is an Ansi/Unicode mismatch
                 */
                if (bAnsi != !!(pcls->CSF_flags & CSF_ANSIPROC)) {
                    dwCPDType |= bAnsi ? CPD_ANSI_TO_UNICODE : CPD_UNICODE_TO_ANSI;
                }
            }
        }

        if (dwCPDType) {
            ULONG_PTR dwCPD;

            dwCPD = GetCPD(pwnd, dwCPDType | CPD_WNDTOCLS, KERNEL_ULONG_PTR_TO_ULONG_PTR(dwData));

            if (dwCPD) {
                dwData = dwCPD;
            } else {
                RIPMSG0(RIP_WARNING, "GetClassLong unable to alloc CPD returning handle\n");
            }
        }
        }
        break;

    case GCL_CBCLSEXTRA:
        if ((pcls->CSF_flags & CSF_WOWCLASS) && (pcls->CSF_flags & CSF_WOWEXTRA)) {
            /*
             * The 16-bit app changed its Extra bytes value.  Return the changed
             * value.  FritzS
             */

            return PWCFromPCLS(pcls)->iClsExtra;
        }
        else
            return pcls->cbclsExtra;

        break;

    /*
     * WOW uses a pointer straight into the class structure.
     */
    case GCLP_WOWWORDS:
        if (pcls->CSF_flags & CSF_WOWCLASS) {
            return ((ULONG_PTR)PWCFromPCLS(pcls));
        } else
            return 0;

    case GCL_STYLE:
        dwData &= CS_VALID;
        break;
    }

    return KERNEL_ULONG_PTR_TO_ULONG_PTR(dwData);
}
Beispiel #2
0
DWORD _GetClassData(
    PCLS pcls,
    PWND pwnd,   // used for transition to kernel-mode for GCL_WNDPROC
    int index,
    BOOL bAnsi)
{
    DWORD dwData;
    DWORD dwCPDType = 0;

    index -= INDEX_OFFSET;

    if (index < 0) {
        RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, "");
        return 0;
    }

    UserAssert(index >= 0);
    UserAssert(index < sizeof(afClassDWord));
    UserAssert(sizeof(afClassDWord) == sizeof(aiClassOffset));
    if (afClassDWord[index]) {
        dwData = *(DWORD *)(((BYTE *)pcls) + aiClassOffset[index]);
    } else {
        dwData = (DWORD)*(WORD *)(((BYTE *)pcls) + aiClassOffset[index]);
    }

    index += INDEX_OFFSET;

    /*
     * If we're returning an icon or cursor handle, do the reverse
     * mapping here.
     */
    switch(index) {
    case GCL_MENUNAME:
        if (pcls->lpszMenuName != MAKEINTRESOURCE(pcls->lpszMenuName)) {
            /*
             * The Menu Name is a real string: return the client-side address.
             * (If the class was registered by another app this returns an
             * address in that app's addr. space, but it's the best we can do)
             */
            dwData = bAnsi ?
                    (DWORD)pcls->lpszClientAnsiMenuName :
                    (DWORD)pcls->lpszClientUnicodeMenuName;
        }
        break;

    case GCL_HICON:
    case GCL_HCURSOR:
    case GCL_HICONSM:
        /*
         * We have to go to the kernel to convert the pcursor to a handle because
         * cursors are allocated out of POOL, which is not accessable from the client.
         */
        if (dwData) {
            dwData = NtUserCallOneParam(dwData, SFI_KERNELPTOH);
        }
        break;

    case GCL_WNDPROC:
        {

        /*
         * Always return the client wndproc in case this is a server
         * window class.
         */

        if (pcls->flags & CSF_SERVERSIDEPROC) {
            dwData = MapServerToClientPfn(dwData, bAnsi);
        } else {
            DWORD dwT = dwData;

            dwData = MapClientNeuterToClientPfn(pcls, dwT, bAnsi);

            /*
             * If the client mapping didn't change the window proc then see if
             * we need a callproc handle.
             */
            if (dwData == dwT) {
                /*
                 * Need to return a CallProc handle if there is an Ansi/Unicode mismatch
                 */
                if (bAnsi != !!(pcls->flags & CSF_ANSIPROC)) {
                    dwCPDType |= bAnsi ? CPD_ANSI_TO_UNICODE : CPD_UNICODE_TO_ANSI;
                }
            }
        }

        if (dwCPDType) {
            DWORD dwCPD;

            dwCPD = GetCPD(pwnd, dwCPDType | CPD_WNDTOCLS, dwData);

            if (dwCPD) {
                dwData = dwCPD;
            } else {
                RIPMSG0(RIP_WARNING, "GetClassLong unable to alloc CPD returning handle\n");
            }
        }
        }
        break;

    /*
     * WOW uses a pointer straight into the class structure.
     */
    case GCL_WOWWORDS:
        return (DWORD) pcls->adwWOW;
    }

    return dwData;
}