KD System Rewrite:
[reactos.git] / reactos / ntoskrnl / ps / suspend.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ps/suspend.c
6 * PURPOSE: Thread managment
7 *
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 ULONG
18 STDCALL
19 KeResumeThread(PKTHREAD Thread);
20
21 /* FUNCTIONS *****************************************************************/
22
23 /*
24 * FUNCTION: Decrements a thread's resume count
25 * ARGUMENTS:
26 * ThreadHandle = Handle to the thread that should be resumed
27 * ResumeCount = The resulting resume count.
28 * RETURNS: Status
29 */
30 NTSTATUS
31 STDCALL
32 NtResumeThread(IN HANDLE ThreadHandle,
33 IN PULONG SuspendCount OPTIONAL)
34 {
35 PETHREAD Thread;
36 ULONG Prev;
37 KPROCESSOR_MODE PreviousMode;
38 NTSTATUS Status = STATUS_SUCCESS;
39
40 PAGED_CODE();
41
42 PreviousMode = ExGetPreviousMode();
43
44 DPRINT("NtResumeThead(ThreadHandle %lx SuspendCount %p)\n",
45 ThreadHandle, SuspendCount);
46
47 /* Check buffer validity */
48 if(SuspendCount && PreviousMode == UserMode) {
49
50 _SEH_TRY {
51
52 ProbeForWrite(SuspendCount,
53 sizeof(ULONG),
54 sizeof(ULONG));
55 } _SEH_HANDLE {
56
57 Status = _SEH_GetExceptionCode();
58
59 } _SEH_END;
60
61 if(!NT_SUCCESS(Status)) return Status;
62 }
63
64 /* Get the Thread Object */
65 Status = ObReferenceObjectByHandle(ThreadHandle,
66 THREAD_SUSPEND_RESUME,
67 PsThreadType,
68 PreviousMode,
69 (PVOID*)&Thread,
70 NULL);
71 if (!NT_SUCCESS(Status)) {
72
73 return Status;
74 }
75
76 /* Call the Kernel Function */
77 Prev = KeResumeThread(&Thread->Tcb);
78
79 /* Return it */
80 if(SuspendCount) {
81
82 _SEH_TRY {
83
84 *SuspendCount = Prev;
85
86 } _SEH_HANDLE {
87
88 Status = _SEH_GetExceptionCode();
89
90 } _SEH_END;
91 }
92
93 /* Dereference and Return */
94 ObDereferenceObject ((PVOID)Thread);
95 return Status;
96 }
97
98 /*
99 * FUNCTION: Increments a thread's suspend count
100 * ARGUMENTS:
101 * ThreadHandle = Handle to the thread that should be resumed
102 * PreviousSuspendCount = The resulting/previous suspend count.
103 * REMARK:
104 * A thread will be suspended if its suspend count is greater than 0.
105 * This procedure maps to the win32 SuspendThread function. (
106 * documentation about the the suspend count can be found here aswell )
107 * The suspend count is not increased if it is greater than
108 * MAXIMUM_SUSPEND_COUNT.
109 * RETURNS: Status
110 */
111 NTSTATUS
112 STDCALL
113 NtSuspendThread(IN HANDLE ThreadHandle,
114 IN PULONG PreviousSuspendCount OPTIONAL)
115 {
116 PETHREAD Thread;
117 ULONG Prev;
118 KPROCESSOR_MODE PreviousMode;
119 NTSTATUS Status = STATUS_SUCCESS;
120
121 PAGED_CODE();
122
123 PreviousMode = ExGetPreviousMode();
124
125 /* Check buffer validity */
126 if(PreviousSuspendCount && PreviousMode == UserMode) {
127
128 _SEH_TRY {
129
130 ProbeForWrite(PreviousSuspendCount,
131 sizeof(ULONG),
132 sizeof(ULONG));
133 } _SEH_HANDLE {
134
135 Status = _SEH_GetExceptionCode();
136
137 } _SEH_END;
138
139 if(!NT_SUCCESS(Status)) return Status;
140 }
141
142 /* Get the Thread Object */
143 Status = ObReferenceObjectByHandle(ThreadHandle,
144 THREAD_SUSPEND_RESUME,
145 PsThreadType,
146 PreviousMode,
147 (PVOID*)&Thread,
148 NULL);
149 if (!NT_SUCCESS(Status)) {
150
151 return Status;
152 }
153
154 /* Call the Kernel Function */
155 Prev = KeSuspendThread(&Thread->Tcb);
156
157 /* Return it */
158 if(PreviousSuspendCount) {
159
160 _SEH_TRY {
161
162 *PreviousSuspendCount = Prev;
163
164 } _SEH_HANDLE {
165
166 Status = _SEH_GetExceptionCode();
167
168 } _SEH_END;
169 }
170
171 /* Dereference and Return */
172 ObDereferenceObject((PVOID)Thread);
173 return Status;
174 }
175
176 /* EOF */