[ADVAPI32]
[reactos.git] / reactos / dll / win32 / advapi32 / sec / ac.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/advapi32/sec/ac.c
6 * PURPOSE: ACL/ACE functions
7 */
8
9 #include <advapi32.h>
10 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
11
12 /* --- ACL --- */
13
14 /*
15 * @implemented
16 */
17 BOOL
18 WINAPI
19 GetAclInformation(PACL pAcl,
20 LPVOID pAclInformation,
21 DWORD nAclInformationLength,
22 ACL_INFORMATION_CLASS dwAclInformationClass)
23 {
24 NTSTATUS Status;
25
26 Status = RtlQueryInformationAcl(pAcl,
27 pAclInformation,
28 nAclInformationLength,
29 dwAclInformationClass);
30 if (!NT_SUCCESS(Status))
31 {
32 SetLastError(RtlNtStatusToDosError(Status));
33 return FALSE;
34 }
35
36 return TRUE;
37 }
38
39
40 /*
41 * @implemented
42 */
43 BOOL
44 WINAPI
45 InitializeAcl(PACL pAcl,
46 DWORD nAclLength,
47 DWORD dwAclRevision)
48 {
49 NTSTATUS Status;
50
51 Status = RtlCreateAcl(pAcl,
52 nAclLength,
53 dwAclRevision);
54 if (!NT_SUCCESS(Status))
55 {
56 SetLastError(RtlNtStatusToDosError(Status));
57 return FALSE;
58 }
59
60 return TRUE;
61 }
62
63
64 /*
65 * @implemented
66 */
67 BOOL
68 WINAPI
69 IsValidAcl(PACL pAcl)
70 {
71 return RtlValidAcl (pAcl);
72 }
73
74
75 /*
76 * @implemented
77 */
78 BOOL
79 WINAPI
80 SetAclInformation(PACL pAcl,
81 LPVOID pAclInformation,
82 DWORD nAclInformationLength,
83 ACL_INFORMATION_CLASS dwAclInformationClass)
84 {
85 NTSTATUS Status;
86
87 Status = RtlSetInformationAcl(pAcl,
88 pAclInformation,
89 nAclInformationLength,
90 dwAclInformationClass);
91 if (!NT_SUCCESS(Status))
92 {
93 SetLastError(RtlNtStatusToDosError(Status));
94 return FALSE;
95 }
96
97 return TRUE;
98 }
99
100
101 /* --- ACE --- */
102
103 /*
104 * @implemented
105 */
106 BOOL
107 WINAPI
108 AddAccessAllowedAce(PACL pAcl,
109 DWORD dwAceRevision,
110 DWORD AccessMask,
111 PSID pSid)
112 {
113 NTSTATUS Status;
114
115 Status = RtlAddAccessAllowedAce(pAcl,
116 dwAceRevision,
117 AccessMask,
118 pSid);
119 if (!NT_SUCCESS(Status))
120 {
121 SetLastError(RtlNtStatusToDosError(Status));
122 return FALSE;
123 }
124
125 return TRUE;
126 }
127
128
129 /*
130 * @implemented
131 */
132 BOOL WINAPI
133 AddAccessAllowedAceEx(PACL pAcl,
134 DWORD dwAceRevision,
135 DWORD AceFlags,
136 DWORD AccessMask,
137 PSID pSid)
138 {
139 NTSTATUS Status;
140
141 Status = RtlAddAccessAllowedAceEx(pAcl,
142 dwAceRevision,
143 AceFlags,
144 AccessMask,
145 pSid);
146 if (!NT_SUCCESS(Status))
147 {
148 SetLastError(RtlNtStatusToDosError(Status));
149 return FALSE;
150 }
151
152 return TRUE;
153 }
154
155
156 /*
157 * @implemented
158 */
159 BOOL
160 WINAPI
161 AddAccessAllowedObjectAce(PACL pAcl,
162 DWORD dwAceRevision,
163 DWORD AceFlags,
164 DWORD AccessMask,
165 GUID *ObjectTypeGuid,
166 GUID *InheritedObjectTypeGuid,
167 PSID pSid)
168 {
169 NTSTATUS Status;
170
171 Status = RtlAddAccessAllowedObjectAce(pAcl,
172 dwAceRevision,
173 AceFlags,
174 AccessMask,
175 ObjectTypeGuid,
176 InheritedObjectTypeGuid,
177 pSid);
178 if (!NT_SUCCESS(Status))
179 {
180 SetLastError(RtlNtStatusToDosError(Status));
181 return FALSE;
182 }
183
184 return TRUE;
185 }
186
187
188 /*
189 * @implemented
190 */
191 BOOL
192 WINAPI
193 AddAccessDeniedAce(PACL pAcl,
194 DWORD dwAceRevision,
195 DWORD AccessMask,
196 PSID pSid)
197 {
198 NTSTATUS Status;
199
200 Status = RtlAddAccessDeniedAce(pAcl,
201 dwAceRevision,
202 AccessMask,
203 pSid);
204 if (!NT_SUCCESS(Status))
205 {
206 SetLastError(RtlNtStatusToDosError(Status));
207 return FALSE;
208 }
209
210 return TRUE;
211 }
212
213
214 /*
215 * @implemented
216 */
217 BOOL WINAPI
218 AddAccessDeniedAceEx(PACL pAcl,
219 DWORD dwAceRevision,
220 DWORD AceFlags,
221 DWORD AccessMask,
222 PSID pSid)
223 {
224 NTSTATUS Status;
225
226 Status = RtlAddAccessDeniedAceEx(pAcl,
227 dwAceRevision,
228 AceFlags,
229 AccessMask,
230 pSid);
231 if (!NT_SUCCESS(Status))
232 {
233 SetLastError(RtlNtStatusToDosError(Status));
234 return FALSE;
235 }
236
237 return TRUE;
238 }
239
240
241 /*
242 * @implemented
243 */
244 BOOL
245 WINAPI
246 AddAccessDeniedObjectAce(PACL pAcl,
247 DWORD dwAceRevision,
248 DWORD AceFlags,
249 DWORD AccessMask,
250 GUID* ObjectTypeGuid,
251 GUID* InheritedObjectTypeGuid,
252 PSID pSid)
253 {
254 NTSTATUS Status;
255
256 Status = RtlAddAccessDeniedObjectAce(pAcl,
257 dwAceRevision,
258 AceFlags,
259 AccessMask,
260 ObjectTypeGuid,
261 InheritedObjectTypeGuid,
262 pSid);
263 if (!NT_SUCCESS(Status))
264 {
265 SetLastError(RtlNtStatusToDosError(Status));
266 return FALSE;
267 }
268
269 return TRUE;
270 }
271
272
273 /*
274 * @implemented
275 */
276 BOOL
277 WINAPI
278 AddAce(PACL pAcl,
279 DWORD dwAceRevision,
280 DWORD dwStartingAceIndex,
281 LPVOID pAceList,
282 DWORD nAceListLength)
283 {
284 NTSTATUS Status;
285
286 Status = RtlAddAce(pAcl,
287 dwAceRevision,
288 dwStartingAceIndex,
289 pAceList,
290 nAceListLength);
291 if (!NT_SUCCESS(Status))
292 {
293 SetLastError(RtlNtStatusToDosError(Status));
294 return FALSE;
295 }
296
297 return TRUE;
298 }
299
300
301 /*
302 * @implemented
303 */
304 BOOL
305 WINAPI
306 AddAuditAccessAce(PACL pAcl,
307 DWORD dwAceRevision,
308 DWORD dwAccessMask,
309 PSID pSid,
310 BOOL bAuditSuccess,
311 BOOL bAuditFailure)
312 {
313 NTSTATUS Status;
314
315 Status = RtlAddAuditAccessAce(pAcl,
316 dwAceRevision,
317 dwAccessMask,
318 pSid,
319 bAuditSuccess,
320 bAuditFailure);
321 if (!NT_SUCCESS(Status))
322 {
323 SetLastError(RtlNtStatusToDosError(Status));
324 return FALSE;
325 }
326
327 return TRUE;
328 }
329
330
331 /*
332 * @implemented
333 */
334 BOOL WINAPI
335 AddAuditAccessAceEx(PACL pAcl,
336 DWORD dwAceRevision,
337 DWORD AceFlags,
338 DWORD dwAccessMask,
339 PSID pSid,
340 BOOL bAuditSuccess,
341 BOOL bAuditFailure)
342 {
343 NTSTATUS Status;
344
345 Status = RtlAddAuditAccessAceEx(pAcl,
346 dwAceRevision,
347 AceFlags,
348 dwAccessMask,
349 pSid,
350 bAuditSuccess,
351 bAuditFailure);
352 if (!NT_SUCCESS(Status))
353 {
354 SetLastError(RtlNtStatusToDosError(Status));
355 return FALSE;
356 }
357
358 return TRUE;
359 }
360
361
362 /*
363 * @implemented
364 */
365 BOOL
366 WINAPI
367 AddAuditAccessObjectAce(PACL pAcl,
368 DWORD dwAceRevision,
369 DWORD AceFlags,
370 DWORD AccessMask,
371 GUID *ObjectTypeGuid,
372 GUID *InheritedObjectTypeGuid,
373 PSID pSid,
374 BOOL bAuditSuccess,
375 BOOL bAuditFailure)
376 {
377 NTSTATUS Status;
378
379 Status = RtlAddAuditAccessObjectAce(pAcl,
380 dwAceRevision,
381 AceFlags,
382 AccessMask,
383 ObjectTypeGuid,
384 InheritedObjectTypeGuid,
385 pSid,
386 bAuditSuccess,
387 bAuditFailure);
388 if (!NT_SUCCESS(Status))
389 {
390 SetLastError(RtlNtStatusToDosError(Status));
391 return FALSE;
392 }
393
394 return TRUE;
395 }
396
397 /*
398 * @implemented
399 */
400 BOOL
401 WINAPI
402 DeleteAce(PACL pAcl,
403 DWORD dwAceIndex)
404 {
405 NTSTATUS Status;
406
407 Status = RtlDeleteAce(pAcl,
408 dwAceIndex);
409 if (!NT_SUCCESS(Status))
410 {
411 SetLastError(RtlNtStatusToDosError(Status));
412 return FALSE;
413 }
414
415 return TRUE;
416 }
417
418
419 /*
420 * @implemented
421 */
422 BOOL
423 WINAPI
424 FindFirstFreeAce(PACL pAcl,
425 LPVOID *pAce)
426 {
427 return RtlFirstFreeAce(pAcl,
428 (PACE*)pAce);
429 }
430
431
432 /*
433 * @implemented
434 */
435 BOOL
436 WINAPI
437 GetAce(PACL pAcl,
438 DWORD dwAceIndex,
439 LPVOID *pAce)
440 {
441 NTSTATUS Status;
442
443 Status = RtlGetAce(pAcl,
444 dwAceIndex,
445 pAce);
446 if (!NT_SUCCESS(Status))
447 {
448 SetLastError(RtlNtStatusToDosError(Status));
449 return FALSE;
450 }
451
452 return TRUE;
453 }
454
455
456 /*
457 * @implemented
458 */
459 DWORD
460 WINAPI
461 GetInheritanceSourceW(LPWSTR pObjectName,
462 SE_OBJECT_TYPE ObjectType,
463 SECURITY_INFORMATION SecurityInfo,
464 BOOL Container,
465 GUID **pObjectClassGuids OPTIONAL,
466 DWORD GuidCount,
467 PACL pAcl,
468 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL,
469 PGENERIC_MAPPING pGenericMapping,
470 PINHERITED_FROMW pInheritArray)
471 {
472 DWORD ErrorCode;
473
474 ErrorCode = CheckNtMartaPresent();
475 if (ErrorCode == ERROR_SUCCESS)
476 {
477 /* call the MARTA provider */
478 ErrorCode = AccGetInheritanceSource(pObjectName,
479 ObjectType,
480 SecurityInfo,
481 Container,
482 pObjectClassGuids,
483 GuidCount,
484 pAcl,
485 pfnArray,
486 pGenericMapping,
487 pInheritArray);
488 }
489
490 return ErrorCode;
491 }
492
493
494 /*
495 * @unimplemented
496 */
497 DWORD
498 WINAPI
499 GetInheritanceSourceA(LPSTR pObjectName,
500 SE_OBJECT_TYPE ObjectType,
501 SECURITY_INFORMATION SecurityInfo,
502 BOOL Container,
503 GUID **pObjectClassGuids OPTIONAL,
504 DWORD GuidCount,
505 PACL pAcl,
506 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL,
507 PGENERIC_MAPPING pGenericMapping,
508 PINHERITED_FROMA pInheritArray)
509 {
510 /* That's all this function does, at least up to w2k3... Even MS was too
511 lazy to implement it... */
512 return ERROR_CALL_NOT_IMPLEMENTED;
513 }
514
515
516 /*
517 * @implemented
518 */
519 DWORD
520 WINAPI
521 FreeInheritedFromArray(PINHERITED_FROMW pInheritArray,
522 USHORT AceCnt,
523 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL)
524 {
525 DWORD ErrorCode;
526
527 ErrorCode = CheckNtMartaPresent();
528 if (ErrorCode == ERROR_SUCCESS)
529 {
530 /* call the MARTA provider */
531 ErrorCode = AccFreeIndexArray(pInheritArray,
532 AceCnt,
533 pfnArray);
534 }
535
536 return ErrorCode;
537 }
538
539
540 /*
541 * @implemented
542 */
543 DWORD
544 WINAPI
545 SetEntriesInAclW(ULONG cCountOfExplicitEntries,
546 PEXPLICIT_ACCESS_W pListOfExplicitEntries,
547 PACL OldAcl,
548 PACL *NewAcl)
549 {
550 DWORD ErrorCode;
551
552 if (!NewAcl)
553 {
554 return ERROR_INVALID_PARAMETER;
555 }
556
557 ErrorCode = CheckNtMartaPresent();
558 if (ErrorCode == ERROR_SUCCESS)
559 {
560 /* call the MARTA provider */
561 ErrorCode = AccRewriteSetEntriesInAcl(cCountOfExplicitEntries,
562 pListOfExplicitEntries,
563 OldAcl,
564 NewAcl);
565 }
566
567 return ErrorCode;
568 }
569
570
571 static DWORD
572 InternalTrusteeAToW(IN PTRUSTEE_A pTrusteeA,
573 OUT PTRUSTEE_W *pTrusteeW)
574 {
575 TRUSTEE_FORM TrusteeForm;
576 INT BufferSize = 0;
577 PSTR lpStr;
578 DWORD ErrorCode = ERROR_SUCCESS;
579
580 //ASSERT(sizeof(TRUSTEE_W) == sizeof(TRUSTEE_A));
581
582 TrusteeForm = GetTrusteeFormA(pTrusteeA);
583 switch (TrusteeForm)
584 {
585 case TRUSTEE_IS_NAME:
586 {
587 /* directly copy the array, this works as the size of the EXPLICIT_ACCESS_A
588 structure matches the size of the EXPLICIT_ACCESS_W version */
589 lpStr = GetTrusteeNameA(pTrusteeA);
590 if (lpStr != NULL)
591 BufferSize = strlen(lpStr) + 1;
592
593 *pTrusteeW = RtlAllocateHeap(RtlGetProcessHeap(),
594 0,
595 sizeof(TRUSTEE_W) + (BufferSize * sizeof(WCHAR)));
596 if (*pTrusteeW != NULL)
597 {
598 RtlCopyMemory(*pTrusteeW,
599 pTrusteeA,
600 FIELD_OFFSET(TRUSTEE_A,
601 ptstrName));
602
603 if (lpStr != NULL)
604 {
605 (*pTrusteeW)->ptstrName = (PWSTR)((*pTrusteeW) + 1);
606
607 /* convert the trustee's name */
608 if (MultiByteToWideChar(CP_ACP,
609 0,
610 lpStr,
611 -1,
612 (*pTrusteeW)->ptstrName,
613 BufferSize) == 0)
614 {
615 goto ConvertErr;
616 }
617 }
618 else
619 {
620 RtlFreeHeap(RtlGetProcessHeap(),
621 0,
622 *pTrusteeW);
623 goto NothingToConvert;
624 }
625 }
626 else
627 ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
628 break;
629 }
630
631 case TRUSTEE_IS_OBJECTS_AND_NAME:
632 {
633 POBJECTS_AND_NAME_A oanA = (POBJECTS_AND_NAME_A)GetTrusteeNameA(pTrusteeA);
634 POBJECTS_AND_NAME_W oan;
635 PWSTR StrBuf;
636
637 /* calculate the size needed */
638 if ((oanA->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
639 oanA->InheritedObjectTypeName != NULL)
640 {
641 BufferSize = strlen(oanA->InheritedObjectTypeName) + 1;
642 }
643 if (oanA->ptstrName != NULL)
644 {
645 BufferSize += strlen(oanA->ptstrName) + 1;
646 }
647
648 *pTrusteeW = RtlAllocateHeap(RtlGetProcessHeap(),
649 0,
650 sizeof(TRUSTEE_W) + sizeof(OBJECTS_AND_NAME_W) +
651 (BufferSize * sizeof(WCHAR)));
652
653 if (*pTrusteeW != NULL)
654 {
655 oan = (POBJECTS_AND_NAME_W)((*pTrusteeW) + 1);
656 StrBuf = (PWSTR)(oan + 1);
657
658 /* copy over the parts of the TRUSTEE structure that don't need
659 to be touched */
660 RtlCopyMemory(*pTrusteeW,
661 pTrusteeA,
662 FIELD_OFFSET(TRUSTEE_A,
663 ptstrName));
664
665 (*pTrusteeW)->ptstrName = (LPWSTR)oan;
666
667 /* convert the OBJECTS_AND_NAME_A structure */
668 oan->ObjectsPresent = oanA->ObjectsPresent;
669 oan->ObjectType = oanA->ObjectType;
670
671 if ((oanA->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
672 oanA->InheritedObjectTypeName != NULL)
673 {
674 /* convert inherited object type name */
675 BufferSize = strlen(oanA->InheritedObjectTypeName) + 1;
676
677 if (MultiByteToWideChar(CP_ACP,
678 0,
679 oanA->InheritedObjectTypeName,
680 -1,
681 StrBuf,
682 BufferSize) == 0)
683 {
684 goto ConvertErr;
685 }
686 oan->InheritedObjectTypeName = StrBuf;
687
688 StrBuf += BufferSize;
689 }
690 else
691 oan->InheritedObjectTypeName = NULL;
692
693 if (oanA->ptstrName != NULL)
694 {
695 /* convert the trustee name */
696 BufferSize = strlen(oanA->ptstrName) + 1;
697
698 if (MultiByteToWideChar(CP_ACP,
699 0,
700 oanA->ptstrName,
701 -1,
702 StrBuf,
703 BufferSize) == 0)
704 {
705 goto ConvertErr;
706 }
707 oan->ptstrName = StrBuf;
708 }
709 else
710 oan->ptstrName = NULL;
711 }
712 else
713 ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
714 break;
715 }
716
717 default:
718 {
719 NothingToConvert:
720 /* no need to convert anything to unicode */
721 *pTrusteeW = (PTRUSTEE_W)pTrusteeA;
722 break;
723 }
724 }
725
726 return ErrorCode;
727
728 ConvertErr:
729 ErrorCode = GetLastError();
730
731 /* cleanup */
732 RtlFreeHeap(RtlGetProcessHeap(),
733 0,
734 *pTrusteeW);
735
736 return ErrorCode;
737 }
738
739
740 static __inline VOID
741 InternalFreeConvertedTrustee(IN PTRUSTEE_W pTrusteeW,
742 IN PTRUSTEE_A pTrusteeA)
743 {
744 if ((PVOID)pTrusteeW != (PVOID)pTrusteeA)
745 {
746 RtlFreeHeap(RtlGetProcessHeap(),
747 0,
748 pTrusteeW);
749 }
750 }
751
752
753 static DWORD
754 InternalExplicitAccessAToW(IN ULONG cCountOfExplicitEntries,
755 IN PEXPLICIT_ACCESS_A pListOfExplicitEntriesA,
756 OUT PEXPLICIT_ACCESS_W *pListOfExplicitEntriesW)
757 {
758 TRUSTEE_FORM TrusteeForm;
759 SIZE_T Size;
760 ULONG i;
761 ULONG ObjectsAndNameCount = 0;
762 PEXPLICIT_ACCESS_W peaw = NULL;
763 DWORD ErrorCode = ERROR_SUCCESS;
764 LPSTR lpStr;
765
766 /* NOTE: This code assumes that the size of the TRUSTEE_A and TRUSTEE_W structure matches! */
767 //ASSERT(sizeof(TRUSTEE_A) == sizeof(TRUSTEE_W));
768
769 if (cCountOfExplicitEntries != 0)
770 {
771 /* calculate the size needed */
772 Size = cCountOfExplicitEntries * sizeof(EXPLICIT_ACCESS_W);
773 for (i = 0; i != cCountOfExplicitEntries; i++)
774 {
775 TrusteeForm = GetTrusteeFormA(&pListOfExplicitEntriesA[i].Trustee);
776
777 switch (TrusteeForm)
778 {
779 case TRUSTEE_IS_NAME:
780 {
781 lpStr = GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
782 if (lpStr != NULL)
783 Size += (strlen(lpStr) + 1) * sizeof(WCHAR);
784 break;
785 }
786
787 case TRUSTEE_IS_OBJECTS_AND_NAME:
788 {
789 POBJECTS_AND_NAME_A oan = (POBJECTS_AND_NAME_A)GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
790
791 if ((oan->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
792 oan->InheritedObjectTypeName != NULL)
793 {
794 Size += (strlen(oan->InheritedObjectTypeName) + 1) * sizeof(WCHAR);
795 }
796
797 if (oan->ptstrName != NULL)
798 Size += (strlen(oan->ptstrName) + 1) * sizeof(WCHAR);
799
800 ObjectsAndNameCount++;
801 break;
802 }
803
804 default:
805 break;
806 }
807 }
808
809 /* allocate the array */
810 peaw = RtlAllocateHeap(RtlGetProcessHeap(),
811 0,
812 Size);
813 if (peaw != NULL)
814 {
815 INT BufferSize;
816 POBJECTS_AND_NAME_W oan = (POBJECTS_AND_NAME_W)(peaw + cCountOfExplicitEntries);
817 LPWSTR StrBuf = (LPWSTR)(oan + ObjectsAndNameCount);
818
819 /* convert the array to unicode */
820 for (i = 0; i != cCountOfExplicitEntries; i++)
821 {
822 peaw[i].grfAccessPermissions = pListOfExplicitEntriesA[i].grfAccessPermissions;
823 peaw[i].grfAccessMode = pListOfExplicitEntriesA[i].grfAccessMode;
824 peaw[i].grfInheritance = pListOfExplicitEntriesA[i].grfInheritance;
825
826 /* convert or copy the TRUSTEE structure */
827 TrusteeForm = GetTrusteeFormA(&pListOfExplicitEntriesA[i].Trustee);
828 switch (TrusteeForm)
829 {
830 case TRUSTEE_IS_NAME:
831 {
832 lpStr = GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
833 if (lpStr != NULL)
834 {
835 /* convert the trustee name */
836 BufferSize = strlen(lpStr) + 1;
837
838 if (MultiByteToWideChar(CP_ACP,
839 0,
840 lpStr,
841 -1,
842 StrBuf,
843 BufferSize) == 0)
844 {
845 goto ConvertErr;
846 }
847 peaw[i].Trustee.ptstrName = StrBuf;
848
849 StrBuf += BufferSize;
850 }
851 else
852 goto RawTrusteeCopy;
853
854 break;
855 }
856
857 case TRUSTEE_IS_OBJECTS_AND_NAME:
858 {
859 POBJECTS_AND_NAME_A oanA = (POBJECTS_AND_NAME_A)GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
860
861 /* copy over the parts of the TRUSTEE structure that don't need
862 to be touched */
863 RtlCopyMemory(&peaw[i].Trustee,
864 &pListOfExplicitEntriesA[i].Trustee,
865 FIELD_OFFSET(TRUSTEE_A,
866 ptstrName));
867
868 peaw[i].Trustee.ptstrName = (LPWSTR)oan;
869
870 /* convert the OBJECTS_AND_NAME_A structure */
871 oan->ObjectsPresent = oanA->ObjectsPresent;
872 oan->ObjectType = oanA->ObjectType;
873
874 if ((oanA->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
875 oanA->InheritedObjectTypeName != NULL)
876 {
877 /* convert inherited object type name */
878 BufferSize = strlen(oanA->InheritedObjectTypeName) + 1;
879
880 if (MultiByteToWideChar(CP_ACP,
881 0,
882 oanA->InheritedObjectTypeName,
883 -1,
884 StrBuf,
885 BufferSize) == 0)
886 {
887 goto ConvertErr;
888 }
889 oan->InheritedObjectTypeName = StrBuf;
890
891 StrBuf += BufferSize;
892 }
893 else
894 oan->InheritedObjectTypeName = NULL;
895
896 if (oanA->ptstrName != NULL)
897 {
898 /* convert the trustee name */
899 BufferSize = strlen(oanA->ptstrName) + 1;
900
901 if (MultiByteToWideChar(CP_ACP,
902 0,
903 oanA->ptstrName,
904 -1,
905 StrBuf,
906 BufferSize) == 0)
907 {
908 goto ConvertErr;
909 }
910 oan->ptstrName = StrBuf;
911
912 StrBuf += BufferSize;
913 }
914 else
915 oan->ptstrName = NULL;
916
917 /* move on to the next OBJECTS_AND_NAME_A structure */
918 oan++;
919 break;
920 }
921
922 default:
923 {
924 RawTrusteeCopy:
925 /* just copy over the TRUSTEE structure, they don't contain any
926 ansi/unicode specific data */
927 RtlCopyMemory(&peaw[i].Trustee,
928 &pListOfExplicitEntriesA[i].Trustee,
929 sizeof(TRUSTEE_A));
930 break;
931 }
932 }
933 }
934
935 ASSERT(ErrorCode == ERROR_SUCCESS);
936 *pListOfExplicitEntriesW = peaw;
937 }
938 else
939 ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
940 }
941
942 return ErrorCode;
943
944 ConvertErr:
945 ErrorCode = GetLastError();
946
947 /* cleanup */
948 RtlFreeHeap(RtlGetProcessHeap(),
949 0,
950 peaw);
951
952 return ErrorCode;
953 }
954
955
956 /*
957 * @implemented
958 */
959 DWORD
960 WINAPI
961 SetEntriesInAclA(ULONG cCountOfExplicitEntries,
962 PEXPLICIT_ACCESS_A pListOfExplicitEntries,
963 PACL OldAcl,
964 PACL *NewAcl)
965 {
966 PEXPLICIT_ACCESS_W ListOfExplicitEntriesW = NULL;
967 DWORD ErrorCode;
968
969 ErrorCode = InternalExplicitAccessAToW(cCountOfExplicitEntries,
970 pListOfExplicitEntries,
971 &ListOfExplicitEntriesW);
972 if (ErrorCode == ERROR_SUCCESS)
973 {
974 ErrorCode = SetEntriesInAclW(cCountOfExplicitEntries,
975 ListOfExplicitEntriesW,
976 OldAcl,
977 NewAcl);
978
979 /* free the allocated array */
980 RtlFreeHeap(RtlGetProcessHeap(),
981 0,
982 ListOfExplicitEntriesW);
983 }
984
985 return ErrorCode;
986 }
987
988
989 /*
990 * @implemented
991 */
992 DWORD
993 WINAPI
994 GetExplicitEntriesFromAclW(PACL pacl,
995 PULONG pcCountOfExplicitEntries,
996 PEXPLICIT_ACCESS_W *pListOfExplicitEntries)
997 {
998 DWORD ErrorCode;
999
1000 ErrorCode = CheckNtMartaPresent();
1001 if (ErrorCode == ERROR_SUCCESS)
1002 {
1003 /* call the MARTA provider */
1004 ErrorCode = AccRewriteGetExplicitEntriesFromAcl(pacl,
1005 pcCountOfExplicitEntries,
1006 pListOfExplicitEntries);
1007 }
1008
1009 return ErrorCode;
1010 }
1011
1012
1013 /*
1014 * @unimplemented
1015 */
1016 DWORD
1017 WINAPI
1018 GetEffectiveRightsFromAclW(IN PACL pacl,
1019 IN PTRUSTEE_W pTrustee,
1020 OUT PACCESS_MASK pAccessRights)
1021 {
1022 FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1023
1024 *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1025 return ERROR_SUCCESS;
1026 }
1027
1028
1029 /*
1030 * @implemented
1031 */
1032 DWORD
1033 WINAPI
1034 GetEffectiveRightsFromAclA(IN PACL pacl,
1035 IN PTRUSTEE_A pTrustee,
1036 OUT PACCESS_MASK pAccessRights)
1037 {
1038 PTRUSTEE_W pTrusteeW = NULL;
1039 DWORD ErrorCode;
1040
1041 ErrorCode = InternalTrusteeAToW(pTrustee,
1042 &pTrusteeW);
1043 if (ErrorCode == ERROR_SUCCESS)
1044 {
1045 ErrorCode = GetEffectiveRightsFromAclW(pacl,
1046 pTrusteeW,
1047 pAccessRights);
1048
1049 InternalFreeConvertedTrustee(pTrusteeW,
1050 pTrustee);
1051 }
1052 else
1053 ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
1054
1055 return ErrorCode;
1056 }
1057
1058
1059 /*
1060 * @unimplemented
1061 */
1062 DWORD
1063 WINAPI
1064 GetAuditedPermissionsFromAclW(IN PACL pacl,
1065 IN PTRUSTEE_W pTrustee,
1066 OUT PACCESS_MASK pSuccessfulAuditedRights,
1067 OUT PACCESS_MASK pFailedAuditRights)
1068 {
1069 FIXME("%s() not implemented!\n", __FUNCTION__);
1070 return ERROR_CALL_NOT_IMPLEMENTED;
1071 }
1072
1073
1074 /*
1075 * @implemented
1076 */
1077 DWORD
1078 WINAPI
1079 GetAuditedPermissionsFromAclA(IN PACL pacl,
1080 IN PTRUSTEE_A pTrustee,
1081 OUT PACCESS_MASK pSuccessfulAuditedRights,
1082 OUT PACCESS_MASK pFailedAuditRights)
1083 {
1084 PTRUSTEE_W pTrusteeW = NULL;
1085 DWORD ErrorCode;
1086
1087 ErrorCode = InternalTrusteeAToW(pTrustee,
1088 &pTrusteeW);
1089 if (ErrorCode == ERROR_SUCCESS)
1090 {
1091 ErrorCode = GetAuditedPermissionsFromAclW(pacl,
1092 pTrusteeW,
1093 pSuccessfulAuditedRights,
1094 pFailedAuditRights);
1095
1096 InternalFreeConvertedTrustee(pTrusteeW,
1097 pTrustee);
1098 }
1099 else
1100 ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
1101
1102 return ErrorCode;
1103 }
1104
1105 /* EOF */