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