4 * This file contains the Rtl* API functions. These should be implementable.
6 * Copyright 1996-1998 Marcus Meissner
17 #include "wine/winestring.h"
19 #include "stackframe.h"
29 /* fixme: move to windef.h*/
30 typedef BOOL32 *LPBOOL;
31 /**************************************************************************
32 * RtlLengthRequiredSid [NTDLL.427]
34 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
36 return sizeof(DWORD)*nrofsubauths+sizeof(SID);
39 /**************************************************************************
40 * RtlLengthSid [NTDLL.429]
42 DWORD WINAPI RtlLengthSid(PSID sid)
43 { TRACE(ntdll,"sid=%p\n",sid);
46 return sizeof(DWORD)*sid->SubAuthorityCount+sizeof(SID);
49 /**************************************************************************
50 * RtlCreateAcl [NTDLL.306]
53 * This should return NTSTATUS
55 DWORD WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
57 if (rev!=ACL_REVISION)
58 return STATUS_INVALID_PARAMETER;
60 return STATUS_BUFFER_TOO_SMALL;
62 return STATUS_INVALID_PARAMETER;
64 memset(acl,'\0',sizeof(ACL));
65 acl->AclRevision = rev;
71 /**************************************************************************
72 * RtlFirstFreeAce [NTDLL.370]
73 * looks for the AceCount+1 ACE, and if it is still within the alloced
74 * ACL, return a pointer to it
76 BOOL32 WINAPI RtlFirstFreeAce(
84 ace = (LPACE_HEADER)(acl+1);
85 for (i=0;i<acl->AceCount;i++) {
86 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
88 ace = (LPACE_HEADER)(((BYTE*)ace)+ace->AceSize);
90 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
96 /**************************************************************************
97 * RtlAddAce [NTDLL.260]
99 NTSTATUS WINAPI RtlAddAce(
103 LPACE_HEADER acestart,
106 LPACE_HEADER ace,targetace;
109 if (acl->AclRevision != ACL_REVISION)
110 return STATUS_INVALID_PARAMETER;
111 if (!RtlFirstFreeAce(acl,&targetace))
112 return STATUS_INVALID_PARAMETER;
113 nrofaces=0;ace=acestart;
114 while (((DWORD)ace-(DWORD)acestart)<acelen) {
116 ace = (LPACE_HEADER)(((BYTE*)ace)+ace->AceSize);
118 if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
119 return STATUS_INVALID_PARAMETER;
120 memcpy((LPBYTE)targetace,acestart,acelen);
121 acl->AceCount+=nrofaces;
122 return STATUS_SUCCESS;
125 /**************************************************************************
126 * RtlCreateSecurityDescriptor [NTDLL.313]
130 * STATUS_INVALID_OWNER, STATUS_PRIVILEGE_NOT_HELD, STATUS_NO_INHERITANCE,
133 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
134 PSECURITY_DESCRIPTOR lpsd,
137 if (rev!=SECURITY_DESCRIPTOR_REVISION)
138 return STATUS_UNKNOWN_REVISION;
139 memset(lpsd,'\0',sizeof(*lpsd));
140 lpsd->Revision = SECURITY_DESCRIPTOR_REVISION;
141 return STATUS_SUCCESS;
144 /**************************************************************************
145 * RtlSetDaclSecurityDescriptor [NTDLL.483]
147 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
148 PSECURITY_DESCRIPTOR lpsd,
151 BOOL32 dacldefaulted )
153 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
154 return STATUS_UNKNOWN_REVISION;
155 if (lpsd->Control & SE_SELF_RELATIVE)
156 return STATUS_INVALID_SECURITY_DESCR;
158 { lpsd->Control &= ~SE_DACL_PRESENT;
161 lpsd->Control |= SE_DACL_PRESENT;
164 lpsd->Control |= SE_DACL_DEFAULTED;
166 lpsd->Control &= ~SE_DACL_DEFAULTED;
168 return STATUS_SUCCESS;
171 /**************************************************************************
172 * RtlSetSaclSecurityDescriptor [NTDLL.488]
174 DWORD WINAPI RtlSetSaclSecurityDescriptor (
175 PSECURITY_DESCRIPTOR lpsd,
178 BOOL32 sacldefaulted)
180 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
181 return STATUS_UNKNOWN_REVISION;
182 if (lpsd->Control & SE_SELF_RELATIVE)
183 return STATUS_INVALID_SECURITY_DESCR;
185 lpsd->Control &= ~SE_SACL_PRESENT;
188 lpsd->Control |= SE_SACL_PRESENT;
191 lpsd->Control |= SE_SACL_DEFAULTED;
193 lpsd->Control &= ~SE_SACL_DEFAULTED;
194 return STATUS_SUCCESS;
197 /**************************************************************************
198 * RtlSetOwnerSecurityDescriptor [NTDLL.487]
200 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
201 PSECURITY_DESCRIPTOR lpsd,
203 BOOL32 ownerdefaulted)
205 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
206 return STATUS_UNKNOWN_REVISION;
207 if (lpsd->Control & SE_SELF_RELATIVE)
208 return STATUS_INVALID_SECURITY_DESCR;
212 lpsd->Control |= SE_OWNER_DEFAULTED;
214 lpsd->Control &= ~SE_OWNER_DEFAULTED;
215 return STATUS_SUCCESS;
218 /**************************************************************************
219 * RtlSetGroupSecurityDescriptor [NTDLL.485]
221 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
222 PSECURITY_DESCRIPTOR lpsd,
224 BOOL32 groupdefaulted)
226 if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
227 return STATUS_UNKNOWN_REVISION;
228 if (lpsd->Control & SE_SELF_RELATIVE)
229 return STATUS_INVALID_SECURITY_DESCR;
233 lpsd->Control |= SE_GROUP_DEFAULTED;
235 lpsd->Control &= ~SE_GROUP_DEFAULTED;
236 return STATUS_SUCCESS;
240 /**************************************************************************
241 * RtlNormalizeProcessParams [NTDLL.441]
243 LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
245 FIXME(ntdll,"(%p), stub\n",x);
249 /**************************************************************************
250 * RtlInitializeSid [NTDLL.410]
252 DWORD WINAPI RtlInitializeSid(PSID PSID,PSID_IDENTIFIER_AUTHORITY PSIDauth,
257 if (a>=SID_MAX_SUB_AUTHORITIES)
259 PSID->SubAuthorityCount = a;
260 PSID->Revision = SID_REVISION;
261 memcpy(&(PSID->IdentifierAuthority),PSIDauth,sizeof(SID_IDENTIFIER_AUTHORITY));
262 return STATUS_SUCCESS;
265 /**************************************************************************
266 * RtlSubAuthoritySid [NTDLL.497]
268 LPDWORD WINAPI RtlSubAuthoritySid(PSID PSID,DWORD nr)
270 return &(PSID->SubAuthority[nr]);
273 /**************************************************************************
274 * RtlSubAuthorityCountSid [NTDLL.496]
276 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID PSID)
278 return ((LPBYTE)PSID)+1;
281 /**************************************************************************
282 * RtlCopySid [NTDLL.302]
284 DWORD WINAPI RtlCopySid(DWORD len,PSID to,PSID from)
287 if (len<(from->SubAuthorityCount*4+8))
288 return STATUS_BUFFER_TOO_SMALL;
289 memmove(to,from,from->SubAuthorityCount*4+8);
290 return STATUS_SUCCESS;
293 /**************************************************************************
294 * RtlAnsiStringToUnicodeString [NTDLL.269]
297 WINAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING uni,PANSI_STRING ansi,BOOL32 doalloc)
299 DWORD unilen = (ansi->Length+1)*sizeof(WCHAR);
302 return STATUS_INVALID_PARAMETER_2;
303 uni->Length = unilen;
305 uni->MaximumLength = unilen;
306 uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen);
308 return STATUS_NO_MEMORY;
310 if (unilen>uni->MaximumLength)
311 return STATUS_BUFFER_OVERFLOW;
312 lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
313 return STATUS_SUCCESS;
316 /**************************************************************************
317 * RtlOemStringToUnicodeString [NTDLL.447]
320 WINAPI RtlOemStringToUnicodeString(PUNICODE_STRING uni,PSTRING ansi,BOOL32 doalloc)
322 DWORD unilen = (ansi->Length+1)*sizeof(WCHAR);
325 return STATUS_INVALID_PARAMETER_2;
326 uni->Length = unilen;
328 uni->MaximumLength = unilen;
329 uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen);
331 return STATUS_NO_MEMORY;
333 if (unilen>uni->MaximumLength)
334 return STATUS_BUFFER_OVERFLOW;
335 lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
336 return STATUS_SUCCESS;
338 /**************************************************************************
339 * RtlMultiByteToUnicodeN [NTDLL.436]
340 * FIXME: multibyte support
343 WINAPI RtlMultiByteToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
351 x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
352 lstrcpynAtoW(x,oemstr,len+1);
353 memcpy(unistr,x,len*2);
354 if (reslen) *reslen = len*2;
358 /**************************************************************************
359 * RtlOemToUnicodeN [NTDLL.448]
362 WINAPI RtlOemToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
370 x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
371 lstrcpynAtoW(x,oemstr,len+1);
372 memcpy(unistr,x,len*2);
373 if (reslen) *reslen = len*2;
377 /**************************************************************************
378 * RtlInitAnsiString [NTDLL.399]
380 VOID WINAPI RtlInitAnsiString(PANSI_STRING target,LPCSTR source)
382 target->Length = target->MaximumLength = 0;
383 target->Buffer = (LPSTR)source;
386 target->MaximumLength = lstrlen32A(target->Buffer);
387 target->Length = target->MaximumLength+1;
389 /**************************************************************************
390 * RtlInitString [NTDLL.402]
392 VOID WINAPI RtlInitString(PSTRING target,LPCSTR source)
394 target->Length = target->MaximumLength = 0;
395 target->Buffer = (LPSTR)source;
398 target->MaximumLength = lstrlen32A(target->Buffer);
399 target->Length = target->MaximumLength+1;
402 /**************************************************************************
403 * RtlInitUnicodeString [NTDLL.403]
405 VOID WINAPI RtlInitUnicodeString(PUNICODE_STRING target,LPCWSTR source)
407 target->Length = target->MaximumLength = 0;
408 target->Buffer = (LPWSTR)source;
411 target->MaximumLength = lstrlen32W(target->Buffer)*2;
412 target->Length = target->MaximumLength+2;
415 /**************************************************************************
416 * RtlFreeUnicodeString [NTDLL.377]
418 VOID WINAPI RtlFreeUnicodeString(PUNICODE_STRING str)
421 HeapFree(GetProcessHeap(),0,str->Buffer);
424 /**************************************************************************
425 * RtlFreeAnsiString [NTDLL.373]
427 VOID WINAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
429 if( AnsiString->Buffer )
430 HeapFree( GetProcessHeap(),0,AnsiString->Buffer );
434 /**************************************************************************
435 * RtlUnicodeToOemN [NTDLL.515]
438 WINAPI RtlUnicodeToOemN(LPSTR oemstr,DWORD oemlen,LPDWORD reslen,LPWSTR unistr,DWORD unilen)
446 x=(LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+1);
447 lstrcpynWtoA(x,unistr,len+1);
448 memcpy(oemstr,x,len);
449 if (reslen) *reslen = len;
453 /**************************************************************************
454 * RtlUnicodeStringToOemString [NTDLL.511]
457 WINAPI RtlUnicodeStringToOemString(PANSI_STRING oem,PUNICODE_STRING uni,BOOL32 alloc)
460 oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
461 oem->MaximumLength = uni->Length/2+1;
463 oem->Length = uni->Length/2;
464 lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
468 /**************************************************************************
469 * RtlUnicodeStringToAnsiString [NTDLL.507]
472 WINAPI RtlUnicodeStringToAnsiString(PANSI_STRING oem,PUNICODE_STRING uni,BOOL32 alloc)
475 oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
476 oem->MaximumLength = uni->Length/2+1;
478 oem->Length = uni->Length/2;
479 lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
483 /**************************************************************************
484 * RtlEqualUnicodeString [NTDLL]
486 DWORD WINAPI RtlEqualUnicodeString(PUNICODE_STRING s1,PUNICODE_STRING s2,DWORD x) {
487 FIXME(ntdll,"(%s,%s,%ld),stub!\n",debugstr_w(s1->Buffer),debugstr_w(s2->Buffer),x);
489 if (s1->Length != s2->Length)
491 return !lstrncmp32W(s1->Buffer,s2->Buffer,s1->Length/2);
494 /**************************************************************************
495 * RtlNtStatusToDosErro [NTDLL.442]
497 DWORD WINAPI RtlNtStatusToDosError(DWORD error)
499 FIXME(ntdll, "(%lx): map STATUS_ to ERROR_\n",error);
503 /**************************************************************************
504 * RtlGetNtProductType [NTDLL.390]
506 BOOL32 WINAPI RtlGetNtProductType(LPDWORD type)
508 FIXME(ntdll, "(%p): stub\n", type);
509 *type=3; /* dunno. 1 for client, 3 for server? */
513 /**************************************************************************
514 * RtlUpcaseUnicodeString [NTDLL.520]
516 DWORD WINAPI RtlUpcaseUnicodeString(PUNICODE_STRING dest,PUNICODE_STRING src,BOOL32 doalloc)
523 dest->MaximumLength = len;
524 dest->Buffer = (LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len);
526 return STATUS_NO_MEMORY;
529 if (dest->MaximumLength < len)
530 return STATUS_BUFFER_OVERFLOW;
531 s=dest->Buffer;t=src->Buffer;
532 /* len is in bytes */
533 for (i=0;i<len/2;i++)
534 s[i] = towupper(t[i]);
535 return STATUS_SUCCESS;
538 /**************************************************************************
539 * RtlxOemStringToUnicodeSize [NTDLL.549]
541 UINT32 WINAPI RtlxOemStringToUnicodeSize(PSTRING str)
543 return str->Length*2+2;
546 /**************************************************************************
547 * RtlxAnsiStringToUnicodeSize [NTDLL.548]
549 UINT32 WINAPI RtlxAnsiStringToUnicodeSize(PANSI_STRING str)
551 return str->Length*2+2;
554 /**************************************************************************
555 * RtlIsTextUnicode [NTDLL.417]
557 * Apply various feeble heuristics to guess whether
558 * the text buffer contains Unicode.
559 * FIXME: should implement more tests.
561 DWORD WINAPI RtlIsTextUnicode(LPVOID buf, DWORD len, DWORD *pf)
564 DWORD flags = -1, out_flags = 0;
571 * Apply various tests to the text string. According to the
572 * docs, each test "passed" sets the corresponding flag in
573 * the output flags. But some of the tests are mutually
574 * exclusive, so I don't see how you could pass all tests ...
577 /* Check for an odd length ... pass if even. */
579 out_flags |= IS_TEXT_UNICODE_ODD_LENGTH;
581 /* Check for the special unicode marker byte. */
583 out_flags |= IS_TEXT_UNICODE_SIGNATURE;
586 * Check whether the string passed all of the tests.
588 flags &= ITU_IMPLEMENTED_TESTS;
589 if ((out_flags & flags) != flags)
597 /**************************************************************************
598 * RtlDosPathNameToNtPathName_U [NTDLL.338]
600 * FIXME: convert to UNC or whatever is expected here
602 BOOL32 WINAPI RtlDosPathNameToNtPathName_U(
603 LPWSTR from,PUNICODE_STRING us,DWORD x2,DWORD x3)
605 LPSTR fromA = HEAP_strdupWtoA(GetProcessHeap(),0,from);
607 FIXME(ntdll,"(%s,%p,%08lx,%08lx)\n",fromA,us,x2,x3);
609 RtlInitUnicodeString(us,HEAP_strdupW(GetProcessHeap(),0,from));
613 /**************************************************************************
614 * NTDLL_chkstk [NTDLL.862]
615 * NTDLL_alloca_probe [NTDLL.861]
616 * Glorified "enter xxxx".
618 REGS_ENTRYPOINT(NTDLL_chkstk)
620 ESP_reg(context) -= EAX_reg(context);
622 REGS_ENTRYPOINT(NTDLL_alloca_probe)
624 ESP_reg(context) -= EAX_reg(context);
627 /******************************************************************************
628 * RtlTimeToElapsedTimeFields [NTDLL.502]
630 DWORD WINAPI RtlTimeToElapsedTimeFields( DWORD x1, DWORD x2 )
632 FIXME(ntdll,"(%lx,%lx): stub\n",x1,x2);
637 /******************************************************************************
638 * RtlExtendedLargeIntegerDivide [NTDLL.359]
640 INT32 WINAPI RtlExtendedLargeIntegerDivide(
641 LARGE_INTEGER dividend,
645 #if SIZEOF_LONG_LONG==8
646 long long x1 = *(long long*)÷nd;
649 *rest = x1 % divisor;
652 FIXME(ntdll,"((%d<<32)+%d,%d,%p), implement this using normal integer arithmetic!\n",dividend.HighPart,dividend.LowPart,divisor,rest);
657 /******************************************************************************
658 * RtlExtendedLargeIntegerMultiply [NTDLL.359]
659 * Note: This even works, since gcc returns 64bit values in eax/edx just like
660 * the caller expects. However... The relay code won't grok this I think.
662 long long /*LARGE_INTEGER*/
663 WINAPI RtlExtendedIntegerMultiply(
664 LARGE_INTEGER factor1,INT32 factor2
666 #if SIZEOF_LONG_LONG==8
667 return (*(long long*)&factor1)*factor2;
669 FIXME(ntdll,"((%d<<32)+%d,%ld), implement this using normal integer arithmetic!\n",factor1.HighPart,factor1.LowPart,factor2);
674 /******************************************************************************
675 * RtlFormatCurrentUserKeyPath [NTDLL.371]
677 DWORD WINAPI RtlFormatCurrentUserKeyPath(DWORD x)
679 FIXME(ntdll,"(0x%08lx): stub\n",x);
683 /******************************************************************************
684 * RtlOpenCurrentUser [NTDLL]
686 DWORD WINAPI RtlOpenCurrentUser(DWORD x1, DWORD *x2)
688 /* Note: this is not the correct solution,
689 * But this works pretty good on wine and NT4.0 binaries
691 if ( x1 == 0x2000000 ) {
692 *x2 = HKEY_CURRENT_USER;
698 /******************************************************************************
699 * RtlAllocateAndInitializeSid [NTDLL.265]
702 BOOL32 WINAPI RtlAllocateAndInitializeSid (PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,DWORD nSubAuthorityCount,
703 DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD x7,DWORD x8,DWORD x9,DWORD x10, PSID pSid)
704 { FIXME(ntdll,"(%p,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p),stub!\n",
705 pIdentifierAuthority,nSubAuthorityCount,x3,x4,x5,x6,x7,x8,x9,x10,pSid);
708 /******************************************************************************
709 * RtlEqualSid [NTDLL.352]
712 DWORD WINAPI RtlEqualSid(DWORD x1,DWORD x2) {
713 FIXME(ntdll,"(0x%08lx,0x%08lx),stub!\n", x1,x2);
717 /******************************************************************************
718 * RtlFreeSid [NTDLL.376]
720 DWORD WINAPI RtlFreeSid(DWORD x1)
721 { FIXME(ntdll,"(0x%08lx),stub!\n", x1);
725 /******************************************************************************
726 * RtlGetDaclSecurityDescriptor [NTDLL]
728 * NOTES: seems to be like GetSecurityDescriptorDacl (js)
730 DWORD WINAPI RtlGetDaclSecurityDescriptor(
731 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
732 OUT LPBOOL lpbDaclPresent,
734 OUT LPBOOL lpbDaclDefaulted)
737 TRACE(ntdll,"(%p,%p,%p,%p)\n",
738 pSecurityDescriptor, lpbDaclPresent, *pDacl, lpbDaclDefaulted);
740 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
741 return STATUS_UNKNOWN_REVISION ;
743 if ( (*lpbDaclPresent = (SE_DACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
745 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
746 { *pDacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Dacl);
749 { *pDacl = pSecurityDescriptor->Dacl;
753 *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
758 /******************************************************************************
759 * RtlCreateEnvironment [NTDLL]
761 DWORD WINAPI RtlCreateEnvironment(DWORD x1,DWORD x2) {
762 FIXME(ntdll,"(0x%08lx,0x%08lx),stub!\n",x1,x2);
767 /******************************************************************************
768 * RtlDestroyEnvironment [NTDLL]
770 DWORD WINAPI RtlDestroyEnvironment(DWORD x) {
771 FIXME(ntdll,"(0x%08lx),stub!\n",x);
775 /******************************************************************************
776 * RtlQueryEnvironmentVariable_U [NTDLL]
778 DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
779 FIXME(ntdll,"(0x%08lx,%s,%p),stub!\n",x1,debugstr_w(key->Buffer),val);
783 /******************************************************************************
784 * RtlSetEnvironmentVariable [NTDLL]
786 DWORD WINAPI RtlSetEnvironmentVariable(DWORD x1,PUNICODE_STRING key,PUNICODE_STRING val) {
787 FIXME(ntdll,"(0x%08lx,%s,%s),stub!\n",x1,debugstr_w(key->Buffer),debugstr_w(val->Buffer));
791 /******************************************************************************
792 * RtlNewSecurityObject [NTDLL]
794 DWORD WINAPI RtlNewSecurityObject(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6) {
795 FIXME(ntdll,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4,x5,x6);
799 /******************************************************************************
800 * RtlDeleteSecurityObject [NTDLL]
802 DWORD WINAPI RtlDeleteSecurityObject(DWORD x1) {
803 FIXME(ntdll,"(0x%08lx),stub!\n",x1);
807 /******************************************************************************
808 * RtlToTimeInSecondsSince1980 [NTDLL]
810 BOOL32 WINAPI RtlTimeToSecondsSince1980(LPFILETIME ft,LPDWORD timeret) {
811 /* 1980 = 1970+10*365 days + 29. februar 1972 + 29.februar 1976 */
812 *timeret = DOSFS_FileTimeToUnixTime(ft,NULL) - (10*365+2)*24*3600;
816 /******************************************************************************
817 * RtlToTimeInSecondsSince1970 [NTDLL]
819 BOOL32 WINAPI RtlTimeToSecondsSince1970(LPFILETIME ft,LPDWORD timeret) {
820 *timeret = DOSFS_FileTimeToUnixTime(ft,NULL);
824 /******************************************************************************
825 * RtlAcquirePebLock [NTDLL]
827 VOID WINAPI RtlAcquirePebLock(void) {
829 /* enter critical section ? */
832 /******************************************************************************
833 * RtlReleasePebLock [NTDLL]
835 VOID WINAPI RtlReleasePebLock(void) {
837 /* leave critical section ? */
840 /******************************************************************************
841 * RtlAddAccessAllowedAce [NTDLL]
843 DWORD WINAPI RtlAddAccessAllowedAce(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
844 FIXME(ntdll,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
848 /******************************************************************************
851 DWORD WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce ) {
852 FIXME(ntdll,"(%p,%ld,%p),stub!\n",pAcl,dwAceIndex,pAce);
856 /******************************************************************************
857 * RtlAdjustPrivilege [NTDLL]
859 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
860 FIXME(ntdll,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
864 /******************************************************************************
865 * RtlIntegerToChar [NTDLL]
867 DWORD WINAPI RtlIntegerToChar(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
868 FIXME(ntdll,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
871 /******************************************************************************
872 * RtlSystemTimeToLocalTime [NTDLL]
874 DWORD WINAPI RtlSystemTimeToLocalTime(DWORD x1,DWORD x2) {
875 FIXME(ntdll,"(0x%08lx,0x%08lx),stub!\n",x1,x2);
878 /******************************************************************************
879 * RtlTimeToTimeFields [NTDLL]
881 DWORD WINAPI RtlTimeToTimeFields(DWORD x1,DWORD x2) {
882 FIXME(ntdll,"(0x%08lx,0x%08lx),stub!\n",x1,x2);
885 /******************************************************************************
886 * RtlCompareUnicodeString [NTDLL]
888 NTSTATUS WINAPI RtlCompareUnicodeString(
889 PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
891 FIXME(ntdll,"(%s,%s,0x%08x),stub!\n",debugstr_w(String1->Buffer),debugstr_w(String1->Buffer),CaseInSensitive);
895 /******************************************************************************
898 void __cdecl DbgPrint(LPCSTR fmt,LPVOID args) {
901 wvsprintf32A(buf,fmt,&args);
902 MSG("DbgPrint says: %s",buf);
903 /* hmm, raise exception? */
905 DWORD NtRaiseException ( DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments,CONST ULONG_PTR *lpArguments)
906 { FIXME(ntdll,"0x%08lx 0x%08lx 0x%08lx %p\n", dwExceptionCode, dwExceptionFlags, nNumberOfArguments, lpArguments);
910 DWORD RtlRaiseException ( DWORD x)
911 { FIXME(ntdll, "0x%08lx\n", x);
915 /***********************************************************************
916 * RtlInitializeResource (NTDLL.409)
918 * xxxResource() functions implement multiple-reader-single-writer lock.
919 * The code is based on information published in WDJ January 1999 issue.
921 void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl)
925 rwl->iNumberActive = 0;
926 rwl->uExclusiveWaiters = 0;
927 rwl->uSharedWaiters = 0;
928 rwl->hOwningThreadId = 0;
929 rwl->dwTimeoutBoost = 0; /* no info on this one, default value is 0 */
930 InitializeCriticalSection( &rwl->rtlCS );
931 rwl->hExclusiveReleaseSemaphore = CreateSemaphore32A( NULL, 0, 65535, NULL );
932 rwl->hSharedReleaseSemaphore = CreateSemaphore32A( NULL, 0, 65535, NULL );
937 /***********************************************************************
938 * RtlDeleteResource (NTDLL.330)
940 void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl)
944 EnterCriticalSection( &rwl->rtlCS );
945 if( rwl->iNumberActive || rwl->uExclusiveWaiters || rwl->uSharedWaiters )
946 MSG("Deleting active MRSW lock (%p), expect failure\n", rwl );
947 rwl->hOwningThreadId = 0;
948 rwl->uExclusiveWaiters = rwl->uSharedWaiters = 0;
949 rwl->iNumberActive = 0;
950 CloseHandle( rwl->hExclusiveReleaseSemaphore );
951 CloseHandle( rwl->hSharedReleaseSemaphore );
952 LeaveCriticalSection( &rwl->rtlCS );
953 DeleteCriticalSection( &rwl->rtlCS );
958 /***********************************************************************
959 * RtlAcquireResourceExclusive (NTDLL.256)
961 BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl, BYTE fWait)
967 EnterCriticalSection( &rwl->rtlCS );
968 if( rwl->iNumberActive == 0 ) /* lock is free */
970 rwl->iNumberActive = -1;
973 else if( rwl->iNumberActive < 0 ) /* exclusive lock in progress */
975 if( rwl->hOwningThreadId == GetCurrentThreadId() )
978 rwl->iNumberActive--;
984 rwl->uExclusiveWaiters++;
986 LeaveCriticalSection( &rwl->rtlCS );
987 if( WaitForSingleObject( rwl->hExclusiveReleaseSemaphore, INFINITE32 ) == WAIT_FAILED )
989 goto start; /* restart the acquisition to avoid deadlocks */
992 else /* one or more shared locks are in progress */
997 rwl->hOwningThreadId = GetCurrentThreadId();
999 LeaveCriticalSection( &rwl->rtlCS );
1003 /***********************************************************************
1004 * RtlAcquireResourceShared (NTDLL.257)
1006 BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl, BYTE fWait)
1008 DWORD dwWait = WAIT_FAILED;
1010 if( !rwl ) return 0;
1013 EnterCriticalSection( &rwl->rtlCS );
1014 if( rwl->iNumberActive < 0 )
1016 if( rwl->hOwningThreadId == GetCurrentThreadId() )
1018 rwl->iNumberActive--;
1025 rwl->uSharedWaiters++;
1026 LeaveCriticalSection( &rwl->rtlCS );
1027 if( (dwWait = WaitForSingleObject( rwl->hSharedReleaseSemaphore, INFINITE32 )) == WAIT_FAILED )
1034 if( dwWait != WAIT_OBJECT_0 ) /* otherwise RtlReleaseResource() has already done it */
1035 rwl->iNumberActive++;
1039 LeaveCriticalSection( &rwl->rtlCS );
1044 /***********************************************************************
1045 * RtlReleaseResource (NTDLL.471)
1047 void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl)
1049 EnterCriticalSection( &rwl->rtlCS );
1051 if( rwl->iNumberActive > 0 ) /* have one or more readers */
1053 if( --rwl->iNumberActive == 0 )
1055 if( rwl->uExclusiveWaiters )
1058 rwl->uExclusiveWaiters--;
1059 ReleaseSemaphore( rwl->hExclusiveReleaseSemaphore, 1, NULL );
1064 if( rwl->iNumberActive < 0 ) /* have a writer, possibly recursive */
1066 if( ++rwl->iNumberActive == 0 )
1068 rwl->hOwningThreadId = 0;
1069 if( rwl->uExclusiveWaiters )
1070 goto wake_exclusive;
1072 if( rwl->uSharedWaiters )
1074 UINT32 n = rwl->uSharedWaiters;
1075 rwl->iNumberActive = rwl->uSharedWaiters; /* prevent new writers from joining until
1076 * all queued readers have done their thing */
1077 rwl->uSharedWaiters = 0;
1078 ReleaseSemaphore( rwl->hSharedReleaseSemaphore, n, NULL );
1082 LeaveCriticalSection( &rwl->rtlCS );
1086 /***********************************************************************
1087 * RtlDumpResource (NTDLL.340)
1089 void WINAPI RtlDumpResource(LPRTL_RWLOCK rwl)
1093 MSG("RtlDumpResource(%p):\n\tactive count = %i\n\twaiting readers = %i\n\twaiting writers = %i\n",
1094 rwl, rwl->iNumberActive, rwl->uSharedWaiters, rwl->uExclusiveWaiters );
1095 if( rwl->iNumberActive )
1096 MSG("\towner thread = %08x\n", rwl->hOwningThreadId );