RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
-
-
- KeInitializeSpinLock(&Desktop->Lock);
InitializeListHead(&Desktop->ShellHookWindows);
Desktop->WindowStation = (PWINSTATION_OBJECT)Parent;
/* Put the desktop on the window station's list of associcated desktops */
- ExInterlockedInsertTailList(
+// ExInterlocked
+ InsertTailList(
&Desktop->WindowStation->DesktopListHead,
- &Desktop->ListEntry,
- &Desktop->WindowStation->Lock);
+ &Desktop->ListEntry);//,
+// &Desktop->WindowStation->Lock);
return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer);
}
IntDesktopObjectDelete(PVOID DeletedObject)
{
PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject;
- KIRQL OldIrql;
DPRINT("Deleting desktop (0x%X)\n", Desktop);
/* Remove the desktop from the window station's list of associcated desktops */
- KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql);
RemoveEntryList(&Desktop->ListEntry);
- KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql);
RtlFreeUnicodeString(&Desktop->Name);
}
/* PRIVATE FUNCTIONS **********************************************************/
+static int GetSystemVersionString(LPWSTR buffer)
+{
+ RTL_OSVERSIONINFOEXW versionInfo;
+ int len;
+
+ versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
+
+ if (!NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW)&versionInfo)))
+ return 0;
+
+ if (versionInfo.dwMajorVersion <= 4)
+ len = swprintf(buffer,
+ L"ReactOS Version %d.%d %s Build %d",
+ versionInfo.dwMajorVersion, versionInfo.dwMinorVersion,
+ versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
+ else
+ len = swprintf(buffer,
+ L"ReactOS %s (Build %d)",
+ versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
+
+ return len;
+}
+
+
NTSTATUS FASTCALL
IntParseDesktopPath(PEPROCESS Process,
PUNICODE_STRING DesktopPath,
#endif
}
+
+
+
+static
+HWND* FASTCALL
+UserBuildShellHookHwndList(PDESKTOP_OBJECT Desktop)
+{
+ ULONG entries=0;
+ PSHELL_HOOK_WINDOW Current;
+ HWND* list;
+
+ /* fixme: if we save nb elements in desktop, we dont have to loop to find nb entries */
+ LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
+ entries++;
+
+ if (!entries) return NULL;
+
+ list = ExAllocatePool(PagedPool, sizeof(HWND) * (entries + 1)); /* alloc one extra for nullterm */
+ if (list)
+ {
+ HWND* cursor = list;
+
+ LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
+ *cursor++ = Current->hWnd;
+
+ *cursor = NULL; /* nullterm list */
+ }
+
+ return list;
+}
+
/*
* Send the Message to the windows registered for ShellHook
* notifications. The lParam contents depend on the Message. See
VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam)
{
PDESKTOP_OBJECT Desktop = IntGetActiveDesktop();
- PLIST_ENTRY Entry, Entry2;
- PSHELL_HOOK_WINDOW Current;
- KIRQL OldLevel;
+ HWND* HwndList;
static UINT MsgType = 0;
return;
}
- /* We have to do some tricks because the list could change
- * between calls, and we can't keep the lock during the call
- */
-
- KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
- Entry = Desktop->ShellHookWindows.Flink;
- while (Entry != &Desktop->ShellHookWindows)
+ HwndList = UserBuildShellHookHwndList(Desktop);
+ if (HwndList)
{
- Current = CONTAINING_RECORD(Entry, SHELL_HOOK_WINDOW, ListEntry);
- KeReleaseSpinLock(&Desktop->Lock, OldLevel);
-
- DPRINT("Sending notify\n");
- co_IntPostOrSendMessage(Current->hWnd,
- MsgType,
- Message,
- lParam);
-
- /* Loop again to find the window we were sending to. If it doesn't
- * exist anymore, we just stop. This could leave an infinite loop
- * if a window is removed and readded to the list. That's quite
- * unlikely though.
- */
-
- KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
- Entry2 = Desktop->ShellHookWindows.Flink;
- while (Entry2 != Entry &&
- Entry2 != &Desktop->ShellHookWindows)
+ HWND* cursor = HwndList;
+
+ for (; *cursor; cursor++)
{
- Entry2 = Entry2->Flink;
+ DPRINT("Sending notify\n");
+ co_IntPostOrSendMessage(*cursor,
+ MsgType,
+ Message,
+ lParam);
}
- if (Entry2 == Entry)
- Entry = Entry->Flink;
- else
- break;
+ ExFreePool(HwndList);
}
- KeReleaseSpinLock(&Desktop->Lock, OldLevel);
+
}
/*
{
PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
PSHELL_HOOK_WINDOW Entry;
- KIRQL OldLevel;
DPRINT("IntRegisterShellHookWindow\n");
*/
IntDeRegisterShellHookWindow(hWnd);
- Entry = ExAllocatePoolWithTag(NonPagedPool,
+ Entry = ExAllocatePoolWithTag(PagedPool,
sizeof(SHELL_HOOK_WINDOW),
TAG_WINSTA);
- /* We have to walk this structure with while holding a spinlock, so we
- * need NonPagedPool */
if (!Entry)
return FALSE;
Entry->hWnd = hWnd;
- KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
InsertTailList(&Desktop->ShellHookWindows, &Entry->ListEntry);
- KeReleaseSpinLock(&Desktop->Lock, OldLevel);
return TRUE;
}
BOOL IntDeRegisterShellHookWindow(HWND hWnd)
{
PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
- PLIST_ENTRY Entry;
PSHELL_HOOK_WINDOW Current;
- KIRQL OldLevel;
-
- KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
- Entry = Desktop->ShellHookWindows.Flink;
- while (Entry != &Desktop->ShellHookWindows)
+ LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
{
- Current = CONTAINING_RECORD(Entry, SHELL_HOOK_WINDOW, ListEntry);
if (Current->hWnd == hWnd)
{
- RemoveEntryList(Entry);
- KeReleaseSpinLock(&Desktop->Lock, OldLevel);
- ExFreePool(Entry);
+ RemoveEntryList(&Current->ListEntry);
+ ExFreePool(Current);
return TRUE;
}
- Entry = Entry->Flink;
}
- KeReleaseSpinLock(&Desktop->Lock, OldLevel);
-
return FALSE;
}
+
+
+
+/* SYSCALLS *******************************************************************/
+
+
/*
* NtUserCreateDesktop
*
CSR_API_MESSAGE Request;
DECLARE_RETURN(HDESK);
- DPRINT("Enter CreateDesktop: %wZ\n", lpszDesktopName);
+ DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
UserEnterExclusive();
Status = IntValidateWindowStationHandle(
PDESKTOP_OBJECT Object;
NTSTATUS Status;
HDESK Desktop;
+ DECLARE_RETURN(HDESK);
+
+ DPRINT("Enter NtUserOpenInputDesktop\n");
+ UserEnterExclusive();
DPRINT("About to open input desktop\n");
if (!NT_SUCCESS(Status))
{
DPRINT("Validation of input desktop handle (0x%X) failed\n", InputDesktop);
- return (HDESK)0;
+ RETURN((HDESK)0);
}
/* Create a new handle to the object */
if (NT_SUCCESS(Status))
{
DPRINT("Successfully opened input desktop\n");
- return (HDESK)Desktop;
+ RETURN((HDESK)Desktop);
}
SetLastNtError(Status);
- return (HDESK)0;
+ RETURN((HDESK)0);
+
+CLEANUP:
+ DPRINT("Leave NtUserOpenInputDesktop, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
/*
{
PDESKTOP_OBJECT Object;
NTSTATUS Status;
+ DECLARE_RETURN(BOOL);
+
+ DPRINT("Enter NtUserCloseDesktop\n");
+ UserEnterExclusive();
DPRINT("About to close desktop handle (0x%X)\n", hDesktop);
if (!NT_SUCCESS(Status))
{
DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
- return FALSE;
+ RETURN(FALSE);
}
ObDereferenceObject(Object);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
- return FALSE;
+ RETURN(FALSE);
}
- return TRUE;
-}
-
-
-static int GetSystemVersionString(LPWSTR buffer)
-{
- RTL_OSVERSIONINFOEXW versionInfo;
- int len;
+ RETURN(TRUE);
- versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
+CLEANUP:
+ DPRINT("Leave NtUserCloseDesktop, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
- if (!NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW)&versionInfo)))
- return 0;
- if (versionInfo.dwMajorVersion <= 4)
- len = swprintf(buffer,
- L"ReactOS Version %d.%d %s Build %d",
- versionInfo.dwMajorVersion, versionInfo.dwMinorVersion,
- versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
- else
- len = swprintf(buffer,
- L"ReactOS %s (Build %d)",
- versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
- return len;
-}
/*
* NtUserPaintDesktop
BOOL doPatBlt = TRUE;
PWINDOW_OBJECT WndDesktop;
int len;
+ DECLARE_RETURN(BOOL);
+
+ UserEnterExclusive();
+ DPRINT("Enter NtUserPaintDesktop\n");
PWINSTATION_OBJECT WinSta = PsGetWin32Thread()->Desktop->WindowStation;
hWndDesktop = IntGetDesktopWindow();
if (!(WndDesktop = UserGetWindowObject(hWndDesktop)))
- return FALSE;
+ RETURN(FALSE);
DesktopBrush = (HBRUSH)IntGetClassLong(WndDesktop, GCL_HBRBACKGROUND, FALSE); //fixme: verify retval
x = (sz.cx / 2) - (WinSta->cxWallpaper / 2);
y = (sz.cy / 2) - (WinSta->cyWallpaper / 2);
- hWallpaperDC = NtGdiCreateCompatableDC(hDC);
+ hWallpaperDC = NtGdiCreateCompatibleDC(hDC);
if(hWallpaperDC != NULL)
{
HBITMAP hOldBitmap;
}
}
- return TRUE;
+ RETURN(TRUE);
+
+CLEANUP:
+ DPRINT("Leave NtUserPaintDesktop, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
{
PDESKTOP_OBJECT DesktopObject;
NTSTATUS Status;
+ DECLARE_RETURN(BOOL);
+
+ UserEnterExclusive();
+ DPRINT("Enter NtUserSwitchDesktop\n");
DPRINT("About to switch desktop (0x%X)\n", hDesktop);
if (!NT_SUCCESS(Status))
{
DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
- return FALSE;
+ RETURN(FALSE);
}
/*
{
ObDereferenceObject(DesktopObject);
DPRINT1("Switching desktop 0x%x denied because the work station is locked!\n", hDesktop);
- return FALSE;
+ RETURN(FALSE);
}
/* FIXME: Fail if the desktop belong to an invisible window station */
ObDereferenceObject(DesktopObject);
- return TRUE;
+ RETURN(TRUE);
+
+CLEANUP:
+ DPRINT("Leave NtUserSwitchDesktop, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
/*
PDESKTOP_OBJECT DesktopObject;
HDESK Ret, hThreadDesktop;
OBJECT_HANDLE_INFORMATION HandleInformation;
+ DECLARE_RETURN(HDESK);
+
+ UserEnterExclusive();
+ DPRINT("Enter NtUserGetThreadDesktop\n");
if(!dwThreadId)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
+ RETURN(0);
}
Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
if(!NT_SUCCESS(Status))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
+ RETURN(0);
}
if(Thread->ThreadsProcess == PsGetCurrentProcess())
{
/* just return the handle, we queried the desktop handle of a thread running
in the same context */
- Ret = Thread->Tcb.Win32Thread->hDesktop;
+ Ret = ((PW32THREAD)Thread->Tcb.Win32Thread)->hDesktop;
ObDereferenceObject(Thread);
- return Ret;
+ RETURN(Ret);
}
/* get the desktop handle and the desktop of the thread */
- if(!(hThreadDesktop = Thread->Tcb.Win32Thread->hDesktop) ||
- !(DesktopObject = Thread->Tcb.Win32Thread->Desktop))
+ if(!(hThreadDesktop = ((PW32THREAD)Thread->Tcb.Win32Thread)->hDesktop) ||
+ !(DesktopObject = ((PW32THREAD)Thread->Tcb.Win32Thread)->Desktop))
{
ObDereferenceObject(Thread);
DPRINT1("Desktop information of thread 0x%x broken!?\n", dwThreadId);
- return NULL;
+ RETURN(NULL);
}
/* we could just use DesktopObject instead of looking up the handle, but latter
if(!NT_SUCCESS(Status))
{
ObDereferenceObject(Thread);
- return NULL;
+ RETURN(NULL);
}
/* lookup our handle table if we can find a handle to the desktop object,
/* all done, we got a valid handle to the desktop */
ObDereferenceObject(DesktopObject);
ObDereferenceObject(Thread);
- return Ret;
+ RETURN(Ret);
+
+CLEANUP:
+ DPRINT("Leave NtUserGetThreadDesktop, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
/*
PW32THREAD W32Thread;
PDESKTOP_OBJECT DesktopObject;
NTSTATUS Status;
-
+ DECLARE_RETURN(BOOL);
+
+ UserEnterExclusive();
+ DPRINT("Enter NtUserSetThreadDesktop\n");
+
/* Validate the new desktop. */
Status = IntValidateDesktopHandle(
hDesktop,
if (!NT_SUCCESS(Status))
{
DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
- return FALSE;
+ RETURN(FALSE);
}
W32Thread = PsGetWin32Thread();
W32Thread->Desktop = DesktopObject;
W32Thread->hDesktop = hDesktop;
- return TRUE;
+ RETURN(TRUE);
+
+CLEANUP:
+ DPRINT("Leave NtUserSetThreadDesktop, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
/* EOF */