[MMEBUDDY]
[reactos.git] / reactos / dll / win32 / advapi32 / sec / misc.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * WINE COPYRIGHT:
4 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
5 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
6 * Copyright 2006 Robert Reif
7 *
8 * PROJECT: ReactOS system libraries
9 * FILE: dll/win32/advapi32/sec/misc.c
10 * PURPOSE: Miscellaneous security functions (some ported from Wine)
11 */
12
13 #include <advapi32.h>
14 #include "wine/unicode.h"
15 #include "wine/debug.h"
16
17 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
18
19
20 /* Interface to ntmarta.dll ***************************************************/
21
22 NTMARTA NtMartaStatic = { 0 };
23 static PNTMARTA NtMarta = NULL;
24
25 #define FindNtMartaProc(Name) \
26 NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \
27 "Acc" # Name ); \
28 if (NtMartaStatic.Name == NULL) \
29 { \
30 return GetLastError(); \
31 }
32
33
34 static DWORD
35 LoadAndInitializeNtMarta(VOID)
36 {
37 /* this code may be executed simultaneously by multiple threads in case they're
38 trying to initialize the interface at the same time, but that's no problem
39 because the pointers returned by GetProcAddress will be the same. However,
40 only one of the threads will change the NtMarta pointer to the NtMartaStatic
41 structure, the others threads will detect that there were other threads
42 initializing the structure faster and will release the reference to the
43 DLL */
44
45 NtMartaStatic.hDllInstance = LoadLibraryW(L"ntmarta.dll");
46 if (NtMartaStatic.hDllInstance == NULL)
47 {
48 return GetLastError();
49 }
50
51 #if 0
52 FindNtMartaProc(LookupAccountTrustee);
53 FindNtMartaProc(LookupAccountName);
54 FindNtMartaProc(LookupAccountSid);
55 FindNtMartaProc(SetEntriesInAList);
56 FindNtMartaProc(ConvertAccessToSecurityDescriptor);
57 FindNtMartaProc(ConvertSDToAccess);
58 FindNtMartaProc(ConvertAclToAccess);
59 FindNtMartaProc(GetAccessForTrustee);
60 FindNtMartaProc(GetExplicitEntries);
61 #endif
62 FindNtMartaProc(RewriteGetNamedRights);
63 FindNtMartaProc(RewriteSetNamedRights);
64 FindNtMartaProc(RewriteGetHandleRights);
65 FindNtMartaProc(RewriteSetHandleRights);
66 FindNtMartaProc(RewriteSetEntriesInAcl);
67 FindNtMartaProc(RewriteGetExplicitEntriesFromAcl);
68 FindNtMartaProc(TreeResetNamedSecurityInfo);
69 FindNtMartaProc(GetInheritanceSource);
70 FindNtMartaProc(FreeIndexArray);
71
72 return ERROR_SUCCESS;
73 }
74
75
76 DWORD
77 CheckNtMartaPresent(VOID)
78 {
79 DWORD ErrorCode;
80
81 if (InterlockedCompareExchangePointer((PVOID)&NtMarta,
82 NULL,
83 NULL) == NULL)
84 {
85 /* we're the first one trying to use ntmarta, initialize it and change
86 the pointer after initialization */
87 ErrorCode = LoadAndInitializeNtMarta();
88
89 if (ErrorCode == ERROR_SUCCESS)
90 {
91 /* try change the NtMarta pointer */
92 if (InterlockedCompareExchangePointer((PVOID)&NtMarta,
93 &NtMartaStatic,
94 NULL) != NULL)
95 {
96 /* another thread initialized ntmarta in the meanwhile, release
97 the reference of the dll loaded. */
98 FreeLibrary(NtMartaStatic.hDllInstance);
99 }
100 }
101 #if DBG
102 else
103 {
104 ERR("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode);
105 }
106 #endif
107 }
108 else
109 {
110 /* ntmarta was already initialized */
111 ErrorCode = ERROR_SUCCESS;
112 }
113
114 return ErrorCode;
115 }
116
117
118 VOID
119 UnloadNtMarta(VOID)
120 {
121 if (InterlockedExchangePointer((PVOID)&NtMarta,
122 NULL) != NULL)
123 {
124 FreeLibrary(NtMartaStatic.hDllInstance);
125 }
126 }
127
128
129 /******************************************************************************/
130
131 /*
132 * @implemented
133 */
134 BOOL
135 WINAPI
136 AreAllAccessesGranted(DWORD GrantedAccess,
137 DWORD DesiredAccess)
138 {
139 return (BOOL)RtlAreAllAccessesGranted(GrantedAccess,
140 DesiredAccess);
141 }
142
143
144 /*
145 * @implemented
146 */
147 BOOL
148 WINAPI
149 AreAnyAccessesGranted(DWORD GrantedAccess,
150 DWORD DesiredAccess)
151 {
152 return (BOOL)RtlAreAnyAccessesGranted(GrantedAccess,
153 DesiredAccess);
154 }
155
156
157 /************************************************************
158 * ADVAPI_IsLocalComputer
159 *
160 * Checks whether the server name indicates local machine.
161 */
162 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
163 {
164 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
165 BOOL Result;
166 LPWSTR buf;
167
168 if (!ServerName || !ServerName[0])
169 return TRUE;
170
171 buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
172 Result = GetComputerNameW(buf, &dwSize);
173 if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
174 ServerName += 2;
175 Result = Result && !lstrcmpW(ServerName, buf);
176 HeapFree(GetProcessHeap(), 0, buf);
177
178 return Result;
179 }
180
181
182 /******************************************************************************
183 * GetFileSecurityA [ADVAPI32.@]
184 *
185 * Obtains Specified information about the security of a file or directory.
186 *
187 * PARAMS
188 * lpFileName [I] Name of the file to get info for
189 * RequestedInformation [I] SE_ flags from "winnt.h"
190 * pSecurityDescriptor [O] Destination for security information
191 * nLength [I] Length of pSecurityDescriptor
192 * lpnLengthNeeded [O] Destination for length of returned security information
193 *
194 * RETURNS
195 * Success: TRUE. pSecurityDescriptor contains the requested information.
196 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
197 *
198 * NOTES
199 * The information returned is constrained by the callers access rights and
200 * privileges.
201 *
202 * @implemented
203 */
204 BOOL
205 WINAPI
206 GetFileSecurityA(LPCSTR lpFileName,
207 SECURITY_INFORMATION RequestedInformation,
208 PSECURITY_DESCRIPTOR pSecurityDescriptor,
209 DWORD nLength,
210 LPDWORD lpnLengthNeeded)
211 {
212 UNICODE_STRING FileName;
213 NTSTATUS Status;
214 BOOL bResult;
215
216 Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
217 (LPSTR)lpFileName);
218 if (!NT_SUCCESS(Status))
219 {
220 SetLastError(RtlNtStatusToDosError(Status));
221 return FALSE;
222 }
223
224 bResult = GetFileSecurityW(FileName.Buffer,
225 RequestedInformation,
226 pSecurityDescriptor,
227 nLength,
228 lpnLengthNeeded);
229
230 RtlFreeUnicodeString(&FileName);
231
232 return bResult;
233 }
234
235
236 /*
237 * @implemented
238 */
239 BOOL
240 WINAPI
241 GetFileSecurityW(LPCWSTR lpFileName,
242 SECURITY_INFORMATION RequestedInformation,
243 PSECURITY_DESCRIPTOR pSecurityDescriptor,
244 DWORD nLength,
245 LPDWORD lpnLengthNeeded)
246 {
247 OBJECT_ATTRIBUTES ObjectAttributes;
248 IO_STATUS_BLOCK StatusBlock;
249 UNICODE_STRING FileName;
250 ULONG AccessMask = 0;
251 HANDLE FileHandle;
252 NTSTATUS Status;
253
254 TRACE("GetFileSecurityW() called\n");
255
256 QuerySecurityAccessMask(RequestedInformation, &AccessMask);
257
258 if (!RtlDosPathNameToNtPathName_U(lpFileName,
259 &FileName,
260 NULL,
261 NULL))
262 {
263 ERR("Invalid path\n");
264 SetLastError(ERROR_INVALID_NAME);
265 return FALSE;
266 }
267
268 InitializeObjectAttributes(&ObjectAttributes,
269 &FileName,
270 OBJ_CASE_INSENSITIVE,
271 NULL,
272 NULL);
273
274 Status = NtOpenFile(&FileHandle,
275 AccessMask,
276 &ObjectAttributes,
277 &StatusBlock,
278 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
279 0);
280
281 RtlFreeHeap(RtlGetProcessHeap(),
282 0,
283 FileName.Buffer);
284
285 if (!NT_SUCCESS(Status))
286 {
287 ERR("NtOpenFile() failed (Status %lx)\n", Status);
288 SetLastError(RtlNtStatusToDosError(Status));
289 return FALSE;
290 }
291
292 Status = NtQuerySecurityObject(FileHandle,
293 RequestedInformation,
294 pSecurityDescriptor,
295 nLength,
296 lpnLengthNeeded);
297 NtClose(FileHandle);
298 if (!NT_SUCCESS(Status))
299 {
300 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status);
301 SetLastError(RtlNtStatusToDosError(Status));
302 return FALSE;
303 }
304
305 return TRUE;
306 }
307
308
309 /*
310 * @implemented
311 */
312 BOOL
313 WINAPI
314 GetKernelObjectSecurity(HANDLE Handle,
315 SECURITY_INFORMATION RequestedInformation,
316 PSECURITY_DESCRIPTOR pSecurityDescriptor,
317 DWORD nLength,
318 LPDWORD lpnLengthNeeded)
319 {
320 NTSTATUS Status;
321
322 Status = NtQuerySecurityObject(Handle,
323 RequestedInformation,
324 pSecurityDescriptor,
325 nLength,
326 lpnLengthNeeded);
327 if (!NT_SUCCESS(Status))
328 {
329 SetLastError(RtlNtStatusToDosError(Status));
330 return FALSE;
331 }
332
333 return TRUE;
334 }
335
336
337 /******************************************************************************
338 * SetFileSecurityA [ADVAPI32.@]
339 * Sets the security of a file or directory
340 *
341 * @implemented
342 */
343 BOOL
344 WINAPI
345 SetFileSecurityA(LPCSTR lpFileName,
346 SECURITY_INFORMATION SecurityInformation,
347 PSECURITY_DESCRIPTOR pSecurityDescriptor)
348 {
349 UNICODE_STRING FileName;
350 NTSTATUS Status;
351 BOOL bResult;
352
353 Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
354 (LPSTR)lpFileName);
355 if (!NT_SUCCESS(Status))
356 {
357 SetLastError(RtlNtStatusToDosError(Status));
358 return FALSE;
359 }
360
361 bResult = SetFileSecurityW(FileName.Buffer,
362 SecurityInformation,
363 pSecurityDescriptor);
364
365 RtlFreeUnicodeString(&FileName);
366
367 return bResult;
368 }
369
370
371 /******************************************************************************
372 * SetFileSecurityW [ADVAPI32.@]
373 * Sets the security of a file or directory
374 *
375 * @implemented
376 */
377 BOOL
378 WINAPI
379 SetFileSecurityW(LPCWSTR lpFileName,
380 SECURITY_INFORMATION SecurityInformation,
381 PSECURITY_DESCRIPTOR pSecurityDescriptor)
382 {
383 OBJECT_ATTRIBUTES ObjectAttributes;
384 IO_STATUS_BLOCK StatusBlock;
385 UNICODE_STRING FileName;
386 ULONG AccessMask = 0;
387 HANDLE FileHandle;
388 NTSTATUS Status;
389
390 TRACE("SetFileSecurityW() called\n");
391
392 SetSecurityAccessMask(SecurityInformation, &AccessMask);
393
394 if (!RtlDosPathNameToNtPathName_U(lpFileName,
395 &FileName,
396 NULL,
397 NULL))
398 {
399 ERR("Invalid path\n");
400 SetLastError(ERROR_INVALID_NAME);
401 return FALSE;
402 }
403
404 InitializeObjectAttributes(&ObjectAttributes,
405 &FileName,
406 OBJ_CASE_INSENSITIVE,
407 NULL,
408 NULL);
409
410 Status = NtOpenFile(&FileHandle,
411 AccessMask,
412 &ObjectAttributes,
413 &StatusBlock,
414 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
415 0);
416
417 RtlFreeHeap(RtlGetProcessHeap(),
418 0,
419 FileName.Buffer);
420
421 if (!NT_SUCCESS(Status))
422 {
423 ERR("NtOpenFile() failed (Status %lx)\n", Status);
424 SetLastError(RtlNtStatusToDosError(Status));
425 return FALSE;
426 }
427
428 Status = NtSetSecurityObject(FileHandle,
429 SecurityInformation,
430 pSecurityDescriptor);
431 NtClose(FileHandle);
432
433 if (!NT_SUCCESS(Status))
434 {
435 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status);
436 SetLastError(RtlNtStatusToDosError(Status));
437 return FALSE;
438 }
439
440 return TRUE;
441 }
442
443
444 /*
445 * @implemented
446 */
447 BOOL
448 WINAPI
449 SetKernelObjectSecurity(HANDLE Handle,
450 SECURITY_INFORMATION SecurityInformation,
451 PSECURITY_DESCRIPTOR SecurityDescriptor)
452 {
453 NTSTATUS Status;
454
455 Status = NtSetSecurityObject(Handle,
456 SecurityInformation,
457 SecurityDescriptor);
458 if (!NT_SUCCESS(Status))
459 {
460 SetLastError(RtlNtStatusToDosError(Status));
461 return FALSE;
462 }
463
464 return TRUE;
465 }
466
467
468 /*
469 * @implemented
470 */
471 BOOL
472 WINAPI
473 ImpersonateAnonymousToken(IN HANDLE ThreadHandle)
474 {
475 NTSTATUS Status;
476
477 Status = NtImpersonateAnonymousToken(ThreadHandle);
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 BOOL
492 WINAPI
493 ImpersonateLoggedOnUser(HANDLE hToken)
494 {
495 SECURITY_QUALITY_OF_SERVICE Qos;
496 OBJECT_ATTRIBUTES ObjectAttributes;
497 HANDLE NewToken;
498 TOKEN_TYPE Type;
499 ULONG ReturnLength;
500 BOOL Duplicated;
501 NTSTATUS Status;
502
503 /* Get the token type */
504 Status = NtQueryInformationToken(hToken,
505 TokenType,
506 &Type,
507 sizeof(TOKEN_TYPE),
508 &ReturnLength);
509 if (!NT_SUCCESS(Status))
510 {
511 SetLastError(RtlNtStatusToDosError(Status));
512 return FALSE;
513 }
514
515 if (Type == TokenPrimary)
516 {
517 /* Create a duplicate impersonation token */
518 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
519 Qos.ImpersonationLevel = SecurityImpersonation;
520 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
521 Qos.EffectiveOnly = FALSE;
522
523 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
524 ObjectAttributes.RootDirectory = NULL;
525 ObjectAttributes.ObjectName = NULL;
526 ObjectAttributes.Attributes = 0;
527 ObjectAttributes.SecurityDescriptor = NULL;
528 ObjectAttributes.SecurityQualityOfService = &Qos;
529
530 Status = NtDuplicateToken(hToken,
531 TOKEN_IMPERSONATE | TOKEN_QUERY,
532 &ObjectAttributes,
533 FALSE,
534 TokenImpersonation,
535 &NewToken);
536 if (!NT_SUCCESS(Status))
537 {
538 SetLastError(RtlNtStatusToDosError(Status));
539 return FALSE;
540 }
541
542 Duplicated = TRUE;
543 }
544 else
545 {
546 /* User the original impersonation token */
547 NewToken = hToken;
548 Duplicated = FALSE;
549 }
550
551 /* Impersonate the the current thread */
552 Status = NtSetInformationThread(NtCurrentThread(),
553 ThreadImpersonationToken,
554 &NewToken,
555 sizeof(HANDLE));
556
557 if (Duplicated == TRUE)
558 {
559 NtClose(NewToken);
560 }
561
562 if (!NT_SUCCESS(Status))
563 {
564 SetLastError(RtlNtStatusToDosError(Status));
565 return FALSE;
566 }
567
568 return TRUE;
569 }
570
571
572 /*
573 * @implemented
574 */
575 BOOL
576 WINAPI
577 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
578 {
579 NTSTATUS Status;
580
581 Status = RtlImpersonateSelf(ImpersonationLevel);
582 if (!NT_SUCCESS(Status))
583 {
584 SetLastError(RtlNtStatusToDosError(Status));
585 return FALSE;
586 }
587
588 return TRUE;
589 }
590
591
592 /*
593 * @implemented
594 */
595 BOOL
596 WINAPI
597 RevertToSelf(VOID)
598 {
599 NTSTATUS Status;
600 HANDLE Token = NULL;
601
602 Status = NtSetInformationThread(NtCurrentThread(),
603 ThreadImpersonationToken,
604 &Token,
605 sizeof(HANDLE));
606 if (!NT_SUCCESS(Status))
607 {
608 SetLastError(RtlNtStatusToDosError(Status));
609 return FALSE;
610 }
611
612 return TRUE;
613 }
614
615
616 /******************************************************************************
617 * GetUserNameA [ADVAPI32.@]
618 *
619 * Get the current user name.
620 *
621 * PARAMS
622 * lpszName [O] Destination for the user name.
623 * lpSize [I/O] Size of lpszName.
624 *
625 *
626 * @implemented
627 */
628 BOOL
629 WINAPI
630 GetUserNameA(LPSTR lpszName,
631 LPDWORD lpSize)
632 {
633 UNICODE_STRING NameW;
634 ANSI_STRING NameA;
635 BOOL Ret;
636
637 /* apparently Win doesn't check whether lpSize is valid at all! */
638
639 NameW.MaximumLength = (*lpSize) * sizeof(WCHAR);
640 NameW.Buffer = LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
641 if(NameW.Buffer == NULL)
642 {
643 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
644 return FALSE;
645 }
646
647 NameA.Length = 0;
648 NameA.MaximumLength = ((*lpSize) < 0xFFFF ? (USHORT)(*lpSize) : 0xFFFF);
649 NameA.Buffer = lpszName;
650
651 Ret = GetUserNameW(NameW.Buffer,
652 lpSize);
653 if(Ret)
654 {
655 NameW.Length = (*lpSize - 1) * sizeof(WCHAR);
656 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
657
658 *lpSize = NameA.Length + 1;
659 }
660
661 LocalFree(NameW.Buffer);
662
663 return Ret;
664 }
665
666
667 /******************************************************************************
668 * GetUserNameW [ADVAPI32.@]
669 *
670 * See GetUserNameA.
671 *
672 * @implemented
673 */
674 BOOL
675 WINAPI
676 GetUserNameW(LPWSTR lpszName,
677 LPDWORD lpSize)
678 {
679 HANDLE hToken = INVALID_HANDLE_VALUE;
680 DWORD tu_len = 0;
681 char* tu_buf = NULL;
682 TOKEN_USER* token_user = NULL;
683 DWORD an_len = 0;
684 SID_NAME_USE snu = SidTypeUser;
685 WCHAR* domain_name = NULL;
686 DWORD dn_len = 0;
687
688 if (!OpenThreadToken (GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken))
689 {
690 DWORD dwLastError = GetLastError();
691 if (dwLastError != ERROR_NO_TOKEN
692 && dwLastError != ERROR_NO_IMPERSONATION_TOKEN)
693 {
694 /* don't call SetLastError(),
695 as OpenThreadToken() ought to have set one */
696 return FALSE;
697 }
698
699 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
700 {
701 /* don't call SetLastError(),
702 as OpenProcessToken() ought to have set one */
703 return FALSE;
704 }
705 }
706
707 tu_buf = LocalAlloc(LMEM_FIXED, 36);
708 if (!tu_buf)
709 {
710 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
711 CloseHandle(hToken);
712 return FALSE;
713 }
714
715 if (!GetTokenInformation(hToken, TokenUser, tu_buf, 36, &tu_len) || tu_len > 36)
716 {
717 LocalFree(tu_buf);
718 tu_buf = LocalAlloc(LMEM_FIXED, tu_len);
719 if (!tu_buf)
720 {
721 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
722 CloseHandle(hToken);
723 return FALSE;
724 }
725
726 if (!GetTokenInformation(hToken, TokenUser, tu_buf, tu_len, &tu_len))
727 {
728 /* don't call SetLastError(),
729 as GetTokenInformation() ought to have set one */
730 LocalFree(tu_buf);
731 CloseHandle(hToken);
732 return FALSE;
733 }
734 }
735
736 CloseHandle(hToken);
737 token_user = (TOKEN_USER*)tu_buf;
738
739 an_len = *lpSize;
740 dn_len = 32;
741 domain_name = LocalAlloc(LMEM_FIXED, dn_len * sizeof(WCHAR));
742 if (!domain_name)
743 {
744 LocalFree(tu_buf);
745 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
746 return FALSE;
747 }
748
749 if (!LookupAccountSidW(NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu)
750 || dn_len > 32)
751 {
752 if (dn_len > 32)
753 {
754 LocalFree(domain_name);
755 domain_name = LocalAlloc(LMEM_FIXED, dn_len * sizeof(WCHAR));
756 if (!domain_name)
757 {
758 LocalFree(tu_buf);
759 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
760 return FALSE;
761 }
762 }
763
764 an_len = *lpSize;
765 if (!LookupAccountSidW(NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu))
766 {
767 /* don't call SetLastError(),
768 as LookupAccountSid() ought to have set one */
769 LocalFree(domain_name);
770 LocalFree(tu_buf);
771 *lpSize = an_len;
772 return FALSE;
773 }
774 }
775
776 LocalFree(domain_name);
777 LocalFree(tu_buf);
778 *lpSize = an_len + 1;
779 return TRUE;
780 }
781
782
783 /******************************************************************************
784 * LookupAccountSidA [ADVAPI32.@]
785 *
786 * @implemented
787 */
788 BOOL
789 WINAPI
790 LookupAccountSidA(LPCSTR lpSystemName,
791 PSID lpSid,
792 LPSTR lpName,
793 LPDWORD cchName,
794 LPSTR lpReferencedDomainName,
795 LPDWORD cchReferencedDomainName,
796 PSID_NAME_USE peUse)
797 {
798 UNICODE_STRING NameW, ReferencedDomainNameW, SystemNameW;
799 LPWSTR NameBuffer = NULL;
800 LPWSTR ReferencedDomainNameBuffer = NULL;
801 DWORD dwName, dwReferencedDomainName;
802 BOOL Ret;
803
804 /*
805 * save the buffer sizes the caller passed to us, as they may get modified and
806 * we require the original values when converting back to ansi
807 */
808 dwName = *cchName;
809 dwReferencedDomainName = *cchReferencedDomainName;
810
811 /* allocate buffers for the unicode strings to receive */
812 if (dwName > 0)
813 {
814 NameBuffer = (PWSTR)LocalAlloc(LMEM_FIXED, dwName);
815 if (NameBuffer == NULL)
816 {
817 SetLastError(ERROR_OUTOFMEMORY);
818 return FALSE;
819 }
820 }
821 else
822 NameBuffer = NULL;
823
824 if (dwReferencedDomainName > 0)
825 {
826 ReferencedDomainNameBuffer = (PWSTR)LocalAlloc(LMEM_FIXED, dwReferencedDomainName);
827 if (ReferencedDomainNameBuffer == NULL)
828 {
829 if (dwName > 0)
830 {
831 LocalFree(NameBuffer);
832 }
833
834 SetLastError(ERROR_OUTOFMEMORY);
835 return FALSE;
836 }
837 }
838 else
839 ReferencedDomainNameBuffer = NULL;
840
841
842 /* convert the system name to unicode - if present */
843 if (lpSystemName != NULL)
844 {
845 ANSI_STRING SystemNameA;
846
847 RtlInitAnsiString(&SystemNameA, lpSystemName);
848 RtlAnsiStringToUnicodeString(&SystemNameW, &SystemNameA, TRUE);
849 }
850 else
851 SystemNameW.Buffer = NULL;
852
853 /* it's time to call the unicode version */
854 Ret = LookupAccountSidW(SystemNameW.Buffer,
855 lpSid,
856 NameBuffer,
857 cchName,
858 ReferencedDomainNameBuffer,
859 cchReferencedDomainName,
860 peUse);
861 if (Ret)
862 {
863 /*
864 * convert unicode strings back to ansi, don't forget that we can't convert
865 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
866 * terminate the converted string, the Rtl functions don't do that!
867 */
868 if (lpName != NULL)
869 {
870 ANSI_STRING NameA;
871
872 NameA.Length = 0;
873 NameA.MaximumLength = ((dwName <= 0xFFFF) ? (USHORT)dwName : 0xFFFF);
874 NameA.Buffer = lpName;
875
876 RtlInitUnicodeString(&NameW, NameBuffer);
877 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
878 NameA.Buffer[NameA.Length] = '\0';
879 }
880
881 if (lpReferencedDomainName != NULL)
882 {
883 ANSI_STRING ReferencedDomainNameA;
884
885 ReferencedDomainNameA.Length = 0;
886 ReferencedDomainNameA.MaximumLength = ((dwReferencedDomainName <= 0xFFFF) ?
887 (USHORT)dwReferencedDomainName : 0xFFFF);
888 ReferencedDomainNameA.Buffer = lpReferencedDomainName;
889
890 RtlInitUnicodeString(&ReferencedDomainNameW, ReferencedDomainNameBuffer);
891 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA, &ReferencedDomainNameW, FALSE);
892 ReferencedDomainNameA.Buffer[ReferencedDomainNameA.Length] = '\0';
893 }
894 }
895
896 /* free previously allocated buffers */
897 if (SystemNameW.Buffer != NULL)
898 {
899 RtlFreeUnicodeString(&SystemNameW);
900 }
901
902 if (NameBuffer != NULL)
903 {
904 LocalFree(NameBuffer);
905 }
906
907 if (ReferencedDomainNameBuffer != NULL)
908 {
909 LocalFree(ReferencedDomainNameBuffer);
910 }
911
912 return Ret;
913 }
914
915
916 /******************************************************************************
917 * LookupAccountSidW [ADVAPI32.@]
918 *
919 * @implemented
920 */
921 BOOL WINAPI
922 LookupAccountSidW(LPCWSTR pSystemName,
923 PSID pSid,
924 LPWSTR pAccountName,
925 LPDWORD pdwAccountName,
926 LPWSTR pDomainName,
927 LPDWORD pdwDomainName,
928 PSID_NAME_USE peUse)
929 {
930 LSA_UNICODE_STRING SystemName;
931 LSA_OBJECT_ATTRIBUTES ObjectAttributes = {0};
932 LSA_HANDLE PolicyHandle = NULL;
933 NTSTATUS Status;
934 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain = NULL;
935 PLSA_TRANSLATED_NAME TranslatedName = NULL;
936 BOOL ret;
937 DWORD dwAccountName, dwDomainName;
938
939 RtlInitUnicodeString(&SystemName, pSystemName);
940 Status = LsaOpenPolicy(&SystemName, &ObjectAttributes, POLICY_LOOKUP_NAMES, &PolicyHandle);
941 if (!NT_SUCCESS(Status))
942 {
943 SetLastError(LsaNtStatusToWinError(Status));
944 return FALSE;
945 }
946
947 Status = LsaLookupSids(PolicyHandle, 1, &pSid, &ReferencedDomain, &TranslatedName);
948
949 LsaClose(PolicyHandle);
950
951 if (!NT_SUCCESS(Status) || Status == STATUS_SOME_NOT_MAPPED)
952 {
953 SetLastError(LsaNtStatusToWinError(Status));
954 ret = FALSE;
955 }
956 else
957 {
958 ret = TRUE;
959
960 dwAccountName = TranslatedName->Name.Length / sizeof(WCHAR);
961 if (ReferencedDomain && ReferencedDomain->Entries > 0)
962 dwDomainName = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR);
963 else
964 dwDomainName = 0;
965
966 if (*pdwAccountName <= dwAccountName || *pdwDomainName <= dwDomainName)
967 {
968 /* One or two buffers are insufficient, add up a char for NULL termination */
969 *pdwAccountName = dwAccountName + 1;
970 *pdwDomainName = dwDomainName + 1;
971 ret = FALSE;
972 }
973 else
974 {
975 /* Lengths are sufficient, copy the data */
976 if (dwAccountName)
977 RtlCopyMemory(pAccountName, TranslatedName->Name.Buffer, dwAccountName * sizeof(WCHAR));
978 pAccountName[dwAccountName] = L'\0';
979
980 if (dwDomainName)
981 RtlCopyMemory(pDomainName, ReferencedDomain->Domains[0].Name.Buffer, dwDomainName * sizeof(WCHAR));
982 pDomainName[dwDomainName] = L'\0';
983
984 *pdwAccountName = dwAccountName;
985 *pdwDomainName = dwDomainName;
986
987 if (peUse)
988 *peUse = TranslatedName->Use;
989 }
990
991 if (!ret)
992 SetLastError(ERROR_INSUFFICIENT_BUFFER);
993 }
994
995 if (ReferencedDomain)
996 LsaFreeMemory(ReferencedDomain);
997
998 if (TranslatedName)
999 LsaFreeMemory(TranslatedName);
1000
1001 return ret;
1002 }
1003
1004
1005 /******************************************************************************
1006 * LookupAccountNameA [ADVAPI32.@]
1007 *
1008 * @implemented
1009 */
1010 BOOL
1011 WINAPI
1012 LookupAccountNameA(LPCSTR SystemName,
1013 LPCSTR AccountName,
1014 PSID Sid,
1015 LPDWORD SidLength,
1016 LPSTR ReferencedDomainName,
1017 LPDWORD hReferencedDomainNameLength,
1018 PSID_NAME_USE SidNameUse)
1019 {
1020 BOOL ret;
1021 UNICODE_STRING lpSystemW;
1022 UNICODE_STRING lpAccountW;
1023 LPWSTR lpReferencedDomainNameW = NULL;
1024
1025 RtlCreateUnicodeStringFromAsciiz(&lpSystemW, SystemName);
1026 RtlCreateUnicodeStringFromAsciiz(&lpAccountW, AccountName);
1027
1028 if (ReferencedDomainName)
1029 lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(),
1030 0,
1031 *hReferencedDomainNameLength * sizeof(WCHAR));
1032
1033 ret = LookupAccountNameW(lpSystemW.Buffer,
1034 lpAccountW.Buffer,
1035 Sid,
1036 SidLength,
1037 lpReferencedDomainNameW,
1038 hReferencedDomainNameLength,
1039 SidNameUse);
1040
1041 if (ret && lpReferencedDomainNameW)
1042 {
1043 WideCharToMultiByte(CP_ACP,
1044 0,
1045 lpReferencedDomainNameW,
1046 *hReferencedDomainNameLength + 1,
1047 ReferencedDomainName,
1048 *hReferencedDomainNameLength + 1,
1049 NULL,
1050 NULL);
1051 }
1052
1053 RtlFreeUnicodeString(&lpSystemW);
1054 RtlFreeUnicodeString(&lpAccountW);
1055 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
1056
1057 return ret;
1058 }
1059
1060
1061 /******************************************************************************
1062 * LookupAccountNameW [ADVAPI32.@]
1063 *
1064 * @implemented
1065 */
1066 BOOL
1067 WINAPI
1068 LookupAccountNameW(LPCWSTR lpSystemName,
1069 LPCWSTR lpAccountName,
1070 PSID Sid,
1071 LPDWORD cbSid,
1072 LPWSTR ReferencedDomainName,
1073 LPDWORD cchReferencedDomainName,
1074 PSID_NAME_USE peUse)
1075 {
1076 OBJECT_ATTRIBUTES ObjectAttributes = {0};
1077 UNICODE_STRING SystemName;
1078 UNICODE_STRING AccountName;
1079 LSA_HANDLE PolicyHandle = NULL;
1080 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains = NULL;
1081 PLSA_TRANSLATED_SID TranslatedSid = NULL;
1082 PSID pDomainSid;
1083 DWORD dwDomainNameLength;
1084 DWORD dwSidLength;
1085 UCHAR nSubAuthorities;
1086 BOOL bResult;
1087 NTSTATUS Status;
1088
1089 TRACE("%s %s %p %p %p %p %p\n", lpSystemName, lpAccountName,
1090 Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
1091
1092 RtlInitUnicodeString(&SystemName,
1093 lpSystemName);
1094
1095 Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL,
1096 &ObjectAttributes,
1097 POLICY_LOOKUP_NAMES,
1098 &PolicyHandle);
1099 if (!NT_SUCCESS(Status))
1100 {
1101 SetLastError(LsaNtStatusToWinError(Status));
1102 return FALSE;
1103 }
1104
1105 RtlInitUnicodeString(&AccountName,
1106 lpAccountName);
1107
1108 Status = LsaLookupNames(PolicyHandle,
1109 1,
1110 &AccountName,
1111 &ReferencedDomains,
1112 &TranslatedSid);
1113
1114 LsaClose(PolicyHandle);
1115
1116 if (!NT_SUCCESS(Status) || Status == STATUS_SOME_NOT_MAPPED)
1117 {
1118 SetLastError(LsaNtStatusToWinError(Status));
1119 bResult = FALSE;
1120 }
1121 else
1122 {
1123 pDomainSid = ReferencedDomains->Domains[TranslatedSid->DomainIndex].Sid;
1124 nSubAuthorities = *GetSidSubAuthorityCount(pDomainSid);
1125 dwSidLength = GetSidLengthRequired(nSubAuthorities + 1);
1126
1127 dwDomainNameLength = ReferencedDomains->Domains->Name.Length / sizeof(WCHAR);
1128
1129 if (*cbSid < dwSidLength ||
1130 *cchReferencedDomainName < dwDomainNameLength + 1)
1131 {
1132 *cbSid = dwSidLength;
1133 *cchReferencedDomainName = dwDomainNameLength + 1;
1134
1135 bResult = FALSE;
1136 }
1137 else
1138 {
1139 CopySid(*cbSid, Sid, pDomainSid);
1140 *GetSidSubAuthorityCount(Sid) = nSubAuthorities + 1;
1141 *GetSidSubAuthority(Sid, (DWORD)nSubAuthorities) = TranslatedSid->RelativeId;
1142
1143 RtlCopyMemory(ReferencedDomainName, ReferencedDomains->Domains->Name.Buffer, dwDomainNameLength * sizeof(WCHAR));
1144 ReferencedDomainName[dwDomainNameLength] = L'\0';
1145
1146 *cchReferencedDomainName = dwDomainNameLength;
1147
1148 *peUse = TranslatedSid->Use;
1149
1150 bResult = TRUE;
1151 }
1152
1153 if (bResult == FALSE)
1154 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1155 }
1156
1157 if (ReferencedDomains != NULL)
1158 LsaFreeMemory(ReferencedDomains);
1159
1160 if (TranslatedSid != NULL)
1161 LsaFreeMemory(TranslatedSid);
1162
1163 return bResult;
1164 }
1165
1166
1167 /**********************************************************************
1168 * LookupPrivilegeValueA EXPORTED
1169 *
1170 * @implemented
1171 */
1172 BOOL
1173 WINAPI
1174 LookupPrivilegeValueA(LPCSTR lpSystemName,
1175 LPCSTR lpName,
1176 PLUID lpLuid)
1177 {
1178 UNICODE_STRING SystemName;
1179 UNICODE_STRING Name;
1180 BOOL Result;
1181
1182 /* Remote system? */
1183 if (lpSystemName != NULL)
1184 {
1185 RtlCreateUnicodeStringFromAsciiz(&SystemName,
1186 (LPSTR)lpSystemName);
1187 }
1188 else
1189 SystemName.Buffer = NULL;
1190
1191 /* Check the privilege name is not NULL */
1192 if (lpName == NULL)
1193 {
1194 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1195 return FALSE;
1196 }
1197
1198 RtlCreateUnicodeStringFromAsciiz(&Name,
1199 (LPSTR)lpName);
1200
1201 Result = LookupPrivilegeValueW(SystemName.Buffer,
1202 Name.Buffer,
1203 lpLuid);
1204
1205 RtlFreeUnicodeString(&Name);
1206
1207 /* Remote system? */
1208 if (SystemName.Buffer != NULL)
1209 {
1210 RtlFreeUnicodeString(&SystemName);
1211 }
1212
1213 return Result;
1214 }
1215
1216
1217 /**********************************************************************
1218 * LookupPrivilegeValueW
1219 *
1220 * @implemented
1221 */
1222 BOOL
1223 WINAPI
1224 LookupPrivilegeValueW(LPCWSTR lpSystemName,
1225 LPCWSTR lpPrivilegeName,
1226 PLUID lpLuid)
1227 {
1228 OBJECT_ATTRIBUTES ObjectAttributes = {0};
1229 UNICODE_STRING SystemName;
1230 UNICODE_STRING PrivilegeName;
1231 LSA_HANDLE PolicyHandle = NULL;
1232 NTSTATUS Status;
1233
1234 TRACE("%S,%S,%p\n", lpSystemName, lpPrivilegeName, lpLuid);
1235
1236 RtlInitUnicodeString(&SystemName,
1237 lpSystemName);
1238
1239 Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL,
1240 &ObjectAttributes,
1241 POLICY_LOOKUP_NAMES,
1242 &PolicyHandle);
1243 if (!NT_SUCCESS(Status))
1244 {
1245 SetLastError(LsaNtStatusToWinError(Status));
1246 return FALSE;
1247 }
1248
1249 RtlInitUnicodeString(&PrivilegeName,
1250 lpPrivilegeName);
1251
1252 Status = LsaLookupPrivilegeValue(PolicyHandle,
1253 &PrivilegeName,
1254 lpLuid);
1255
1256 LsaClose(PolicyHandle);
1257
1258 if (!NT_SUCCESS(Status))
1259 {
1260 SetLastError(LsaNtStatusToWinError(Status));
1261 return FALSE;
1262 }
1263
1264 return TRUE;
1265 }
1266
1267
1268 /**********************************************************************
1269 * LookupPrivilegeDisplayNameA EXPORTED
1270 *
1271 * @unimplemented
1272 */
1273 BOOL
1274 WINAPI
1275 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName,
1276 LPCSTR lpName,
1277 LPSTR lpDisplayName,
1278 LPDWORD cbDisplayName,
1279 LPDWORD lpLanguageId)
1280 {
1281 FIXME("%s() not implemented!\n", __FUNCTION__);
1282 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1283 return FALSE;
1284 }
1285
1286
1287 /**********************************************************************
1288 * LookupPrivilegeDisplayNameW EXPORTED
1289 *
1290 * @unimplemented
1291 */
1292 BOOL
1293 WINAPI
1294 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName,
1295 LPCWSTR lpName,
1296 LPWSTR lpDisplayName,
1297 LPDWORD cbDisplayName,
1298 LPDWORD lpLanguageId)
1299 {
1300 FIXME("%s() not implemented!\n", __FUNCTION__);
1301 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1302 return FALSE;
1303 }
1304
1305
1306 /**********************************************************************
1307 * LookupPrivilegeNameA EXPORTED
1308 *
1309 * @implemented
1310 */
1311 BOOL
1312 WINAPI
1313 LookupPrivilegeNameA(LPCSTR lpSystemName,
1314 PLUID lpLuid,
1315 LPSTR lpName,
1316 LPDWORD cchName)
1317 {
1318 UNICODE_STRING lpSystemNameW;
1319 BOOL ret;
1320 DWORD wLen = 0;
1321
1322 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1323
1324 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1325 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1326 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1327 {
1328 LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1329
1330 ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1331 &wLen);
1332 if (ret)
1333 {
1334 /* Windows crashes if cchName is NULL, so will I */
1335 unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1336 *cchName, NULL, NULL);
1337
1338 if (len == 0)
1339 {
1340 /* WideCharToMultiByte failed */
1341 ret = FALSE;
1342 }
1343 else if (len > *cchName)
1344 {
1345 *cchName = len;
1346 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1347 ret = FALSE;
1348 }
1349 else
1350 {
1351 /* WideCharToMultiByte succeeded, output length needs to be
1352 * length not including NULL terminator
1353 */
1354 *cchName = len - 1;
1355 }
1356 }
1357 HeapFree(GetProcessHeap(), 0, lpNameW);
1358 }
1359 RtlFreeUnicodeString(&lpSystemNameW);
1360 return ret;
1361 }
1362
1363
1364 /**********************************************************************
1365 * LookupPrivilegeNameW EXPORTED
1366 *
1367 * @implemented
1368 */
1369 BOOL
1370 WINAPI
1371 LookupPrivilegeNameW(LPCWSTR lpSystemName,
1372 PLUID lpLuid,
1373 LPWSTR lpName,
1374 LPDWORD cchName)
1375 {
1376 OBJECT_ATTRIBUTES ObjectAttributes = {0};
1377 UNICODE_STRING SystemName;
1378 PUNICODE_STRING PrivilegeName = NULL;
1379 LSA_HANDLE PolicyHandle = NULL;
1380 NTSTATUS Status;
1381
1382 TRACE("%S,%p,%p,%p\n", lpSystemName, lpLuid, lpName, cchName);
1383
1384 RtlInitUnicodeString(&SystemName,
1385 lpSystemName);
1386
1387 Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL,
1388 &ObjectAttributes,
1389 POLICY_LOOKUP_NAMES,
1390 &PolicyHandle);
1391 if (!NT_SUCCESS(Status))
1392 {
1393 SetLastError(LsaNtStatusToWinError(Status));
1394 return FALSE;
1395 }
1396
1397 Status = LsaLookupPrivilegeName(PolicyHandle,
1398 lpLuid,
1399 &PrivilegeName);
1400 if (NT_SUCCESS(Status))
1401 {
1402 if (PrivilegeName->Length + sizeof(WCHAR) > *cchName * sizeof(WCHAR))
1403 {
1404 Status = STATUS_BUFFER_TOO_SMALL;
1405
1406 *cchName = (PrivilegeName->Length + sizeof(WCHAR)) / sizeof(WCHAR);
1407 }
1408 else
1409 {
1410 RtlMoveMemory(lpName,
1411 PrivilegeName->Buffer,
1412 PrivilegeName->Length);
1413 lpName[PrivilegeName->Length / sizeof(WCHAR)] = 0;
1414
1415 *cchName = PrivilegeName->Length / sizeof(WCHAR);
1416 }
1417
1418 LsaFreeMemory(PrivilegeName->Buffer);
1419 LsaFreeMemory(PrivilegeName);
1420 }
1421
1422 LsaClose(PolicyHandle);
1423
1424 if (!NT_SUCCESS(Status))
1425 {
1426 SetLastError(LsaNtStatusToWinError(Status));
1427 return FALSE;
1428 }
1429
1430 return TRUE;
1431 }
1432
1433
1434 static DWORD
1435 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo,
1436 PSID *ppsidOwner,
1437 PSID *ppsidGroup,
1438 PACL *ppDacl,
1439 PACL *ppSacl,
1440 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
1441 {
1442 if ((SecurityInfo & (OWNER_SECURITY_INFORMATION |
1443 GROUP_SECURITY_INFORMATION |
1444 DACL_SECURITY_INFORMATION |
1445 SACL_SECURITY_INFORMATION)) &&
1446 ppSecurityDescriptor == NULL)
1447 {
1448 /* if one of the SIDs or ACLs are present, the security descriptor
1449 most not be NULL */
1450 return ERROR_INVALID_PARAMETER;
1451 }
1452 else
1453 {
1454 /* reset the pointers unless they're ignored */
1455 if ((SecurityInfo & OWNER_SECURITY_INFORMATION) &&
1456 ppsidOwner != NULL)
1457 {
1458 *ppsidOwner = NULL;
1459 }
1460 if ((SecurityInfo & GROUP_SECURITY_INFORMATION) &&
1461 ppsidGroup != NULL)
1462 {
1463 *ppsidGroup = NULL;
1464 }
1465 if ((SecurityInfo & DACL_SECURITY_INFORMATION) &&
1466 ppDacl != NULL)
1467 {
1468 *ppDacl = NULL;
1469 }
1470 if ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
1471 ppSacl != NULL)
1472 {
1473 *ppSacl = NULL;
1474 }
1475
1476 if (SecurityInfo & (OWNER_SECURITY_INFORMATION |
1477 GROUP_SECURITY_INFORMATION |
1478 DACL_SECURITY_INFORMATION |
1479 SACL_SECURITY_INFORMATION))
1480 {
1481 *ppSecurityDescriptor = NULL;
1482 }
1483
1484 return ERROR_SUCCESS;
1485 }
1486 }
1487
1488
1489 static DWORD
1490 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,
1491 SECURITY_INFORMATION SecurityInfo,
1492 PSID psidOwner,
1493 PSID psidGroup,
1494 PACL pDacl,
1495 PACL pSacl)
1496 {
1497 /* initialize a security descriptor on the stack */
1498 if (!InitializeSecurityDescriptor(pSecurityDescriptor,
1499 SECURITY_DESCRIPTOR_REVISION))
1500 {
1501 return GetLastError();
1502 }
1503
1504 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
1505 {
1506 if (RtlValidSid(psidOwner))
1507 {
1508 if (!SetSecurityDescriptorOwner(pSecurityDescriptor,
1509 psidOwner,
1510 FALSE))
1511 {
1512 return GetLastError();
1513 }
1514 }
1515 else
1516 {
1517 return ERROR_INVALID_PARAMETER;
1518 }
1519 }
1520
1521 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
1522 {
1523 if (RtlValidSid(psidGroup))
1524 {
1525 if (!SetSecurityDescriptorGroup(pSecurityDescriptor,
1526 psidGroup,
1527 FALSE))
1528 {
1529 return GetLastError();
1530 }
1531 }
1532 else
1533 {
1534 return ERROR_INVALID_PARAMETER;
1535 }
1536 }
1537
1538 if (SecurityInfo & DACL_SECURITY_INFORMATION)
1539 {
1540 if (pDacl != NULL)
1541 {
1542 if (SetSecurityDescriptorDacl(pSecurityDescriptor,
1543 TRUE,
1544 pDacl,
1545 FALSE))
1546 {
1547 /* check if the DACL needs to be protected from being
1548 modified by inheritable ACEs */
1549 if (SecurityInfo & PROTECTED_DACL_SECURITY_INFORMATION)
1550 {
1551 goto ProtectDacl;
1552 }
1553 }
1554 else
1555 {
1556 return GetLastError();
1557 }
1558 }
1559 else
1560 {
1561 ProtectDacl:
1562 /* protect the DACL from being modified by inheritable ACEs */
1563 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1564 SE_DACL_PROTECTED,
1565 SE_DACL_PROTECTED))
1566 {
1567 return GetLastError();
1568 }
1569 }
1570 }
1571
1572 if (SecurityInfo & SACL_SECURITY_INFORMATION)
1573 {
1574 if (pSacl != NULL)
1575 {
1576 if (SetSecurityDescriptorSacl(pSecurityDescriptor,
1577 TRUE,
1578 pSacl,
1579 FALSE))
1580 {
1581 /* check if the SACL needs to be protected from being
1582 modified by inheritable ACEs */
1583 if (SecurityInfo & PROTECTED_SACL_SECURITY_INFORMATION)
1584 {
1585 goto ProtectSacl;
1586 }
1587 }
1588 else
1589 {
1590 return GetLastError();
1591 }
1592 }
1593 else
1594 {
1595 ProtectSacl:
1596 /* protect the SACL from being modified by inheritable ACEs */
1597 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1598 SE_SACL_PROTECTED,
1599 SE_SACL_PROTECTED))
1600 {
1601 return GetLastError();
1602 }
1603 }
1604 }
1605
1606 return ERROR_SUCCESS;
1607 }
1608
1609
1610 /**********************************************************************
1611 * GetNamedSecurityInfoW EXPORTED
1612 *
1613 * @implemented
1614 */
1615 DWORD
1616 WINAPI
1617 GetNamedSecurityInfoW(LPWSTR pObjectName,
1618 SE_OBJECT_TYPE ObjectType,
1619 SECURITY_INFORMATION SecurityInfo,
1620 PSID *ppsidOwner,
1621 PSID *ppsidGroup,
1622 PACL *ppDacl,
1623 PACL *ppSacl,
1624 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1625 {
1626 DWORD ErrorCode;
1627
1628 if (pObjectName != NULL)
1629 {
1630 ErrorCode = CheckNtMartaPresent();
1631 if (ErrorCode == ERROR_SUCCESS)
1632 {
1633 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1634 ppsidOwner,
1635 ppsidGroup,
1636 ppDacl,
1637 ppSacl,
1638 ppSecurityDescriptor);
1639
1640 if (ErrorCode == ERROR_SUCCESS)
1641 {
1642 /* call the MARTA provider */
1643 ErrorCode = AccRewriteGetNamedRights(pObjectName,
1644 ObjectType,
1645 SecurityInfo,
1646 ppsidOwner,
1647 ppsidGroup,
1648 ppDacl,
1649 ppSacl,
1650 ppSecurityDescriptor);
1651 }
1652 }
1653 }
1654 else
1655 ErrorCode = ERROR_INVALID_PARAMETER;
1656
1657 return ErrorCode;
1658 }
1659
1660
1661 /**********************************************************************
1662 * GetNamedSecurityInfoA EXPORTED
1663 *
1664 * @implemented
1665 */
1666 DWORD
1667 WINAPI
1668 GetNamedSecurityInfoA(LPSTR pObjectName,
1669 SE_OBJECT_TYPE ObjectType,
1670 SECURITY_INFORMATION SecurityInfo,
1671 PSID *ppsidOwner,
1672 PSID *ppsidGroup,
1673 PACL *ppDacl,
1674 PACL *ppSacl,
1675 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1676 {
1677 DWORD len;
1678 LPWSTR wstr = NULL;
1679 DWORD r;
1680
1681 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
1682 ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
1683
1684 if( pObjectName )
1685 {
1686 len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
1687 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
1688 MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
1689 }
1690
1691 r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
1692 ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
1693
1694 HeapFree( GetProcessHeap(), 0, wstr );
1695
1696 return r;
1697 }
1698
1699
1700 /**********************************************************************
1701 * SetNamedSecurityInfoW EXPORTED
1702 *
1703 * @implemented
1704 */
1705 DWORD
1706 WINAPI
1707 SetNamedSecurityInfoW(LPWSTR pObjectName,
1708 SE_OBJECT_TYPE ObjectType,
1709 SECURITY_INFORMATION SecurityInfo,
1710 PSID psidOwner,
1711 PSID psidGroup,
1712 PACL pDacl,
1713 PACL pSacl)
1714 {
1715 DWORD ErrorCode;
1716
1717 if (pObjectName != NULL)
1718 {
1719 ErrorCode = CheckNtMartaPresent();
1720 if (ErrorCode == ERROR_SUCCESS)
1721 {
1722 SECURITY_DESCRIPTOR SecurityDescriptor;
1723
1724 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1725 SecurityInfo,
1726 psidOwner,
1727 psidGroup,
1728 pDacl,
1729 pSacl);
1730
1731 if (ErrorCode == ERROR_SUCCESS)
1732 {
1733 /* call the MARTA provider */
1734 ErrorCode = AccRewriteSetNamedRights(pObjectName,
1735 ObjectType,
1736 SecurityInfo,
1737 &SecurityDescriptor);
1738 }
1739 }
1740 }
1741 else
1742 ErrorCode = ERROR_INVALID_PARAMETER;
1743
1744 return ErrorCode;
1745 }
1746
1747
1748 /**********************************************************************
1749 * SetNamedSecurityInfoA EXPORTED
1750 *
1751 * @implemented
1752 */
1753 DWORD
1754 WINAPI
1755 SetNamedSecurityInfoA(LPSTR pObjectName,
1756 SE_OBJECT_TYPE ObjectType,
1757 SECURITY_INFORMATION SecurityInfo,
1758 PSID psidOwner,
1759 PSID psidGroup,
1760 PACL pDacl,
1761 PACL pSacl)
1762 {
1763 UNICODE_STRING ObjectName;
1764 NTSTATUS Status;
1765 DWORD Ret;
1766
1767 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1768 pObjectName);
1769 if (!NT_SUCCESS(Status))
1770 {
1771 return RtlNtStatusToDosError(Status);
1772 }
1773
1774 Ret = SetNamedSecurityInfoW(ObjectName.Buffer,
1775 ObjectType,
1776 SecurityInfo,
1777 psidOwner,
1778 psidGroup,
1779 pDacl,
1780 pSacl);
1781
1782 RtlFreeUnicodeString(&ObjectName);
1783
1784 return Ret;
1785 }
1786
1787
1788 /**********************************************************************
1789 * GetSecurityInfo EXPORTED
1790 *
1791 * @implemented
1792 */
1793 DWORD
1794 WINAPI
1795 GetSecurityInfo(HANDLE handle,
1796 SE_OBJECT_TYPE ObjectType,
1797 SECURITY_INFORMATION SecurityInfo,
1798 PSID *ppsidOwner,
1799 PSID *ppsidGroup,
1800 PACL *ppDacl,
1801 PACL *ppSacl,
1802 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1803 {
1804 DWORD ErrorCode;
1805
1806 if (handle != NULL)
1807 {
1808 ErrorCode = CheckNtMartaPresent();
1809 if (ErrorCode == ERROR_SUCCESS)
1810 {
1811 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1812 ppsidOwner,
1813 ppsidGroup,
1814 ppDacl,
1815 ppSacl,
1816 ppSecurityDescriptor);
1817
1818 if (ErrorCode == ERROR_SUCCESS)
1819 {
1820 /* call the MARTA provider */
1821 ErrorCode = AccRewriteGetHandleRights(handle,
1822 ObjectType,
1823 SecurityInfo,
1824 ppsidOwner,
1825 ppsidGroup,
1826 ppDacl,
1827 ppSacl,
1828 ppSecurityDescriptor);
1829 }
1830 }
1831 }
1832 else
1833 ErrorCode = ERROR_INVALID_HANDLE;
1834
1835 return ErrorCode;
1836 }
1837
1838
1839 /**********************************************************************
1840 * SetSecurityInfo EXPORTED
1841 *
1842 * @implemented
1843 */
1844 DWORD
1845 WINAPI
1846 SetSecurityInfo(HANDLE handle,
1847 SE_OBJECT_TYPE ObjectType,
1848 SECURITY_INFORMATION SecurityInfo,
1849 PSID psidOwner,
1850 PSID psidGroup,
1851 PACL pDacl,
1852 PACL pSacl)
1853 {
1854 DWORD ErrorCode;
1855
1856 if (handle != NULL)
1857 {
1858 ErrorCode = CheckNtMartaPresent();
1859 if (ErrorCode == ERROR_SUCCESS)
1860 {
1861 SECURITY_DESCRIPTOR SecurityDescriptor;
1862
1863 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1864 SecurityInfo,
1865 psidOwner,
1866 psidGroup,
1867 pDacl,
1868 pSacl);
1869
1870 if (ErrorCode == ERROR_SUCCESS)
1871 {
1872 /* call the MARTA provider */
1873 ErrorCode = AccRewriteSetHandleRights(handle,
1874 ObjectType,
1875 SecurityInfo,
1876 &SecurityDescriptor);
1877 }
1878 }
1879 }
1880 else
1881 ErrorCode = ERROR_INVALID_HANDLE;
1882
1883 return ErrorCode;
1884 }
1885
1886
1887 /******************************************************************************
1888 * GetSecurityInfoExW EXPORTED
1889 */
1890 DWORD
1891 WINAPI
1892 GetSecurityInfoExA(HANDLE hObject,
1893 SE_OBJECT_TYPE ObjectType,
1894 SECURITY_INFORMATION SecurityInfo,
1895 LPCSTR lpProvider,
1896 LPCSTR lpProperty,
1897 PACTRL_ACCESSA *ppAccessList,
1898 PACTRL_AUDITA *ppAuditList,
1899 LPSTR *lppOwner,
1900 LPSTR *lppGroup)
1901 {
1902 FIXME("%s() not implemented!\n", __FUNCTION__);
1903 return ERROR_BAD_PROVIDER;
1904 }
1905
1906
1907 /******************************************************************************
1908 * GetSecurityInfoExW EXPORTED
1909 */
1910 DWORD
1911 WINAPI
1912 GetSecurityInfoExW(HANDLE hObject,
1913 SE_OBJECT_TYPE ObjectType,
1914 SECURITY_INFORMATION SecurityInfo,
1915 LPCWSTR lpProvider,
1916 LPCWSTR lpProperty,
1917 PACTRL_ACCESSW *ppAccessList,
1918 PACTRL_AUDITW *ppAuditList,
1919 LPWSTR *lppOwner,
1920 LPWSTR *lppGroup)
1921 {
1922 FIXME("%s() not implemented!\n", __FUNCTION__);
1923 return ERROR_BAD_PROVIDER;
1924 }
1925
1926
1927 /**********************************************************************
1928 * ImpersonateNamedPipeClient EXPORTED
1929 *
1930 * @implemented
1931 */
1932 BOOL
1933 WINAPI
1934 ImpersonateNamedPipeClient(HANDLE hNamedPipe)
1935 {
1936 IO_STATUS_BLOCK StatusBlock;
1937 NTSTATUS Status;
1938
1939 TRACE("ImpersonateNamedPipeClient() called\n");
1940
1941 Status = NtFsControlFile(hNamedPipe,
1942 NULL,
1943 NULL,
1944 NULL,
1945 &StatusBlock,
1946 FSCTL_PIPE_IMPERSONATE,
1947 NULL,
1948 0,
1949 NULL,
1950 0);
1951 if (!NT_SUCCESS(Status))
1952 {
1953 SetLastError(RtlNtStatusToDosError(Status));
1954 return FALSE;
1955 }
1956
1957 return TRUE;
1958 }
1959
1960
1961 /*
1962 * @implemented
1963 */
1964 BOOL
1965 WINAPI
1966 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
1967 PSECURITY_DESCRIPTOR CreatorDescriptor,
1968 PSECURITY_DESCRIPTOR *NewDescriptor,
1969 BOOL IsDirectoryObject,
1970 HANDLE Token,
1971 PGENERIC_MAPPING GenericMapping)
1972 {
1973 NTSTATUS Status;
1974
1975 Status = RtlNewSecurityObject(ParentDescriptor,
1976 CreatorDescriptor,
1977 NewDescriptor,
1978 IsDirectoryObject,
1979 Token,
1980 GenericMapping);
1981 if (!NT_SUCCESS(Status))
1982 {
1983 SetLastError(RtlNtStatusToDosError(Status));
1984 return FALSE;
1985 }
1986
1987 return TRUE;
1988 }
1989
1990
1991 /*
1992 * @unimplemented
1993 */
1994 BOOL
1995 WINAPI
1996 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor,
1997 PSECURITY_DESCRIPTOR CreatorDescriptor,
1998 PSECURITY_DESCRIPTOR* NewDescriptor,
1999 GUID* ObjectType,
2000 BOOL IsContainerObject,
2001 ULONG AutoInheritFlags,
2002 HANDLE Token,
2003 PGENERIC_MAPPING GenericMapping)
2004 {
2005 FIXME("%s() not implemented!\n", __FUNCTION__);
2006 return FALSE;
2007 }
2008
2009
2010 /*
2011 * @unimplemented
2012 */
2013 BOOL
2014 WINAPI
2015 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor,
2016 PSECURITY_DESCRIPTOR CreatorDescriptor,
2017 PSECURITY_DESCRIPTOR* NewDescriptor,
2018 GUID** ObjectTypes,
2019 ULONG GuidCount,
2020 BOOL IsContainerObject,
2021 ULONG AutoInheritFlags,
2022 HANDLE Token,
2023 PGENERIC_MAPPING GenericMapping)
2024 {
2025 FIXME("%s() not implemented!\n", __FUNCTION__);
2026 return FALSE;
2027 }
2028
2029
2030 /*
2031 * @implemented
2032 */
2033 BOOL
2034 WINAPI
2035 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR *ObjectDescriptor)
2036 {
2037 NTSTATUS Status;
2038
2039 Status = RtlDeleteSecurityObject(ObjectDescriptor);
2040 if (!NT_SUCCESS(Status))
2041 {
2042 SetLastError(RtlNtStatusToDosError(Status));
2043 return FALSE;
2044 }
2045
2046 return TRUE;
2047 }
2048
2049
2050 /*
2051 * @implemented
2052 */
2053 BOOL
2054 WINAPI
2055 GetPrivateObjectSecurity(IN PSECURITY_DESCRIPTOR ObjectDescriptor,
2056 IN SECURITY_INFORMATION SecurityInformation,
2057 OUT PSECURITY_DESCRIPTOR ResultantDescriptor OPTIONAL,
2058 IN DWORD DescriptorLength,
2059 OUT PDWORD ReturnLength)
2060 {
2061 NTSTATUS Status;
2062
2063 /* Call RTL */
2064 Status = RtlQuerySecurityObject(ObjectDescriptor,
2065 SecurityInformation,
2066 ResultantDescriptor,
2067 DescriptorLength,
2068 ReturnLength);
2069 if (!NT_SUCCESS(Status))
2070 {
2071 /* Fail */
2072 SetLastError(RtlNtStatusToDosError(Status));
2073 return FALSE;
2074 }
2075
2076 /* Success */
2077 return TRUE;
2078 }
2079
2080
2081 /*
2082 * @implemented
2083 */
2084 BOOL
2085 WINAPI
2086 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation,
2087 PSECURITY_DESCRIPTOR ModificationDescriptor,
2088 PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
2089 PGENERIC_MAPPING GenericMapping,
2090 HANDLE Token)
2091 {
2092 NTSTATUS Status;
2093
2094 Status = RtlSetSecurityObject(SecurityInformation,
2095 ModificationDescriptor,
2096 ObjectsSecurityDescriptor,
2097 GenericMapping,
2098 Token);
2099 if (!NT_SUCCESS(Status))
2100 {
2101 SetLastError(RtlNtStatusToDosError(Status));
2102 return FALSE;
2103 }
2104
2105 return TRUE;
2106 }
2107
2108
2109 /*
2110 * @implemented
2111 */
2112 DWORD
2113 WINAPI
2114 TreeResetNamedSecurityInfoW(LPWSTR pObjectName,
2115 SE_OBJECT_TYPE ObjectType,
2116 SECURITY_INFORMATION SecurityInfo,
2117 PSID pOwner,
2118 PSID pGroup,
2119 PACL pDacl,
2120 PACL pSacl,
2121 BOOL KeepExplicit,
2122 FN_PROGRESSW fnProgress,
2123 PROG_INVOKE_SETTING ProgressInvokeSetting,
2124 PVOID Args)
2125 {
2126 DWORD ErrorCode;
2127
2128 if (pObjectName != NULL)
2129 {
2130 ErrorCode = CheckNtMartaPresent();
2131 if (ErrorCode == ERROR_SUCCESS)
2132 {
2133 switch (ObjectType)
2134 {
2135 case SE_FILE_OBJECT:
2136 case SE_REGISTRY_KEY:
2137 {
2138 /* check the SecurityInfo flags for sanity (both, the protected
2139 and unprotected dacl/sacl flag must not be passed together) */
2140 if (((SecurityInfo & DACL_SECURITY_INFORMATION) &&
2141 (SecurityInfo & (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION)) ==
2142 (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION))
2143
2144 ||
2145
2146 ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
2147 (SecurityInfo & (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)) ==
2148 (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)))
2149 {
2150 ErrorCode = ERROR_INVALID_PARAMETER;
2151 break;
2152 }
2153
2154 /* call the MARTA provider */
2155 ErrorCode = AccTreeResetNamedSecurityInfo(pObjectName,
2156 ObjectType,
2157 SecurityInfo,
2158 pOwner,
2159 pGroup,
2160 pDacl,
2161 pSacl,
2162 KeepExplicit,
2163 fnProgress,
2164 ProgressInvokeSetting,
2165 Args);
2166 break;
2167 }
2168
2169 default:
2170 /* object type not supported */
2171 ErrorCode = ERROR_INVALID_PARAMETER;
2172 break;
2173 }
2174 }
2175 }
2176 else
2177 ErrorCode = ERROR_INVALID_PARAMETER;
2178
2179 return ErrorCode;
2180 }
2181
2182 #ifdef HAS_FN_PROGRESSW
2183
2184 typedef struct _INERNAL_FNPROGRESSW_DATA
2185 {
2186 FN_PROGRESSA fnProgress;
2187 PVOID Args;
2188 } INERNAL_FNPROGRESSW_DATA, *PINERNAL_FNPROGRESSW_DATA;
2189
2190 static VOID WINAPI
2191 InternalfnProgressW(LPWSTR pObjectName,
2192 DWORD Status,
2193 PPROG_INVOKE_SETTING pInvokeSetting,
2194 PVOID Args,
2195 BOOL SecuritySet)
2196 {
2197 PINERNAL_FNPROGRESSW_DATA pifnProgressData = (PINERNAL_FNPROGRESSW_DATA)Args;
2198 INT ObjectNameSize;
2199 LPSTR pObjectNameA;
2200
2201 ObjectNameSize = WideCharToMultiByte(CP_ACP,
2202 0,
2203 pObjectName,
2204 -1,
2205 NULL,
2206 0,
2207 NULL,
2208 NULL);
2209
2210 if (ObjectNameSize > 0)
2211 {
2212 pObjectNameA = RtlAllocateHeap(RtlGetProcessHeap(),
2213 0,
2214 ObjectNameSize);
2215 if (pObjectNameA != NULL)
2216 {
2217 pObjectNameA[0] = '\0';
2218 WideCharToMultiByte(CP_ACP,
2219 0,
2220 pObjectName,
2221 -1,
2222 pObjectNameA,
2223 ObjectNameSize,
2224 NULL,
2225 NULL);
2226
2227 pifnProgressData->fnProgress((LPWSTR)pObjectNameA, /* FIXME: wrong cast!! */
2228 Status,
2229 pInvokeSetting,
2230 pifnProgressData->Args,
2231 SecuritySet);
2232
2233 RtlFreeHeap(RtlGetProcessHeap(),
2234 0,
2235 pObjectNameA);
2236 }
2237 }
2238 }
2239 #endif
2240
2241
2242 /*
2243 * @implemented
2244 */
2245 DWORD
2246 WINAPI
2247 TreeResetNamedSecurityInfoA(LPSTR pObjectName,
2248 SE_OBJECT_TYPE ObjectType,
2249 SECURITY_INFORMATION SecurityInfo,
2250 PSID pOwner,
2251 PSID pGroup,
2252 PACL pDacl,
2253 PACL pSacl,
2254 BOOL KeepExplicit,
2255 FN_PROGRESSA fnProgress,
2256 PROG_INVOKE_SETTING ProgressInvokeSetting,
2257 PVOID Args)
2258 {
2259 #ifndef HAS_FN_PROGRESSW
2260 /* That's all this function does, at least up to w2k3... Even MS was too
2261 lazy to implement it... */
2262 return ERROR_CALL_NOT_IMPLEMENTED;
2263 #else
2264 INERNAL_FNPROGRESSW_DATA ifnProgressData;
2265 UNICODE_STRING ObjectName;
2266 NTSTATUS Status;
2267 DWORD Ret;
2268
2269 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
2270 pObjectName);
2271 if (!NT_SUCCESS(Status))
2272 {
2273 return RtlNtStatusToDosError(Status);
2274 }
2275
2276 ifnProgressData.fnProgress = fnProgress;
2277 ifnProgressData.Args = Args;
2278
2279 Ret = TreeResetNamedSecurityInfoW(ObjectName.Buffer,
2280 ObjectType,
2281 SecurityInfo,
2282 pOwner,
2283 pGroup,
2284 pDacl,
2285 pSacl,
2286 KeepExplicit,
2287 (fnProgress != NULL ? InternalfnProgressW : NULL),
2288 ProgressInvokeSetting,
2289 &ifnProgressData);
2290
2291 RtlFreeUnicodeString(&ObjectName);
2292
2293 return Ret;
2294 #endif
2295 }
2296
2297 /******************************************************************************
2298 * SaferCreateLevel [ADVAPI32.@]
2299 */
2300 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
2301 SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
2302 {
2303 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
2304 return FALSE;
2305 }
2306
2307 /******************************************************************************
2308 * SaferGetPolicyInformation [ADVAPI32.@]
2309 */
2310 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
2311 PVOID buffer, PDWORD required, LPVOID lpReserved)
2312 {
2313 FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
2314 return FALSE;
2315 }
2316
2317 /******************************************************************************
2318 * QueryWindows31FilesMigration [ADVAPI32.@]
2319 *
2320 * PARAMS
2321 * x1 []
2322 */
2323 BOOL WINAPI
2324 QueryWindows31FilesMigration( DWORD x1 )
2325 {
2326 FIXME("(%d):stub\n",x1);
2327 return TRUE;
2328 }
2329
2330 /******************************************************************************
2331 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2332 *
2333 * PARAMS
2334 * x1 []
2335 * x2 []
2336 * x3 []
2337 * x4 []
2338 */
2339 BOOL WINAPI
2340 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2341 DWORD x4 )
2342 {
2343 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2344 return TRUE;
2345 }
2346
2347 /* EOF */