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