Commit | Line | Data |
---|---|---|
b1bac320 AJ |
1 | /* |
2 | * NT basis DLL | |
9a624916 | 3 | * |
51505b12 | 4 | * This file contains the Rtl* API functions. These should be implementable. |
9a624916 | 5 | * |
51505b12 | 6 | * Copyright 1996-1998 Marcus Meissner |
c83aa0d3 TM |
7 | * Copyright 1999 Alex Korobka |
8 | * Copyright 2003 Thomas Mertes | |
ccf2f616 | 9 | * Crc32 code Copyright 1986 Gary S. Brown (Public domain) |
0799c1a7 AJ |
10 | * |
11 | * This library is free software; you can redistribute it and/or | |
12 | * modify it under the terms of the GNU Lesser General Public | |
13 | * License as published by the Free Software Foundation; either | |
14 | * version 2.1 of the License, or (at your option) any later version. | |
15 | * | |
16 | * This library is distributed in the hope that it will be useful, | |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
19 | * Lesser General Public License for more details. | |
20 | * | |
21 | * You should have received a copy of the GNU Lesser General Public | |
22 | * License along with this library; if not, write to the Free Software | |
360a3f91 | 23 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
b1bac320 AJ |
24 | */ |
25 | ||
ccf2f616 JG |
26 | #include "config.h" |
27 | #include "wine/port.h" | |
28 | ||
b1bac320 | 29 | #include <stdlib.h> |
e37c6e18 | 30 | #include <stdarg.h> |
0aa6cc29 | 31 | #include <stdio.h> |
b1bac320 | 32 | #include <string.h> |
1a1583a3 GG |
33 | #include "ntstatus.h" |
34 | #define WIN32_NO_STATUS | |
d3e22d9d | 35 | #include "windef.h" |
e37c6e18 | 36 | #include "winternl.h" |
40f81e7c | 37 | #include "wine/debug.h" |
769a84fa | 38 | #include "ntdll_misc.h" |
b1bac320 | 39 | |
0799c1a7 | 40 | WINE_DEFAULT_DEBUG_CHANNEL(ntdll); |
b4b9fae6 | 41 | |
6b636e3e MM |
42 | static RTL_CRITICAL_SECTION peb_lock; |
43 | static RTL_CRITICAL_SECTION_DEBUG critsect_debug = | |
19b6a498 AJ |
44 | { |
45 | 0, 0, &peb_lock, | |
46 | { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, | |
20a1a203 | 47 | 0, 0, { (DWORD_PTR)(__FILE__ ": peb_lock") } |
19b6a498 | 48 | }; |
6b636e3e | 49 | static RTL_CRITICAL_SECTION peb_lock = { &critsect_debug, -1, 0, 0, 0, 0 }; |
361943aa | 50 | |
ccf2f616 JG |
51 | /* CRC polynomial 0xedb88320 */ |
52 | static const DWORD CRC_table[256] = | |
53 | { | |
54 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, | |
55 | 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, | |
56 | 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, | |
57 | 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, | |
58 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, | |
59 | 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, | |
60 | 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, | |
61 | 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, | |
62 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, | |
63 | 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, | |
64 | 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, | |
65 | 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, | |
66 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, | |
67 | 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, | |
68 | 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, | |
69 | 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, | |
70 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, | |
71 | 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, | |
72 | 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, | |
73 | 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, | |
74 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, | |
75 | 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, | |
76 | 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, | |
77 | 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, | |
78 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, | |
79 | 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, | |
80 | 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, | |
81 | 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, | |
82 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, | |
83 | 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, | |
84 | 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, | |
85 | 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, | |
86 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, | |
87 | 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, | |
88 | 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, | |
89 | 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, | |
90 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, | |
91 | 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, | |
92 | 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, | |
93 | 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, | |
94 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, | |
95 | 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, | |
96 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d | |
97 | }; | |
98 | ||
026d9db8 JS |
99 | /* |
100 | * resource functions | |
01d6346a | 101 | */ |
f0cbfa0c | 102 | |
6479f0fa | 103 | /*********************************************************************** |
8b216b3d | 104 | * RtlInitializeResource (NTDLL.@) |
6479f0fa AK |
105 | * |
106 | * xxxResource() functions implement multiple-reader-single-writer lock. | |
107 | * The code is based on information published in WDJ January 1999 issue. | |
108 | */ | |
109 | void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl) | |
110 | { | |
111 | if( rwl ) | |
112 | { | |
113 | rwl->iNumberActive = 0; | |
114 | rwl->uExclusiveWaiters = 0; | |
115 | rwl->uSharedWaiters = 0; | |
116 | rwl->hOwningThreadId = 0; | |
117 | rwl->dwTimeoutBoost = 0; /* no info on this one, default value is 0 */ | |
cc9cfdff | 118 | RtlInitializeCriticalSection( &rwl->rtlCS ); |
9dc3843c EP |
119 | NtCreateSemaphore( &rwl->hExclusiveReleaseSemaphore, SEMAPHORE_ALL_ACCESS, NULL, 0, 65535 ); |
120 | NtCreateSemaphore( &rwl->hSharedReleaseSemaphore, SEMAPHORE_ALL_ACCESS, NULL, 0, 65535 ); | |
6479f0fa AK |
121 | } |
122 | } | |
123 | ||
124 | ||
125 | /*********************************************************************** | |
8b216b3d | 126 | * RtlDeleteResource (NTDLL.@) |
6479f0fa AK |
127 | */ |
128 | void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl) | |
129 | { | |
130 | if( rwl ) | |
131 | { | |
cc9cfdff | 132 | RtlEnterCriticalSection( &rwl->rtlCS ); |
6479f0fa | 133 | if( rwl->iNumberActive || rwl->uExclusiveWaiters || rwl->uSharedWaiters ) |
15657090 | 134 | MESSAGE("Deleting active MRSW lock (%p), expect failure\n", rwl ); |
6479f0fa AK |
135 | rwl->hOwningThreadId = 0; |
136 | rwl->uExclusiveWaiters = rwl->uSharedWaiters = 0; | |
137 | rwl->iNumberActive = 0; | |
0aa6cc29 AJ |
138 | NtClose( rwl->hExclusiveReleaseSemaphore ); |
139 | NtClose( rwl->hSharedReleaseSemaphore ); | |
cc9cfdff AJ |
140 | RtlLeaveCriticalSection( &rwl->rtlCS ); |
141 | RtlDeleteCriticalSection( &rwl->rtlCS ); | |
6479f0fa AK |
142 | } |
143 | } | |
144 | ||
145 | ||
146 | /*********************************************************************** | |
8b216b3d | 147 | * RtlAcquireResourceExclusive (NTDLL.@) |
6479f0fa AK |
148 | */ |
149 | BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl, BYTE fWait) | |
150 | { | |
151 | BYTE retVal = 0; | |
152 | if( !rwl ) return 0; | |
153 | ||
154 | start: | |
cc9cfdff | 155 | RtlEnterCriticalSection( &rwl->rtlCS ); |
6479f0fa AK |
156 | if( rwl->iNumberActive == 0 ) /* lock is free */ |
157 | { | |
158 | rwl->iNumberActive = -1; | |
159 | retVal = 1; | |
160 | } | |
161 | else if( rwl->iNumberActive < 0 ) /* exclusive lock in progress */ | |
162 | { | |
7375597f | 163 | if( rwl->hOwningThreadId == (HANDLE)GetCurrentThreadId() ) |
6479f0fa AK |
164 | { |
165 | retVal = 1; | |
166 | rwl->iNumberActive--; | |
167 | goto done; | |
168 | } | |
169 | wait: | |
170 | if( fWait ) | |
171 | { | |
6c45b626 MM |
172 | NTSTATUS status; |
173 | ||
6479f0fa AK |
174 | rwl->uExclusiveWaiters++; |
175 | ||
cc9cfdff | 176 | RtlLeaveCriticalSection( &rwl->rtlCS ); |
6c45b626 MM |
177 | status = NtWaitForSingleObject( rwl->hExclusiveReleaseSemaphore, FALSE, NULL ); |
178 | if( HIWORD(status) ) | |
6479f0fa AK |
179 | goto done; |
180 | goto start; /* restart the acquisition to avoid deadlocks */ | |
181 | } | |
182 | } | |
183 | else /* one or more shared locks are in progress */ | |
184 | if( fWait ) | |
185 | goto wait; | |
9a624916 | 186 | |
6479f0fa | 187 | if( retVal == 1 ) |
7375597f | 188 | rwl->hOwningThreadId = (HANDLE)GetCurrentThreadId(); |
6479f0fa | 189 | done: |
cc9cfdff | 190 | RtlLeaveCriticalSection( &rwl->rtlCS ); |
6479f0fa AK |
191 | return retVal; |
192 | } | |
193 | ||
194 | /*********************************************************************** | |
8b216b3d | 195 | * RtlAcquireResourceShared (NTDLL.@) |
6479f0fa AK |
196 | */ |
197 | BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl, BYTE fWait) | |
198 | { | |
6c45b626 | 199 | NTSTATUS status = STATUS_UNSUCCESSFUL; |
6479f0fa AK |
200 | BYTE retVal = 0; |
201 | if( !rwl ) return 0; | |
202 | ||
203 | start: | |
cc9cfdff | 204 | RtlEnterCriticalSection( &rwl->rtlCS ); |
6479f0fa AK |
205 | if( rwl->iNumberActive < 0 ) |
206 | { | |
7375597f | 207 | if( rwl->hOwningThreadId == (HANDLE)GetCurrentThreadId() ) |
6479f0fa AK |
208 | { |
209 | rwl->iNumberActive--; | |
210 | retVal = 1; | |
211 | goto done; | |
212 | } | |
9a624916 | 213 | |
6479f0fa AK |
214 | if( fWait ) |
215 | { | |
216 | rwl->uSharedWaiters++; | |
cc9cfdff | 217 | RtlLeaveCriticalSection( &rwl->rtlCS ); |
6c45b626 MM |
218 | status = NtWaitForSingleObject( rwl->hSharedReleaseSemaphore, FALSE, NULL ); |
219 | if( HIWORD(status) ) | |
6479f0fa AK |
220 | goto done; |
221 | goto start; | |
222 | } | |
223 | } | |
9a624916 | 224 | else |
6479f0fa | 225 | { |
6c45b626 | 226 | if( status != STATUS_WAIT_0 ) /* otherwise RtlReleaseResource() has already done it */ |
6479f0fa AK |
227 | rwl->iNumberActive++; |
228 | retVal = 1; | |
229 | } | |
230 | done: | |
cc9cfdff | 231 | RtlLeaveCriticalSection( &rwl->rtlCS ); |
6479f0fa AK |
232 | return retVal; |
233 | } | |
234 | ||
235 | ||
236 | /*********************************************************************** | |
8b216b3d | 237 | * RtlReleaseResource (NTDLL.@) |
6479f0fa AK |
238 | */ |
239 | void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl) | |
240 | { | |
cc9cfdff | 241 | RtlEnterCriticalSection( &rwl->rtlCS ); |
6479f0fa AK |
242 | |
243 | if( rwl->iNumberActive > 0 ) /* have one or more readers */ | |
244 | { | |
245 | if( --rwl->iNumberActive == 0 ) | |
246 | { | |
247 | if( rwl->uExclusiveWaiters ) | |
248 | { | |
249 | wake_exclusive: | |
250 | rwl->uExclusiveWaiters--; | |
0aa6cc29 | 251 | NtReleaseSemaphore( rwl->hExclusiveReleaseSemaphore, 1, NULL ); |
6479f0fa AK |
252 | } |
253 | } | |
254 | } | |
9a624916 | 255 | else |
6479f0fa AK |
256 | if( rwl->iNumberActive < 0 ) /* have a writer, possibly recursive */ |
257 | { | |
258 | if( ++rwl->iNumberActive == 0 ) | |
259 | { | |
260 | rwl->hOwningThreadId = 0; | |
261 | if( rwl->uExclusiveWaiters ) | |
262 | goto wake_exclusive; | |
263 | else | |
264 | if( rwl->uSharedWaiters ) | |
265 | { | |
a3960292 | 266 | UINT n = rwl->uSharedWaiters; |
6479f0fa AK |
267 | rwl->iNumberActive = rwl->uSharedWaiters; /* prevent new writers from joining until |
268 | * all queued readers have done their thing */ | |
269 | rwl->uSharedWaiters = 0; | |
0aa6cc29 | 270 | NtReleaseSemaphore( rwl->hSharedReleaseSemaphore, n, NULL ); |
6479f0fa AK |
271 | } |
272 | } | |
273 | } | |
cc9cfdff | 274 | RtlLeaveCriticalSection( &rwl->rtlCS ); |
6479f0fa AK |
275 | } |
276 | ||
277 | ||
278 | /*********************************************************************** | |
8b216b3d | 279 | * RtlDumpResource (NTDLL.@) |
6479f0fa AK |
280 | */ |
281 | void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl) | |
282 | { | |
283 | if( rwl ) | |
284 | { | |
9a624916 | 285 | MESSAGE("RtlDumpResource(%p):\n\tactive count = %i\n\twaiting readers = %i\n\twaiting writers = %i\n", |
6479f0fa AK |
286 | rwl, rwl->iNumberActive, rwl->uSharedWaiters, rwl->uExclusiveWaiters ); |
287 | if( rwl->iNumberActive ) | |
ed800c69 | 288 | MESSAGE("\towner thread = %p\n", rwl->hOwningThreadId ); |
6479f0fa AK |
289 | } |
290 | } | |
291 | ||
026d9db8 JS |
292 | /* |
293 | * misc functions | |
294 | */ | |
3426d853 JS |
295 | |
296 | /****************************************************************************** | |
3ca98239 | 297 | * DbgPrint [NTDLL.@] |
3426d853 | 298 | */ |
43b9f97b | 299 | NTSTATUS WINAPIV DbgPrint(LPCSTR fmt, ...) |
0aa6cc29 | 300 | { |
43b9f97b RJ |
301 | char buf[512]; |
302 | va_list args; | |
a4b80d44 | 303 | |
43b9f97b RJ |
304 | va_start(args, fmt); |
305 | vsprintf(buf,fmt, args); | |
306 | va_end(args); | |
3426d853 | 307 | |
43b9f97b RJ |
308 | MESSAGE("DbgPrint says: %s",buf); |
309 | /* hmm, raise exception? */ | |
310 | return STATUS_SUCCESS; | |
311 | } | |
312 | ||
313 | ||
314 | /****************************************************************************** | |
bf5539bb | 315 | * DbgPrintEx [NTDLL.@] |
43b9f97b RJ |
316 | */ |
317 | NTSTATUS WINAPIV DbgPrintEx(ULONG iComponentId, ULONG Level, LPCSTR fmt, ...) | |
318 | { | |
55ad6cc5 AJ |
319 | NTSTATUS ret; |
320 | va_list args; | |
43b9f97b | 321 | |
55ad6cc5 AJ |
322 | va_start(args, fmt); |
323 | ret = vDbgPrintEx(iComponentId, Level, fmt, args); | |
324 | va_end(args); | |
325 | return ret; | |
326 | } | |
43b9f97b | 327 | |
55ad6cc5 AJ |
328 | /****************************************************************************** |
329 | * vDbgPrintEx [NTDLL.@] | |
330 | */ | |
331 | NTSTATUS WINAPI vDbgPrintEx( ULONG id, ULONG level, LPCSTR fmt, va_list args ) | |
332 | { | |
333 | return vDbgPrintExWithPrefix( "", id, level, fmt, args ); | |
334 | } | |
335 | ||
336 | /****************************************************************************** | |
337 | * vDbgPrintExWithPrefix [NTDLL.@] | |
338 | */ | |
339 | NTSTATUS WINAPI vDbgPrintExWithPrefix( LPCSTR prefix, ULONG id, ULONG level, LPCSTR fmt, va_list args ) | |
340 | { | |
341 | char buf[1024]; | |
342 | ||
343 | vsprintf(buf, fmt, args); | |
344 | ||
345 | switch (level & DPFLTR_MASK) | |
346 | { | |
347 | case DPFLTR_ERROR_LEVEL: ERR("%s%lx: %s", prefix, id, buf); break; | |
348 | case DPFLTR_WARNING_LEVEL: WARN("%s%lx: %s", prefix, id, buf); break; | |
349 | case DPFLTR_TRACE_LEVEL: | |
350 | case DPFLTR_INFO_LEVEL: | |
351 | default: TRACE("%s%lx: %s", prefix, id, buf); break; | |
352 | } | |
353 | return STATUS_SUCCESS; | |
3426d853 | 354 | } |
3426d853 | 355 | |
3426d853 | 356 | /****************************************************************************** |
3ca98239 | 357 | * RtlAcquirePebLock [NTDLL.@] |
3426d853 | 358 | */ |
361943aa AJ |
359 | VOID WINAPI RtlAcquirePebLock(void) |
360 | { | |
361 | RtlEnterCriticalSection( &peb_lock ); | |
3426d853 JS |
362 | } |
363 | ||
364 | /****************************************************************************** | |
3ca98239 | 365 | * RtlReleasePebLock [NTDLL.@] |
3426d853 | 366 | */ |
361943aa AJ |
367 | VOID WINAPI RtlReleasePebLock(void) |
368 | { | |
369 | RtlLeaveCriticalSection( &peb_lock ); | |
3426d853 JS |
370 | } |
371 | ||
3426d853 | 372 | /****************************************************************************** |
3ca98239 | 373 | * RtlNewSecurityObject [NTDLL.@] |
3426d853 | 374 | */ |
46d2886d RR |
375 | NTSTATUS WINAPI |
376 | RtlNewSecurityObject( PSECURITY_DESCRIPTOR ParentDescriptor, | |
377 | PSECURITY_DESCRIPTOR CreatorDescriptor, | |
378 | PSECURITY_DESCRIPTOR *NewDescriptor, | |
379 | BOOLEAN IsDirectoryObject, | |
380 | HANDLE Token, | |
381 | PGENERIC_MAPPING GenericMapping ) | |
382 | { | |
383 | FIXME("(%p %p %p %d %p %p) stub!\n", ParentDescriptor, CreatorDescriptor, | |
384 | NewDescriptor, IsDirectoryObject, Token, GenericMapping); | |
385 | return STATUS_NOT_IMPLEMENTED; | |
3426d853 JS |
386 | } |
387 | ||
388 | /****************************************************************************** | |
3ca98239 | 389 | * RtlDeleteSecurityObject [NTDLL.@] |
3426d853 | 390 | */ |
46d2886d RR |
391 | NTSTATUS WINAPI |
392 | RtlDeleteSecurityObject( PSECURITY_DESCRIPTOR *ObjectDescriptor ) | |
393 | { | |
394 | FIXME("(%p) stub!\n", ObjectDescriptor); | |
395 | return STATUS_NOT_IMPLEMENTED; | |
3426d853 JS |
396 | } |
397 | ||
3426d853 | 398 | /************************************************************************** |
01d5e5b0 | 399 | * _chkstk [NTDLL.@] |
17fd4e38 | 400 | * |
3426d853 JS |
401 | * Glorified "enter xxxx". |
402 | */ | |
f752be84 | 403 | #ifdef __i386__ |
50bbfb3c AJ |
404 | __ASM_GLOBAL_FUNC( _chkstk, |
405 | "negl %eax\n\t" | |
406 | "addl %esp,%eax\n\t" | |
407 | "xchgl %esp,%eax\n\t" | |
408 | "movl 0(%eax),%eax\n\t" /* copy return address from old location */ | |
409 | "movl %eax,0(%esp)\n\t" | |
410 | "ret" ); | |
f752be84 | 411 | #endif |
17fd4e38 PS |
412 | |
413 | /************************************************************************** | |
01d5e5b0 | 414 | * _alloca_probe [NTDLL.@] |
17fd4e38 PS |
415 | * |
416 | * Glorified "enter xxxx". | |
417 | */ | |
f752be84 | 418 | #ifdef __i386__ |
50bbfb3c AJ |
419 | __ASM_GLOBAL_FUNC( _alloca_probe, |
420 | "negl %eax\n\t" | |
421 | "addl %esp,%eax\n\t" | |
422 | "xchgl %esp,%eax\n\t" | |
423 | "movl 0(%eax),%eax\n\t" /* copy return address from old location */ | |
424 | "movl %eax,0(%esp)\n\t" | |
425 | "ret" ); | |
f752be84 AJ |
426 | #endif |
427 | ||
3426d853 | 428 | |
9f50d049 | 429 | /****************************************************************************** |
ccf2f616 | 430 | * RtlInitializeGenericTable [NTDLL.@] |
9f50d049 | 431 | */ |
ccf2f616 | 432 | PVOID WINAPI RtlInitializeGenericTable(PVOID pTable, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5) |
9f50d049 | 433 | { |
ccf2f616 JG |
434 | FIXME("(%p,%p,%p,%p,%p) stub!\n", pTable, arg2, arg3, arg4, arg5); |
435 | return NULL; | |
9a624916 | 436 | } |
9f50d049 JS |
437 | |
438 | /****************************************************************************** | |
3ca98239 | 439 | * RtlMoveMemory [NTDLL.@] |
ccf2f616 JG |
440 | * |
441 | * Move a block of memory that may overlap. | |
442 | * | |
443 | * PARAMS | |
444 | * Destination [O] End destination for block | |
445 | * Source [O] Where to start copying from | |
446 | * Length [I] Number of bytes to copy | |
447 | * | |
448 | * RETURNS | |
449 | * Nothing. | |
9f50d049 JS |
450 | */ |
451 | #undef RtlMoveMemory | |
452 | VOID WINAPI RtlMoveMemory( VOID *Destination, CONST VOID *Source, SIZE_T Length ) | |
453 | { | |
454 | memmove(Destination, Source, Length); | |
455 | } | |
456 | ||
457 | /****************************************************************************** | |
3ca98239 | 458 | * RtlFillMemory [NTDLL.@] |
ccf2f616 JG |
459 | * |
460 | * Set a block of memory with a value. | |
461 | * | |
462 | * PARAMS | |
463 | * Destination [O] Block to fill | |
464 | * Length [I] Number of bytes to fill | |
465 | * Fill [I] Value to set | |
466 | * | |
467 | * RETURNS | |
468 | * Nothing. | |
9f50d049 JS |
469 | */ |
470 | #undef RtlFillMemory | |
471 | VOID WINAPI RtlFillMemory( VOID *Destination, SIZE_T Length, BYTE Fill ) | |
472 | { | |
473 | memset(Destination, Fill, Length); | |
474 | } | |
475 | ||
476 | /****************************************************************************** | |
3ca98239 | 477 | * RtlZeroMemory [NTDLL.@] |
ccf2f616 JG |
478 | * |
479 | * Set a block of memory with 0's. | |
480 | * | |
481 | * PARAMS | |
482 | * Destination [O] Block to fill | |
483 | * Length [I] Number of bytes to fill | |
484 | * | |
485 | * RETURNS | |
486 | * Nothing. | |
9f50d049 JS |
487 | */ |
488 | #undef RtlZeroMemory | |
489 | VOID WINAPI RtlZeroMemory( VOID *Destination, SIZE_T Length ) | |
490 | { | |
491 | memset(Destination, 0, Length); | |
492 | } | |
493 | ||
494 | /****************************************************************************** | |
3ca98239 | 495 | * RtlCompareMemory [NTDLL.@] |
ccf2f616 JG |
496 | * |
497 | * Compare one block of memory with another | |
498 | * | |
499 | * PARAMS | |
500 | * Source1 [I] Source block | |
501 | * Source2 [I] Block to compare to Source1 | |
bf5539bb | 502 | * Length [I] Number of bytes to compare |
ccf2f616 JG |
503 | * |
504 | * RETURNS | |
505 | * The length of the first byte at which Source1 and Source2 differ, or Length | |
506 | * if they are the same. | |
9f50d049 JS |
507 | */ |
508 | SIZE_T WINAPI RtlCompareMemory( const VOID *Source1, const VOID *Source2, SIZE_T Length) | |
509 | { | |
ccf2f616 | 510 | SIZE_T i; |
db525887 | 511 | for(i=0; (i<Length) && (((const BYTE*)Source1)[i]==((const BYTE*)Source2)[i]); i++); |
9f50d049 JS |
512 | return i; |
513 | } | |
514 | ||
ccf2f616 JG |
515 | /****************************************************************************** |
516 | * RtlCompareMemoryUlong [NTDLL.@] | |
517 | * | |
518 | * Compare a block of memory with a value, a ULONG at a time | |
519 | * | |
520 | * PARAMS | |
521 | * Source1 [I] Source block. This must be ULONG aligned | |
522 | * Length [I] Number of bytes to compare. This should be a multiple of 4 | |
523 | * dwVal [I] Value to compare to | |
524 | * | |
525 | * RETURNS | |
526 | * The byte position of the first byte at which Source1 is not dwVal. | |
527 | */ | |
528 | SIZE_T WINAPI RtlCompareMemoryUlong(const ULONG *Source1, SIZE_T Length, ULONG dwVal) | |
529 | { | |
530 | SIZE_T i; | |
531 | for(i = 0; i < Length/sizeof(ULONG) && Source1[i] == dwVal; i++); | |
532 | return i * sizeof(ULONG); | |
533 | } | |
534 | ||
63e8bd5d | 535 | /****************************************************************************** |
3ca98239 | 536 | * RtlAssert [NTDLL.@] |
63e8bd5d | 537 | * |
ccf2f616 JG |
538 | * Fail a debug assertion. |
539 | * | |
540 | * RETURNS | |
541 | * Nothing. This call does not return control to its caller. | |
542 | * | |
543 | * NOTES | |
63e8bd5d AM |
544 | * Not implemented in non-debug versions. |
545 | */ | |
546 | void WINAPI RtlAssert(LPVOID x1,LPVOID x2,DWORD x3, DWORD x4) | |
547 | { | |
548 | FIXME("(%p,%p,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4); | |
549 | } | |
08be8f06 | 550 | |
1da29717 JG |
551 | /************************************************************************* |
552 | * RtlFillMemoryUlong [NTDLL.@] | |
553 | * | |
554 | * Fill memory with a 32 bit (dword) value. | |
555 | * | |
556 | * PARAMS | |
557 | * lpDest [I] Bitmap pointer | |
558 | * ulCount [I] Number of dwords to write | |
559 | * ulValue [I] Value to fill with | |
560 | * | |
561 | * RETURNS | |
562 | * Nothing. | |
563 | */ | |
564 | VOID WINAPI RtlFillMemoryUlong(ULONG* lpDest, ULONG ulCount, ULONG ulValue) | |
565 | { | |
566 | TRACE("(%p,%ld,%ld)\n", lpDest, ulCount, ulValue); | |
567 | ||
ccf2f616 | 568 | ulCount /= sizeof(ULONG); |
1da29717 JG |
569 | while(ulCount--) |
570 | *lpDest++ = ulValue; | |
571 | } | |
572 | ||
ccf2f616 JG |
573 | /********************************************************************* |
574 | * RtlComputeCrc32 [NTDLL.@] | |
575 | * | |
576 | * Calculate the CRC32 checksum of a block of bytes | |
577 | * | |
578 | * PARAMS | |
579 | * dwInitial [I] Initial CRC value | |
580 | * pData [I] Data block | |
581 | * iLen [I] Length of the byte block | |
582 | * | |
583 | * RETURNS | |
584 | * The cumulative CRC32 of dwInitial and iLen bytes of the pData block. | |
585 | */ | |
586 | DWORD WINAPI RtlComputeCrc32(DWORD dwInitial, PBYTE pData, INT iLen) | |
587 | { | |
588 | DWORD crc = ~dwInitial; | |
589 | ||
590 | TRACE("(%ld,%p,%d)\n", dwInitial, pData, iLen); | |
591 | ||
592 | while (iLen > 0) | |
593 | { | |
594 | crc = CRC_table[(crc ^ *pData) & 0xff] ^ (crc >> 8); | |
595 | pData++; | |
596 | iLen--; | |
597 | } | |
598 | return ~crc; | |
599 | } | |
6da4c275 AJ |
600 | |
601 | ||
602 | /************************************************************************* | |
603 | * RtlUlonglongByteSwap [NTDLL.@] | |
604 | * | |
605 | * Swap the bytes of an unsigned long long value. | |
606 | * | |
607 | * PARAMS | |
608 | * i [I] Value to swap bytes of | |
609 | * | |
610 | * RETURNS | |
611 | * The value with its bytes swapped. | |
612 | */ | |
613 | ULONGLONG __cdecl RtlUlonglongByteSwap(ULONGLONG i) | |
614 | { | |
615 | return ((ULONGLONG)RtlUlongByteSwap(i) << 32) | RtlUlongByteSwap(i>>32); | |
616 | } | |
617 | ||
618 | /************************************************************************* | |
619 | * RtlUlongByteSwap [NTDLL.@] | |
620 | * | |
621 | * Swap the bytes of an unsigned int value. | |
622 | * | |
623 | * NOTES | |
624 | * ix86 version takes argument in %ecx. Other systems use the inline version. | |
625 | */ | |
626 | #ifdef __i386__ | |
a9bedef3 | 627 | __ASM_GLOBAL_FUNC(NTDLL_RtlUlongByteSwap, |
6da4c275 AJ |
628 | "movl %ecx,%eax\n\t" |
629 | "bswap %eax\n\t" | |
630 | "ret"); | |
631 | #endif | |
632 | ||
633 | /************************************************************************* | |
634 | * RtlUshortByteSwap [NTDLL.@] | |
635 | * | |
636 | * Swap the bytes of an unsigned short value. | |
637 | * | |
638 | * NOTES | |
639 | * i386 version takes argument in %cx. Other systems use the inline version. | |
640 | */ | |
641 | #ifdef __i386__ | |
a9bedef3 | 642 | __ASM_GLOBAL_FUNC(NTDLL_RtlUshortByteSwap, |
6da4c275 AJ |
643 | "movb %ch,%al\n\t" |
644 | "movb %cl,%ah\n\t" | |
645 | "ret"); | |
646 | #endif | |
c83aa0d3 TM |
647 | |
648 | ||
649 | /************************************************************************* | |
650 | * RtlUniform [NTDLL.@] | |
651 | * | |
652 | * Generates an uniform random number | |
653 | * | |
654 | * PARAMS | |
655 | * seed [O] The seed of the Random function | |
656 | * | |
657 | * RETURNS | |
0ce4826e | 658 | * It returns a random number uniformly distributed over [0..MAXLONG-1]. |
c83aa0d3 TM |
659 | * |
660 | * NOTES | |
0ce4826e TM |
661 | * Generates an uniform random number using D.H. Lehmer's 1948 algorithm. |
662 | * In our case the algorithm is: | |
663 | * | |
bf5539bb JG |
664 | *| result = (*seed * 0x7fffffed + 0x7fffffc3) % MAXLONG; |
665 | *| | |
666 | *| *seed = result; | |
0ce4826e TM |
667 | * |
668 | * DIFFERENCES | |
669 | * The native documentation states that the random number is | |
670 | * uniformly distributed over [0..MAXLONG]. In reality the native | |
671 | * function and our function return a random number uniformly | |
672 | * distributed over [0..MAXLONG-1]. | |
c83aa0d3 TM |
673 | */ |
674 | ULONG WINAPI RtlUniform (PULONG seed) | |
675 | { | |
676 | ULONG result; | |
677 | ||
0ce4826e TM |
678 | /* |
679 | * Instead of the algorithm stated above, we use the algorithm | |
680 | * below, which is totally equivalent (see the tests), but does | |
681 | * not use a division and therefore is faster. | |
682 | */ | |
c83aa0d3 TM |
683 | result = *seed * 0xffffffed + 0x7fffffc3; |
684 | if (result == 0xffffffff || result == 0x7ffffffe) { | |
685 | result = (result + 2) & MAXLONG; | |
686 | } else if (result == 0x7fffffff) { | |
0ce4826e | 687 | result = 0; |
c83aa0d3 TM |
688 | } else if ((result & 0x80000000) == 0) { |
689 | result = result + (~result & 1); | |
690 | } else { | |
691 | result = (result + (result & 1)) & MAXLONG; | |
692 | } /* if */ | |
693 | *seed = result; | |
694 | return result; | |
695 | } | |
0ce4826e TM |
696 | |
697 | ||
698 | /************************************************************************* | |
699 | * RtlRandom [NTDLL.@] | |
700 | * | |
701 | * Generates a random number | |
702 | * | |
703 | * PARAMS | |
704 | * seed [O] The seed of the Random function | |
705 | * | |
706 | * RETURNS | |
707 | * It returns a random number distributed over [0..MAXLONG-1]. | |
708 | */ | |
709 | ULONG WINAPI RtlRandom (PULONG seed) | |
710 | { | |
711 | static ULONG saved_value[128] = | |
712 | { /* 0 */ 0x4c8bc0aa, 0x4c022957, 0x2232827a, 0x2f1e7626, 0x7f8bdafb, 0x5c37d02a, 0x0ab48f72, 0x2f0c4ffa, | |
713 | /* 8 */ 0x290e1954, 0x6b635f23, 0x5d3885c0, 0x74b49ff8, 0x5155fa54, 0x6214ad3f, 0x111e9c29, 0x242a3a09, | |
714 | /* 16 */ 0x75932ae1, 0x40ac432e, 0x54f7ba7a, 0x585ccbd5, 0x6df5c727, 0x0374dad1, 0x7112b3f1, 0x735fc311, | |
715 | /* 24 */ 0x404331a9, 0x74d97781, 0x64495118, 0x323e04be, 0x5974b425, 0x4862e393, 0x62389c1d, 0x28a68b82, | |
716 | /* 32 */ 0x0f95da37, 0x7a50bbc6, 0x09b0091c, 0x22cdb7b4, 0x4faaed26, 0x66417ccd, 0x189e4bfa, 0x1ce4e8dd, | |
717 | /* 40 */ 0x5274c742, 0x3bdcf4dc, 0x2d94e907, 0x32eac016, 0x26d33ca3, 0x60415a8a, 0x31f57880, 0x68c8aa52, | |
718 | /* 48 */ 0x23eb16da, 0x6204f4a1, 0x373927c1, 0x0d24eb7c, 0x06dd7379, 0x2b3be507, 0x0f9c55b1, 0x2c7925eb, | |
719 | /* 56 */ 0x36d67c9a, 0x42f831d9, 0x5e3961cb, 0x65d637a8, 0x24bb3820, 0x4d08e33d, 0x2188754f, 0x147e409e, | |
720 | /* 64 */ 0x6a9620a0, 0x62e26657, 0x7bd8ce81, 0x11da0abb, 0x5f9e7b50, 0x23e444b6, 0x25920c78, 0x5fc894f0, | |
721 | /* 72 */ 0x5e338cbb, 0x404237fd, 0x1d60f80f, 0x320a1743, 0x76013d2b, 0x070294ee, 0x695e243b, 0x56b177fd, | |
722 | /* 80 */ 0x752492e1, 0x6decd52f, 0x125f5219, 0x139d2e78, 0x1898d11e, 0x2f7ee785, 0x4db405d8, 0x1a028a35, | |
723 | /* 88 */ 0x63f6f323, 0x1f6d0078, 0x307cfd67, 0x3f32a78a, 0x6980796c, 0x462b3d83, 0x34b639f2, 0x53fce379, | |
724 | /* 96 */ 0x74ba50f4, 0x1abc2c4b, 0x5eeaeb8d, 0x335a7a0d, 0x3973dd20, 0x0462d66b, 0x159813ff, 0x1e4643fd, | |
725 | /* 104 */ 0x06bc5c62, 0x3115e3fc, 0x09101613, 0x47af2515, 0x4f11ec54, 0x78b99911, 0x3db8dd44, 0x1ec10b9b, | |
726 | /* 112 */ 0x5b5506ca, 0x773ce092, 0x567be81a, 0x5475b975, 0x7a2cde1a, 0x494536f5, 0x34737bb4, 0x76d9750b, | |
727 | /* 120 */ 0x2a1f6232, 0x2e49644d, 0x7dddcbe7, 0x500cebdb, 0x619dab9e, 0x48c626fe, 0x1cda3193, 0x52dabe9d }; | |
728 | ULONG rand; | |
729 | int pos; | |
730 | ULONG result; | |
731 | ||
732 | rand = (*seed * 0x7fffffed + 0x7fffffc3) % 0x7fffffff; | |
733 | *seed = (rand * 0x7fffffed + 0x7fffffc3) % 0x7fffffff; | |
734 | pos = *seed & 0x7f; | |
735 | result = saved_value[pos]; | |
736 | saved_value[pos] = rand; | |
737 | return(result); | |
738 | } | |
739 | ||
740 | ||
741 | /************************************************************************* | |
742 | * RtlAreAllAccessesGranted [NTDLL.@] | |
743 | * | |
744 | * Check if all desired accesses are granted | |
745 | * | |
746 | * RETURNS | |
747 | * TRUE: All desired accesses are granted | |
748 | * FALSE: Otherwise | |
749 | */ | |
750 | BOOLEAN WINAPI RtlAreAllAccessesGranted( | |
751 | ACCESS_MASK GrantedAccess, | |
752 | ACCESS_MASK DesiredAccess) | |
753 | { | |
754 | return (GrantedAccess & DesiredAccess) == DesiredAccess; | |
755 | } | |
756 | ||
757 | ||
758 | /************************************************************************* | |
759 | * RtlAreAnyAccessesGranted [NTDLL.@] | |
760 | * | |
761 | * Check if at least one of the desired accesses is granted | |
762 | * | |
bf5539bb JG |
763 | * PARAMS |
764 | * GrantedAccess [I] Access mask of granted accesses | |
765 | * DesiredAccess [I] Access mask of desired accesses | |
766 | * | |
0ce4826e TM |
767 | * RETURNS |
768 | * TRUE: At least one of the desired accesses is granted | |
769 | * FALSE: Otherwise | |
770 | */ | |
771 | BOOLEAN WINAPI RtlAreAnyAccessesGranted( | |
772 | ACCESS_MASK GrantedAccess, | |
773 | ACCESS_MASK DesiredAccess) | |
774 | { | |
775 | return (GrantedAccess & DesiredAccess) != 0; | |
776 | } | |
777 | ||
778 | ||
779 | /************************************************************************* | |
780 | * RtlMapGenericMask [NTDLL.@] | |
781 | * | |
782 | * Determine the nongeneric access rights specified by an access mask | |
783 | * | |
784 | * RETURNS | |
785 | * Nothing. | |
786 | */ | |
787 | void WINAPI RtlMapGenericMask( | |
788 | PACCESS_MASK AccessMask, | |
789 | const GENERIC_MAPPING *GenericMapping) | |
790 | { | |
791 | if (*AccessMask & GENERIC_READ) { | |
792 | *AccessMask |= GenericMapping->GenericRead; | |
793 | } /* if */ | |
794 | ||
795 | if (*AccessMask & GENERIC_WRITE) { | |
796 | *AccessMask |= GenericMapping->GenericWrite; | |
797 | } /* if */ | |
798 | ||
799 | if (*AccessMask & GENERIC_EXECUTE) { | |
800 | *AccessMask |= GenericMapping->GenericExecute; | |
801 | } /* if */ | |
802 | ||
803 | if (*AccessMask & GENERIC_ALL) { | |
804 | *AccessMask |= GenericMapping->GenericAll; | |
805 | } /* if */ | |
806 | ||
807 | *AccessMask &= 0x0FFFFFFF; | |
808 | } | |
809 | ||
810 | ||
811 | /************************************************************************* | |
812 | * RtlCopyLuid [NTDLL.@] | |
813 | * | |
bf5539bb JG |
814 | * Copy a local unique ID. |
815 | * | |
816 | * PARAMS | |
817 | * LuidDest [O] Destination for the copied Luid | |
818 | * LuidSrc [I] Source Luid to copy to LuidDest | |
0ce4826e TM |
819 | * |
820 | * RETURNS | |
821 | * Nothing. | |
822 | */ | |
823 | void WINAPI RtlCopyLuid (PLUID LuidDest, const LUID *LuidSrc) | |
824 | { | |
825 | *LuidDest = *LuidSrc; | |
826 | } | |
827 | ||
828 | ||
829 | /************************************************************************* | |
830 | * RtlEqualLuid [NTDLL.@] | |
831 | * | |
bf5539bb JG |
832 | * Compare two local unique ID's. |
833 | * | |
834 | * PARAMS | |
835 | * Luid1 [I] First Luid to compare to Luid2 | |
836 | * Luid2 [I] Second Luid to compare to Luid1 | |
0ce4826e TM |
837 | * |
838 | * RETURNS | |
839 | * TRUE: The two LUID's are equal. | |
840 | * FALSE: Otherwise | |
841 | */ | |
842 | BOOLEAN WINAPI RtlEqualLuid (const LUID *Luid1, const LUID *Luid2) | |
843 | { | |
844 | return (Luid1->LowPart == Luid2->LowPart && Luid1->HighPart == Luid2->HighPart); | |
845 | } | |
846 | ||
847 | ||
848 | /************************************************************************* | |
849 | * RtlCopyLuidAndAttributesArray [NTDLL.@] | |
850 | * | |
bf5539bb JG |
851 | * Copy an array of local unique ID's and attributes. |
852 | * | |
853 | * PARAMS | |
854 | * Count [I] Number of Luid/attributes in Src | |
855 | * Src [I] Source Luid/attributes to copy | |
856 | * Dest [O] Destination for copied Luid/attributes | |
0ce4826e TM |
857 | * |
858 | * RETURNS | |
859 | * Nothing. | |
bf5539bb JG |
860 | * |
861 | * NOTES | |
862 | * Dest must be large enough to hold Src. | |
0ce4826e TM |
863 | */ |
864 | void WINAPI RtlCopyLuidAndAttributesArray( | |
865 | ULONG Count, | |
866 | const LUID_AND_ATTRIBUTES *Src, | |
867 | PLUID_AND_ATTRIBUTES Dest) | |
868 | { | |
869 | ULONG i; | |
870 | ||
871 | for (i = 0; i < Count; i++) Dest[i] = Src[i]; | |
872 | } | |
e21aff07 JD |
873 | |
874 | NTSTATUS WINAPI RtlIpv4StringToAddressExW(PULONG IP, PULONG Port, | |
875 | LPCWSTR Buffer, PULONG MaxSize) | |
876 | { | |
877 | FIXME("(%p,%p,%p,%p): stub\n", IP, Port, Buffer, MaxSize); | |
878 | ||
879 | return STATUS_SUCCESS; | |
880 | } | |
881 | ||
882 | NTSTATUS WINAPI RtlIpv4AddressToStringExW (PULONG IP, PULONG Port, | |
883 | LPWSTR Buffer, PULONG MaxSize) | |
884 | { | |
885 | FIXME("(%p,%p,%p,%p): stub\n", IP, Port, Buffer, MaxSize); | |
886 | ||
887 | return STATUS_SUCCESS; | |
888 | } |