Release 980503
[wine] / misc / ntdll.c
1 /*
2  * NT basis DLL
3  * 
4  * Copyright 1996 Marcus Meissner
5  */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <time.h>
11 #include <ctype.h>
12 #include <math.h>
13 #include "win.h"
14 #include "windows.h"
15 #include "ntdll.h"
16 #include "heap.h"
17 #include "debug.h"
18 #include "module.h"
19 #include "heap.h"
20
21 /**************************************************************************
22  *                 RtlLengthRequiredSid                 [NTDLL]
23  */
24 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
25 {
26         return sizeof(DWORD)*nrofsubauths+sizeof(SID);
27 }
28
29 /**************************************************************************
30  *                 RtlLengthSid                         [NTDLL]
31  */
32 DWORD WINAPI RtlLengthSid(LPSID sid)
33 {
34         return sizeof(DWORD)*sid->SubAuthorityCount+sizeof(SID);
35 }
36
37 /**************************************************************************
38  *                 RtlCreateAcl                         [NTDLL]
39  *
40  * NOTES
41  *    This should return NTSTATUS
42  */
43 DWORD WINAPI RtlCreateAcl(LPACL acl,DWORD size,DWORD rev)
44 {
45         if (rev!=ACL_REVISION)
46                 return STATUS_INVALID_PARAMETER;
47         if (size<sizeof(ACL))
48                 return STATUS_BUFFER_TOO_SMALL;
49         if (size>0xFFFF)
50                 return STATUS_INVALID_PARAMETER;
51
52         memset(acl,'\0',sizeof(ACL));
53         acl->AclRevision        = rev;
54         acl->AclSize            = size;
55         acl->AceCount           = 0;
56         return 0;
57 }
58
59 /**************************************************************************
60  *                 RtlFirstFreeAce                      [NTDLL]
61  * looks for the AceCount+1 ACE, and if it is still within the alloced
62  * ACL, return a pointer to it
63  */
64 BOOL32 WINAPI RtlFirstFreeAce(LPACL acl,LPACE_HEADER *x)
65 {
66         LPACE_HEADER    ace;
67         int             i;
68
69         *x = 0;
70         ace = (LPACE_HEADER)(acl+1);
71         for (i=0;i<acl->AceCount;i++) {
72                 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
73                         return 0;
74                 ace = (LPACE_HEADER)(((BYTE*)ace)+ace->AceSize);
75         }
76         if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
77                 return 0;
78         *x = ace;
79         return 1;
80 }
81
82 /**************************************************************************
83  *                 RtlAddAce                            [NTDLL]
84  */
85 DWORD /* NTSTATUS */  WINAPI RtlAddAce(LPACL acl,DWORD rev,DWORD xnrofaces,
86                                        LPACE_HEADER acestart,DWORD acelen)
87 {
88         LPACE_HEADER    ace,targetace;
89         int             nrofaces;
90
91         if (acl->AclRevision != ACL_REVISION)
92                 return STATUS_INVALID_PARAMETER;
93         if (!RtlFirstFreeAce(acl,&targetace))
94                 return STATUS_INVALID_PARAMETER;
95         nrofaces=0;ace=acestart;
96         while (((DWORD)ace-(DWORD)acestart)<acelen) {
97                 nrofaces++;
98                 ace = (LPACE_HEADER)(((BYTE*)ace)+ace->AceSize);
99         }
100         if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
101                 return STATUS_INVALID_PARAMETER;
102         memcpy((LPBYTE)targetace,acestart,acelen);
103         acl->AceCount+=nrofaces;
104         return 0;
105 }
106
107 /**************************************************************************
108  *                 RtlCreateSecurityDescriptor          [NTDLL]
109  */
110 DWORD /* NTSTATUS */ WINAPI RtlCreateSecurityDescriptor(LPSECURITY_DESCRIPTOR lpsd,DWORD rev)
111 {
112         if (rev!=SECURITY_DESCRIPTOR_REVISION)
113                 return STATUS_UNKNOWN_REVISION;
114         memset(lpsd,'\0',sizeof(*lpsd));
115         lpsd->Revision = SECURITY_DESCRIPTOR_REVISION;
116         return 0;
117 }
118
119 /**************************************************************************
120  *                 RtlSetDaclSecurityDescriptor         [NTDLL]
121  */
122 DWORD /* NTSTATUS */ WINAPI RtlSetDaclSecurityDescriptor ( LPSECURITY_DESCRIPTOR lpsd,BOOL32 daclpresent,LPACL dacl,BOOL32 dacldefaulted )
123 {
124         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
125                 return STATUS_UNKNOWN_REVISION;
126         if (lpsd->Control & SE_SELF_RELATIVE)
127                 return STATUS_INVALID_SECURITY_DESCR;
128         if (!daclpresent) {
129                 lpsd->Control &= ~SE_DACL_PRESENT;
130                 return 0;
131         }
132         lpsd->Control |= SE_DACL_PRESENT;
133         lpsd->Dacl = dacl;
134         if (dacldefaulted)
135                 lpsd->Control |= SE_DACL_DEFAULTED;
136         else
137                 lpsd->Control &= ~SE_DACL_DEFAULTED;
138         return 0;
139 }
140
141 /**************************************************************************
142  *                 RtlSetSaclSecurityDescriptor         [NTDLL]
143  */
144 DWORD /* NTSTATUS */ WINAPI RtlSetSaclSecurityDescriptor (
145 LPSECURITY_DESCRIPTOR lpsd,BOOL32 saclpresent,LPACL sacl,BOOL32 sacldefaulted
146 )
147 {
148         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
149                 return STATUS_UNKNOWN_REVISION;
150         if (lpsd->Control & SE_SELF_RELATIVE)
151                 return STATUS_INVALID_SECURITY_DESCR;
152         if (!saclpresent) {
153                 lpsd->Control &= ~SE_SACL_PRESENT;
154                 return 0;
155         }
156         lpsd->Control |= SE_SACL_PRESENT;
157         lpsd->Sacl = sacl;
158         if (sacldefaulted)
159                 lpsd->Control |= SE_SACL_DEFAULTED;
160         else
161                 lpsd->Control &= ~SE_SACL_DEFAULTED;
162         return 0;
163 }
164
165 /**************************************************************************
166  *                 RtlSetOwnerSecurityDescriptor                [NTDLL]
167  */
168 DWORD /* NTSTATUS */ WINAPI RtlSetOwnerSecurityDescriptor (LPSECURITY_DESCRIPTOR lpsd,LPSID owner,BOOL32 ownerdefaulted)
169 {
170         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
171                 return STATUS_UNKNOWN_REVISION;
172         if (lpsd->Control & SE_SELF_RELATIVE)
173                 return STATUS_INVALID_SECURITY_DESCR;
174
175         lpsd->Owner = owner;
176         if (ownerdefaulted)
177                 lpsd->Control |= SE_OWNER_DEFAULTED;
178         else
179                 lpsd->Control &= ~SE_OWNER_DEFAULTED;
180         return 0;
181 }
182
183 /**************************************************************************
184  *                 RtlSetOwnerSecurityDescriptor                [NTDLL]
185  */
186 DWORD /* NTSTATUS */ WINAPI RtlSetGroupSecurityDescriptor (LPSECURITY_DESCRIPTOR lpsd,LPSID group,BOOL32 groupdefaulted)
187 {
188         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
189                 return STATUS_UNKNOWN_REVISION;
190         if (lpsd->Control & SE_SELF_RELATIVE)
191                 return STATUS_INVALID_SECURITY_DESCR;
192
193         lpsd->Group = group;
194         if (groupdefaulted)
195                 lpsd->Control |= SE_GROUP_DEFAULTED;
196         else
197                 lpsd->Control &= ~SE_GROUP_DEFAULTED;
198         return 0;
199 }
200
201
202 /**************************************************************************
203  *                 RtlNormalizeProcessParams            [NTDLL]
204  */
205 LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
206 {
207     FIXME(ntdll,"(%p), stub.\n",x);
208     return x;
209 }
210
211 /**************************************************************************
212  *                 RtlInitializeSid                     [NTDLL]
213  */
214 DWORD WINAPI RtlInitializeSid(LPSID lpsid,LPSID_IDENTIFIER_AUTHORITY lpsidauth,
215                               DWORD c)
216 {
217         BYTE    a = c&0xff;
218
219         if (a>=SID_MAX_SUB_AUTHORITIES)
220                 return a;
221         lpsid->SubAuthorityCount = a;
222         lpsid->Revision          = SID_REVISION;
223         memcpy(&(lpsid->IdentifierAuthority),lpsidauth,sizeof(SID_IDENTIFIER_AUTHORITY));
224         return 0;
225 }
226
227 /**************************************************************************
228  *                 RtlSubAuthoritySid                   [NTDLL]
229  */
230 LPDWORD WINAPI RtlSubAuthoritySid(LPSID lpsid,DWORD nr)
231 {
232         return &(lpsid->SubAuthority[nr]);
233 }
234
235 /**************************************************************************
236  *                 RtlSubAuthorityCountSid              [NTDLL]
237  */
238 LPBYTE WINAPI RtlSubAuthorityCountSid(LPSID lpsid)
239 {
240         return ((LPBYTE)lpsid)+1;
241 }
242
243 /**************************************************************************
244  *                 RtlCopySid                           [NTDLL]
245  */
246 DWORD WINAPI RtlCopySid(DWORD len,LPSID to,LPSID from)
247 {
248         if (len<(from->SubAuthorityCount*4+8))
249                 return STATUS_BUFFER_TOO_SMALL;
250         memmove(to,from,from->SubAuthorityCount*4+8);
251         return STATUS_SUCCESS;
252 }
253
254 /**************************************************************************
255  *                 RtlAnsiStringToUnicodeString         [NTDLL]
256  */
257 DWORD /* NTSTATUS */ WINAPI RtlAnsiStringToUnicodeString(LPUNICODE_STRING uni,LPANSI_STRING ansi,BOOL32 doalloc)
258 {
259         DWORD   unilen = (ansi->Length+1)*sizeof(WCHAR);
260
261         if (unilen>0xFFFF)
262                 return STATUS_INVALID_PARAMETER_2;
263         uni->Length = unilen;
264         if (doalloc) {
265                 uni->MaximumLength = unilen;
266                 uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen);
267                 if (!uni->Buffer)
268                         return STATUS_NO_MEMORY;
269         }
270         if (unilen>uni->MaximumLength)
271                 return STATUS_BUFFER_OVERFLOW;
272         lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
273         return STATUS_SUCCESS;
274 }
275
276 /**************************************************************************
277  *                 RtlOemStringToUnicodeString          [NTDLL]
278  */
279 DWORD /* NTSTATUS */ WINAPI RtlOemStringToUnicodeString(LPUNICODE_STRING uni,LPSTRING ansi,BOOL32 doalloc)
280 {
281         DWORD   unilen = (ansi->Length+1)*sizeof(WCHAR);
282
283         if (unilen>0xFFFF)
284                 return STATUS_INVALID_PARAMETER_2;
285         uni->Length = unilen;
286         if (doalloc) {
287                 uni->MaximumLength = unilen;
288                 uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen);
289                 if (!uni->Buffer)
290                         return STATUS_NO_MEMORY;
291         }
292         if (unilen>uni->MaximumLength)
293                 return STATUS_BUFFER_OVERFLOW;
294         lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
295         return STATUS_SUCCESS;
296 }
297 /**************************************************************************
298  *                 RtlMultiByteToUnicodeN               [NTDLL]
299  * FIXME: multibyte support
300  */
301 DWORD /* NTSTATUS */ WINAPI RtlMultiByteToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
302 {
303         DWORD   len;
304         LPWSTR  x;
305
306         len = oemlen;
307         if (unilen/2 < len)
308                 len = unilen/2;
309         x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
310         lstrcpynAtoW(x,oemstr,len+1);
311         memcpy(unistr,x,len*2);
312         if (reslen) *reslen = len*2;
313         return 0;
314 }
315
316 /**************************************************************************
317  *                 RtlOemToUnicodeN                     [NTDLL]
318  */
319 DWORD /* NTSTATUS */ WINAPI RtlOemToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
320 {
321         DWORD   len;
322         LPWSTR  x;
323
324         len = oemlen;
325         if (unilen/2 < len)
326                 len = unilen/2;
327         x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
328         lstrcpynAtoW(x,oemstr,len+1);
329         memcpy(unistr,x,len*2);
330         if (reslen) *reslen = len*2;
331         return 0;
332 }
333
334 /**************************************************************************
335  *                 RtlInitString                        [NTDLL]
336  */
337 VOID WINAPI RtlInitAnsiString(LPANSI_STRING target,LPCSTR source)
338 {
339         target->Length = target->MaximumLength = 0;
340         target->Buffer = (LPSTR)source;
341         if (!source)
342                 return;
343         target->Length = lstrlen32A(target->Buffer);
344         target->MaximumLength = target->Length+1;
345 }
346 /**************************************************************************
347  *                 RtlInitString                        [NTDLL]
348  */
349 VOID WINAPI RtlInitString(LPSTRING target,LPCSTR source)
350 {
351         target->Length = target->MaximumLength = 0;
352         target->Buffer = (LPSTR)source;
353         if (!source)
354                 return;
355         target->Length = lstrlen32A(target->Buffer);
356         target->MaximumLength = target->Length+1;
357 }
358
359 /**************************************************************************
360  *                 RtlInitUnicodeString                 [NTDLL]
361  */
362 VOID WINAPI RtlInitUnicodeString(LPUNICODE_STRING target,LPCWSTR source)
363 {
364         target->Length = target->MaximumLength = 0;
365         target->Buffer = (LPWSTR)source;
366         if (!source)
367                 return;
368         target->Length = lstrlen32W(target->Buffer)*2;
369         target->MaximumLength = target->Length+2;
370 }
371
372 /**************************************************************************
373  *                 RtlFreeUnicodeString                 [NTDLL]
374  */
375 VOID WINAPI RtlFreeUnicodeString(LPUNICODE_STRING str)
376 {
377         if (str->Buffer)
378                 HeapFree(GetProcessHeap(),0,str->Buffer);
379 }
380
381 /**************************************************************************
382  *                 RtlUnicodeToOemN                     [NTDLL]
383  */
384 DWORD /* NTSTATUS */ WINAPI RtlUnicodeToOemN(LPSTR oemstr,DWORD oemlen,LPDWORD reslen,LPWSTR unistr,DWORD unilen)
385 {
386         DWORD   len;
387         LPSTR   x;
388
389         len = oemlen;
390         if (unilen/2 < len)
391                 len = unilen/2;
392         x=(LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+1);
393         lstrcpynWtoA(x,unistr,len+1);
394         memcpy(oemstr,x,len);
395         if (reslen) *reslen = len;
396         return 0;
397 }
398
399 /**************************************************************************
400  *                 RtlUnicodeStringToOemString          [NTDLL]
401  */
402 DWORD /* NTSTATUS */ WINAPI RtlUnicodeStringToOemString(LPANSI_STRING oem,LPUNICODE_STRING uni,BOOL32 alloc)
403 {
404         if (alloc) {
405                 oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
406                 oem->MaximumLength = uni->Length/2+1;
407         }
408         oem->Length = uni->Length/2;
409         lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
410         return 0;
411 }
412
413 /**************************************************************************
414  *                 RtlUnicodeStringToAnsiString         [NTDLL]
415  */
416 DWORD /* NTSTATUS */ WINAPI RtlUnicodeStringToAnsiString(LPUNICODE_STRING uni,LPANSI_STRING oem,BOOL32 alloc)
417 {
418         if (alloc) {
419                 oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
420                 oem->MaximumLength = uni->Length/2+1;
421         }
422         oem->Length = uni->Length/2;
423         lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
424         return 0;
425 }
426
427 /**************************************************************************
428  *                 RtlNtStatusToDosErro                 [NTDLL]
429  */
430 DWORD WINAPI RtlNtStatusToDosError(DWORD error)
431 {
432         /* FIXME: map STATUS_ to ERROR_ */
433         return error;
434 }
435
436 /**************************************************************************
437  *                 RtlGetNtProductType                  [NTDLL]
438  */
439 DWORD WINAPI RtlGetNtProductType(LPVOID x)
440 {
441         /* FIXME : find documentation for this one */
442         return 0;
443 }
444
445 /**************************************************************************
446  *                 RtlUpcaseUnicodeString               [NTDLL]
447  */
448 DWORD WINAPI RtlUpcaseUnicodeString(LPUNICODE_STRING dest,LPUNICODE_STRING src,BOOL32 doalloc)
449 {
450         LPWSTR  s,t;
451         DWORD   i,len;
452
453         len = src->Length;
454         if (doalloc) {
455                 dest->MaximumLength = len; 
456                 dest->Buffer = (LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len);
457                 if (!dest->Buffer)
458                         return STATUS_NO_MEMORY;
459
460         }
461         if (dest->MaximumLength < len)
462                 return STATUS_BUFFER_OVERFLOW;
463         s=dest->Buffer;t=src->Buffer;
464         /* len is in bytes */
465         for (i=0;i<len/2;i++)
466                 s[i]=toupper(t[i]);
467         return STATUS_SUCCESS;
468 }
469
470 /**************************************************************************
471  *                 RtlxOemStringToUnicodeSize           [NTDLL]
472  */
473 UINT32 WINAPI RtlxOemStringToUnicodeSize(LPSTRING str)
474 {
475         return str->Length*2+2;
476 }
477
478 /**************************************************************************
479  *                 RtlxAnsiStringToUnicodeSize          [NTDLL]
480  */
481 UINT32 WINAPI RtlxAnsiStringToUnicodeSize(LPANSI_STRING str)
482 {
483         return str->Length*2+2;
484 }
485
486 /**************************************************************************
487  *                 RtlDosPathNameToNtPathName_U         [NTDLL]
488  *
489  * FIXME: convert to UNC or whatever is expected here
490  */
491 BOOL32  WINAPI RtlDosPathNameToNtPathName_U(
492         LPWSTR from,LPUNICODE_STRING us,DWORD x2,DWORD x3)
493 {
494         LPSTR   fromA = HEAP_strdupWtoA(GetProcessHeap(),0,from);
495
496         FIXME(ntdll,"(%s,%p,%08lx,%08lx)\n",fromA,us,x2,x3);
497         if (us)
498                 RtlInitUnicodeString(us,HEAP_strdupW(GetProcessHeap(),0,from));
499         return TRUE;
500 }
501
502 /**************************************************************************
503  *                 NtOpenFile                           [NTDLL]
504  */
505 DWORD WINAPI NtOpenFile(DWORD x1,DWORD flags,DWORD x3,DWORD x4,DWORD alignment,DWORD x6)
506 {
507         FIXME(ntdll,"(%08lx,%08lx,%08lx,%08lx,%08lx,%08lx)\n",
508               x1,flags,x3,x4,alignment,x6);
509         /* returns file io completion status */
510         return 0;
511 }
512
513
514 /**************************************************************************
515  *                 NTDLL_chkstk   (NTDLL.862)
516  */
517 void NTDLL_chkstk(void)
518 {
519     /* FIXME: should subtract %eax bytes from stack pointer */
520 }