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