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