NtUserCreateWindowEx函数主要用来创建一个窗口显示。在Win32k.sys里的代码如下:
#001 HWND APIENTRY
#002 NtUserCreateWindowEx(DWORD dwExStyle,
#003 PUNICODE_STRING UnsafeClassName,
#004 PUNICODE_STRING UnsafeWindowName,
#005 DWORD dwStyle,
#006 LONG x,
#007 LONG y,
#008 LONG nWidth,
#009 LONG nHeight,
#010 HWND hWndParent,
#011 HMENU hMenu,
#012 HINSTANCE hInstance,
#013 LPVOID lpParam,
#014 DWORD dwShowMode,
#015 BOOL bUnicodeWindow,
#016 DWORD dwUnknown)
#017 {
#018 NTSTATUS Status;
#019 UNICODE_STRING WindowName;
#020 UNICODE_STRING ClassName;
#021 HWND NewWindow;
#022 DECLARE_RETURN(HWND);
#023
#024 DPRINT("Enter NtUserCreateWindowEx(): (%d,%d-%d,%d)/n", x, y, nWidth, nHeight);
用户界面临界区进入。
#025 UserEnterExclusive();
#026
获取窗口类的名称。
#027 /* Get the class name (string or atom) */
#028 Status = MmCopyFromCaller(&ClassName, UnsafeClassName, sizeof(UNICODE_STRING));
#029 if (! NT_SUCCESS(Status))
#030 {
#031 SetLastNtError(Status);
#032 RETURN( NULL);
#033 }
#034 if (ClassName.Length != 0)
#035 {
#036 Status = IntSafeCopyUnicodeStringTerminateNULL(&ClassName, UnsafeClassName);
#037 if (! NT_SUCCESS(Status))
#038 {
#039 SetLastNtError(Status);
#040 RETURN( NULL);
#041 }
#042 }
#043 else if (! IS_ATOM(ClassName.Buffer))
#044 {
#045 SetLastWin32Error(ERROR_INVALID_PARAMETER);
#046 RETURN(NULL);
#047 }
#048
拷贝窗口的名称。
#049 /* safely copy the window name */
#050 if (NULL != UnsafeWindowName)
#051 {
#052 Status = IntSafeCopyUnicodeString(&WindowName, UnsafeWindowName);
#053 if (! NT_SUCCESS(Status))
#054 {
#055 if (! IS_ATOM(ClassName.Buffer))
#056 {
#057 ExFreePoolWithTag(ClassName.Buffer, TAG_STRING);
#058 }
#059 SetLastNtError(Status);
#060 RETURN( NULL);
#061 }
#062 }
#063 else
#064 {
#065 RtlInitUnicodeString(&WindowName, NULL);
#066 }
#067
调用函数co_IntCreateWindowEx来创建窗口。
#068 NewWindow = co_IntCreateWindowEx(dwExStyle, &ClassName, &WindowName, dwStyle, x, y, nWidth, nHeight,
#069 hWndParent, hMenu, hInstance, lpParam, dwShowMode, bUnicodeWindow);
#070
清空窗口名称和窗口类名称的缓冲区。
#071 if (WindowName.Buffer)
#072 {
#073 ExFreePoolWithTag(WindowName.Buffer, TAG_STRING);
#074 }
#075 if (! IS_ATOM(ClassName.Buffer))
#076 {
#077 ExFreePoolWithTag(ClassName.Buffer, TAG_STRING);
#078 }
#079
返回创建的新窗口。
#080 RETURN( NewWindow);
#081
#082 CLEANUP:
#083 DPRINT("Leave NtUserCreateWindowEx, ret=%i/n",_ret_);
#084 UserLeave();
#085 END_CLEANUP;
#086 }
#087