⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 class.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
        default:
            SetLastWin32Error(ERROR_INVALID_INDEX);
            break;
    }

    return Ret;
}

static BOOL
UserGetClassInfo(IN PWINDOWCLASS Class,
                 OUT PWNDCLASSEXW lpwcx,
                 IN BOOL Ansi,
                 HINSTANCE hInstance)
{
    PW32PROCESSINFO pi;

    lpwcx->style = Class->Style;

    pi = GetW32ProcessInfo();
    lpwcx->lpfnWndProc = IntGetClassWndProc(Class,
                                            pi,
                                            Ansi,
                                            FALSE);

    lpwcx->cbClsExtra = Class->ClsExtra;
    lpwcx->cbWndExtra = Class->WndExtra;
    lpwcx->hIcon = Class->hIcon; /* FIXME - get handle from pointer */
    lpwcx->hCursor = Class->hCursor; /* FIXME - get handle from pointer */
    lpwcx->hbrBackground = Class->hbrBackground;

    if (Ansi)
        ((PWNDCLASSEXA)lpwcx)->lpszMenuName = Class->AnsiMenuName;
    else
        lpwcx->lpszMenuName = Class->MenuName;

    if (Class->hInstance == pi->hModUser)
        lpwcx->hInstance = NULL;
    else
        lpwcx->hInstance = Class->hInstance;

    lpwcx->lpszClassName = (LPCWSTR)((ULONG_PTR)Class->Atom); /* FIXME - return the string? */

    lpwcx->hIconSm = Class->hIconSm; /* FIXME - get handle from pointer */

    return TRUE;
}

/* SYSCALLS *****************************************************************/


RTL_ATOM NTAPI
NtUserRegisterClassEx(IN CONST WNDCLASSEXW* lpwcx,
                      IN PUNICODE_STRING ClassName,
                      IN PUNICODE_STRING MenuName,
                      IN WNDPROC wpExtra,
                      IN DWORD Flags,
                      IN HMENU hMenu)

/*
 * FUNCTION:
 *   Registers a new class with the window manager
 * ARGUMENTS:
 *   lpwcx          = Win32 extended window class structure
 *   bUnicodeClass = Whether to send ANSI or unicode strings
 *                   to window procedures
 *   wpExtra       = Extra window procedure, if this is not null, its used for the second window procedure for standard controls.
 * RETURNS:
 *   Atom identifying the new class
 */
{
    WNDCLASSEXW CapturedClassInfo = {0};
    UNICODE_STRING CapturedName = {0}, CapturedMenuName = {0};
    RTL_ATOM Ret = (RTL_ATOM)0;

    if (Flags & ~REGISTERCLASS_ALL)
    {
        SetLastWin32Error(ERROR_INVALID_FLAGS);
        return Ret;
    }

    UserEnterExclusive();

    _SEH_TRY
    {
        /* Probe the parameters and basic parameter checks */
        if (ProbeForReadUint(&lpwcx->cbSize) != sizeof(WNDCLASSEXW))
        {
            goto InvalidParameter;
        }

        ProbeForRead(lpwcx,
                     sizeof(WNDCLASSEXW),
                     sizeof(ULONG));
        RtlCopyMemory(&CapturedClassInfo,
                      lpwcx,
                      sizeof(WNDCLASSEXW));

        CapturedName = ProbeForReadUnicodeString(ClassName);
        CapturedMenuName = ProbeForReadUnicodeString(MenuName);

        if (CapturedName.Length & 1 || CapturedMenuName.Length & 1 ||
            CapturedClassInfo.cbClsExtra < 0 ||
            CapturedClassInfo.cbClsExtra + CapturedName.Length +
                CapturedMenuName.Length + sizeof(WINDOWCLASS) < CapturedClassInfo.cbClsExtra ||
            CapturedClassInfo.cbWndExtra < 0 ||
            CapturedClassInfo.hInstance == NULL)
        {
            goto InvalidParameter;
        }

        if (CapturedName.Length != 0)
        {
            ProbeForRead(CapturedName.Buffer,
                         CapturedName.Length,
                         sizeof(WCHAR));
        }
        else
        {
            if (!IS_ATOM(CapturedName.Buffer))
            {
                goto InvalidParameter;
            }
        }

        if (CapturedMenuName.Length != 0)
        {
            ProbeForRead(CapturedMenuName.Buffer,
                         CapturedMenuName.Length,
                         sizeof(WCHAR));
        }
        else if (CapturedMenuName.Buffer != NULL &&
                 !IS_INTRESOURCE(CapturedMenuName.Buffer))
        {
InvalidParameter:
            SetLastWin32Error(ERROR_INVALID_PARAMETER);
            _SEH_LEAVE;
        }

        /* Register the class */
        Ret = UserRegisterClass(&CapturedClassInfo,
                                &CapturedName,
                                &CapturedMenuName,
                                hMenu, /* FIXME - pass pointer */
                                wpExtra,
                                Flags);

    }
    _SEH_HANDLE
    {
        SetLastNtError(_SEH_GetExceptionCode());
    }
    _SEH_END;

    UserLeave();

    return Ret;
}



ULONG_PTR NTAPI
NtUserGetClassLong(IN HWND hWnd,
                   IN INT Offset,
                   IN BOOL Ansi)
{
    PWINDOW_OBJECT Window;
    ULONG_PTR Ret = 0;

    if (Offset != GCLP_WNDPROC)
    {
        UserEnterShared();
    }
    else
    {
        UserEnterExclusive();
    }

    Window = UserGetWindowObject(hWnd);
    if (Window != NULL)
    {
        Ret = UserGetClassLongPtr(Window->Class,
                                  Offset,
                                  Ansi);

        if (Ret != 0 && Offset == GCLP_MENUNAME && Window->Class->MenuNameIsString)
        {
            Ret = (ULONG_PTR)UserHeapAddressToUser((PVOID)Ret);
        }
    }

    UserLeave();

    return Ret;
}



ULONG_PTR STDCALL
NtUserSetClassLong(HWND hWnd,
                   INT Offset,
                   ULONG_PTR dwNewLong,
                   BOOL Ansi)
{
    PW32PROCESSINFO pi;
    PWINDOW_OBJECT Window;
    ULONG_PTR Ret = 0;

    UserEnterExclusive();

    pi = GetW32ProcessInfo();
    if (pi == NULL)
        goto Cleanup;

    Window = UserGetWindowObject(hWnd);
    if (Window != NULL)
    {
        if (Window->ti->kpi != pi)
        {
            SetLastWin32Error(ERROR_ACCESS_DENIED);
            goto Cleanup;
        }

        _SEH_TRY
        {
            UNICODE_STRING Value;

            /* probe the parameters */
            if (Offset == GCW_ATOM || Offset == GCLP_MENUNAME)
            {
                Value = ProbeForReadUnicodeString((PUNICODE_STRING)dwNewLong);
                if (Value.Length & 1)
                {
                    goto InvalidParameter;
                }

                if (Value.Length != 0)
                {
                    ProbeForRead(Value.Buffer,
                                 Value.Length,
                                 sizeof(WCHAR));
                }
                else
                {
                    if (Offset == GCW_ATOM && !IS_ATOM(Value.Buffer))
                    {
                        goto InvalidParameter;
                    }
                    else if (Offset == GCLP_MENUNAME && !IS_INTRESOURCE(Value.Buffer))
                    {
InvalidParameter:
                        SetLastWin32Error(ERROR_INVALID_PARAMETER);
                        _SEH_LEAVE;
                    }
                }

                dwNewLong = (ULONG_PTR)&Value;
            }

            Ret = UserSetClassLongPtr(Window->Class,
                                      Offset,
                                      dwNewLong,
                                      Ansi);
        }
        _SEH_HANDLE
        {
            SetLastNtError(_SEH_GetExceptionCode());
        }
        _SEH_END;
    }

Cleanup:
    UserLeave();

    return Ret;
}

DWORD STDCALL
NtUserSetClassWord(DWORD Unknown0,
                   DWORD Unknown1,
                   DWORD Unknown2)
{
   return(0);
}

BOOL NTAPI
NtUserUnregisterClass(IN PUNICODE_STRING ClassNameOrAtom,
                      IN HINSTANCE hInstance)
{
    UNICODE_STRING CapturedClassName;
    BOOL Ret = FALSE;

    UserEnterExclusive();

    _SEH_TRY
    {
        /* probe the paramters */
        CapturedClassName = ProbeForReadUnicodeString(ClassNameOrAtom);
        if (CapturedClassName.Length & 1)
        {
            goto InvalidParameter;
        }

        if (CapturedClassName.Length != 0)
        {
            ProbeForRead(CapturedClassName.Buffer,
                         CapturedClassName.Length,
                         sizeof(WCHAR));
        }
        else
        {
            if (!IS_ATOM(CapturedClassName.Buffer))
            {
InvalidParameter:
                SetLastWin32Error(ERROR_INVALID_PARAMETER);
                _SEH_LEAVE;
            }
        }

        /* unregister the class */
        Ret = UserUnregisterClass(&CapturedClassName,
                                  hInstance);
    }
    _SEH_HANDLE
    {
        SetLastNtError(_SEH_GetExceptionCode());
    }
    _SEH_END;

    UserLeave();

    return Ret;
}

/* NOTE: for system classes hInstance is not NULL here, but User32Instance */
BOOL STDCALL
NtUserGetClassInfo(
   HINSTANCE hInstance,
   PUNICODE_STRING ClassName,
   LPWNDCLASSEXW lpWndClassEx,
   BOOL Ansi)
{
    UNICODE_STRING CapturedClassName;
    PWINDOWCLASS Class;
    RTL_ATOM ClassAtom;
    PW32PROCESSINFO pi;
    BOOL Ret = FALSE;

    /* NOTE: need exclusive lock because getting the wndproc might require the
             creation of a call procedure handle */
    UserEnterExclusive();

    pi = GetW32ProcessInfo();
    if (pi == NULL)
    {
        ERR("GetW32ProcessInfo() returned NULL!\n");
        goto Cleanup;
    }
    _SEH_TRY
    {
        /* probe the paramters */
        CapturedClassName = ProbeForReadUnicodeString(ClassName);

        if (CapturedClassName.Length == 0)
            TRACE("hInst %p atom %04X lpWndClassEx %p Ansi %d\n", hInstance, CapturedClassName.Buffer, lpWndClassEx, Ansi);
        else
            TRACE("hInst %p class %wZ lpWndClassEx %p Ansi %d\n", hInstance, &CapturedClassName, lpWndClassEx, Ansi);

        if (CapturedClassName.Length & 1)
        {
            goto InvalidParameter;
        }

        if (CapturedClassName.Length != 0)
        {
            ProbeForRead(CapturedClassName.Buffer,
                         CapturedClassName.Length,
                         sizeof(WCHAR));
        }
        else
        {
            if (!IS_ATOM(CapturedClassName.Buffer))
            {
                ERR("NtUserGetClassInfo() got ClassName instead of Atom!\n");
                goto InvalidParameter;
            }
        }

        if (ProbeForReadUint(&lpWndClassEx->cbSize) != sizeof(WNDCLASSEXW))
        {
InvalidParameter:
            SetLastWin32Error(ERROR_INVALID_PARAMETER);
            _SEH_LEAVE;
        }

        ProbeForWrite(lpWndClassEx,
                      sizeof(WNDCLASSEXW),
                      sizeof(ULONG));

        ClassAtom = IntGetClassAtom(&CapturedClassName,
                                    hInstance,
                                    pi,
                                    &Class,
                                    NULL);
        if (ClassAtom != (RTL_ATOM)0)
        {
            if (hInstance == NULL)
                hInstance = pi->hModUser;

            Ret = UserGetClassInfo(Class,
                                   lpWndClassEx,
                                   Ansi,
                                   hInstance);

            if (Ret)
            {
                lpWndClassEx->lpszClassName = CapturedClassName.Buffer;
                /* FIXME - handle Class->Desktop == NULL!!!!! */

                if (Class->MenuName != NULL && Class->MenuNameIsString)
                {
                    lpWndClassEx->lpszMenuName = UserHeapAddressToUser(Ansi ?
                                                                           (PVOID)Class->AnsiMenuName :
                                                                           (PVOID)Class->MenuName);
                }

                /* Undocumented behavior! Return the class atom as a BOOL! */
                Ret = (BOOL)ClassAtom;
            }
         }
         else
         {
            if (CapturedClassName.Length == 0)
               WARN("Tried to get information of a non-existing class atom 0x%p\n", CapturedClassName.Buffer);
            else
               WARN("Tried to get information of a non-existing class \"%wZ\"\n", &CapturedClassName);
            SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
         }
    }
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -