- Create KD branch. All debugging support is removed in this branch (no symbols,...
[reactos.git] / reactos / dll / win32 / ntmarta / ntmarta.c
1 /*
2 * ReactOS MARTA provider
3 * Copyright (C) 2005 - 2006 ReactOS Team
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 /* $Id$
20 *
21 * PROJECT: ReactOS MARTA provider
22 * FILE: lib/ntmarta/ntmarta.c
23 * PURPOSE: ReactOS MARTA provider
24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
25 *
26 * UPDATE HISTORY:
27 * 07/26/2005 Created
28 */
29 #include <ntmarta.h>
30
31 #define NDEBUG
32 #include <debug.h>
33
34 HINSTANCE hDllInstance;
35
36 static ACCESS_MODE
37 AccpGetAceAccessMode(IN PACE_HEADER AceHeader)
38 {
39 ACCESS_MODE Mode = NOT_USED_ACCESS;
40
41 switch (AceHeader->AceType)
42 {
43 case ACCESS_ALLOWED_ACE_TYPE:
44 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE:
45 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
46 case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
47 Mode = GRANT_ACCESS;
48 break;
49
50 case ACCESS_DENIED_ACE_TYPE:
51 case ACCESS_DENIED_CALLBACK_ACE_TYPE:
52 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
53 case ACCESS_DENIED_OBJECT_ACE_TYPE:
54 Mode = DENY_ACCESS;
55 break;
56
57 case SYSTEM_AUDIT_ACE_TYPE:
58 case SYSTEM_AUDIT_CALLBACK_ACE_TYPE:
59 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
60 case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
61 if (AceHeader->AceFlags & FAILED_ACCESS_ACE_FLAG)
62 Mode = SET_AUDIT_FAILURE;
63 else if (AceHeader->AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
64 Mode = SET_AUDIT_SUCCESS;
65 break;
66 }
67
68 return Mode;
69 }
70
71 static UINT
72 AccpGetAceStructureSize(IN PACE_HEADER AceHeader)
73 {
74 UINT Size = 0;
75
76 switch (AceHeader->AceType)
77 {
78 case ACCESS_ALLOWED_ACE_TYPE:
79 case ACCESS_DENIED_ACE_TYPE:
80 Size = FIELD_OFFSET(ACCESS_ALLOWED_ACE,
81 SidStart);
82 break;
83 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE:
84 case ACCESS_DENIED_CALLBACK_ACE_TYPE:
85 Size = FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_ACE,
86 SidStart);
87 break;
88 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
89 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
90 {
91 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader;
92 Size = FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_OBJECT_ACE,
93 ObjectType);
94 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
95 Size += sizeof(Ace->ObjectType);
96 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
97 Size += sizeof(Ace->InheritedObjectType);
98 break;
99 }
100 case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
101 case ACCESS_DENIED_OBJECT_ACE_TYPE:
102 {
103 PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader;
104 Size = FIELD_OFFSET(ACCESS_ALLOWED_OBJECT_ACE,
105 ObjectType);
106 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
107 Size += sizeof(Ace->ObjectType);
108 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
109 Size += sizeof(Ace->InheritedObjectType);
110 break;
111 }
112
113 case SYSTEM_AUDIT_ACE_TYPE:
114 Size = FIELD_OFFSET(SYSTEM_AUDIT_ACE,
115 SidStart);
116 break;
117 case SYSTEM_AUDIT_CALLBACK_ACE_TYPE:
118 Size = FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_ACE,
119 SidStart);
120 break;
121 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
122 {
123 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader;
124 Size = FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_OBJECT_ACE,
125 ObjectType);
126 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
127 Size += sizeof(Ace->ObjectType);
128 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
129 Size += sizeof(Ace->InheritedObjectType);
130 break;
131 }
132 case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
133 {
134 PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader;
135 Size = FIELD_OFFSET(SYSTEM_AUDIT_OBJECT_ACE,
136 ObjectType);
137 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
138 Size += sizeof(Ace->ObjectType);
139 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
140 Size += sizeof(Ace->InheritedObjectType);
141 break;
142 }
143 }
144
145 return Size;
146 }
147
148 static PSID
149 AccpGetAceSid(IN PACE_HEADER AceHeader)
150 {
151 return (PSID)((ULONG_PTR)AceHeader + AccpGetAceStructureSize(AceHeader));
152 }
153
154 static ACCESS_MASK
155 AccpGetAceAccessMask(IN PACE_HEADER AceHeader)
156 {
157 return *((PACCESS_MASK)(AceHeader + 1));
158 }
159
160 static BOOL
161 AccpIsObjectAce(IN PACE_HEADER AceHeader)
162 {
163 BOOL Ret;
164
165 switch (AceHeader->AceType)
166 {
167 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
168 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
169 case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
170 case ACCESS_DENIED_OBJECT_ACE_TYPE:
171 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
172 case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
173 Ret = TRUE;
174 break;
175
176 default:
177 Ret = FALSE;
178 break;
179 }
180
181 return Ret;
182 }
183
184 static GUID*
185 AccpGetObjectAceObjectType(IN PACE_HEADER AceHeader)
186 {
187 GUID *ObjectType = NULL;
188
189 switch (AceHeader->AceType)
190 {
191 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
192 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
193 {
194 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader;
195 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
196 ObjectType = &Ace->ObjectType;
197 break;
198 }
199 case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
200 case ACCESS_DENIED_OBJECT_ACE_TYPE:
201 {
202 PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader;
203 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
204 ObjectType = &Ace->ObjectType;
205 break;
206 }
207
208 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
209 {
210 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader;
211 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
212 ObjectType = &Ace->ObjectType;
213 break;
214 }
215 case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
216 {
217 PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader;
218 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
219 ObjectType = &Ace->ObjectType;
220 break;
221 }
222 }
223
224 return ObjectType;
225 }
226
227 static GUID*
228 AccpGetObjectAceInheritedObjectType(IN PACE_HEADER AceHeader)
229 {
230 GUID *ObjectType = NULL;
231
232 switch (AceHeader->AceType)
233 {
234 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
235 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
236 {
237 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader;
238 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
239 {
240 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
241 ObjectType = &Ace->InheritedObjectType;
242 else
243 ObjectType = &Ace->ObjectType;
244 }
245 break;
246 }
247 case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
248 case ACCESS_DENIED_OBJECT_ACE_TYPE:
249 {
250 PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader;
251 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
252 {
253 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
254 ObjectType = &Ace->InheritedObjectType;
255 else
256 ObjectType = &Ace->ObjectType;
257 }
258 break;
259 }
260
261 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
262 {
263 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader;
264 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
265 {
266 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
267 ObjectType = &Ace->InheritedObjectType;
268 else
269 ObjectType = &Ace->ObjectType;
270 }
271 break;
272 }
273 case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
274 {
275 PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader;
276 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
277 {
278 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
279 ObjectType = &Ace->InheritedObjectType;
280 else
281 ObjectType = &Ace->ObjectType;
282 }
283 break;
284 }
285 }
286
287 return ObjectType;
288 }
289
290
291 /**********************************************************************
292 * AccRewriteGetHandleRights EXPORTED
293 *
294 * @unimplemented
295 */
296 DWORD WINAPI
297 AccRewriteGetHandleRights(HANDLE handle,
298 SE_OBJECT_TYPE ObjectType,
299 SECURITY_INFORMATION SecurityInfo,
300 PSID* ppsidOwner,
301 PSID* ppsidGroup,
302 PACL* ppDacl,
303 PACL* ppSacl,
304 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
305 {
306 PSECURITY_DESCRIPTOR pSD = NULL;
307 ULONG SDSize = 0;
308 NTSTATUS Status;
309 DWORD LastErr;
310 DWORD Ret;
311
312 /* save the last error code */
313 LastErr = GetLastError();
314
315 do
316 {
317 Ret = ERROR_SUCCESS;
318
319 /* allocate a buffer large enough to hold the
320 security descriptor we need to return */
321 SDSize += 0x100;
322 if (pSD == NULL)
323 {
324 pSD = LocalAlloc(LMEM_FIXED,
325 (SIZE_T)SDSize);
326 }
327 else
328 {
329 PSECURITY_DESCRIPTOR newSD;
330
331 newSD = LocalReAlloc((HLOCAL)pSD,
332 (SIZE_T)SDSize,
333 LMEM_MOVEABLE);
334 if (newSD != NULL)
335 pSD = newSD;
336 }
337
338 if (pSD == NULL)
339 {
340 Ret = GetLastError();
341 break;
342 }
343
344 /* perform the actual query depending on the object type */
345 switch (ObjectType)
346 {
347 case SE_REGISTRY_KEY:
348 {
349 Ret = (DWORD)RegGetKeySecurity((HKEY)handle,
350 SecurityInfo,
351 pSD,
352 &SDSize);
353 break;
354 }
355
356 case SE_FILE_OBJECT:
357 /* FIXME - handle console handles? */
358 case SE_KERNEL_OBJECT:
359 {
360 Status = NtQuerySecurityObject(handle,
361 SecurityInfo,
362 pSD,
363 SDSize,
364 &SDSize);
365 if (!NT_SUCCESS(Status))
366 {
367 Ret = RtlNtStatusToDosError(Status);
368 }
369 break;
370 }
371
372 case SE_SERVICE:
373 {
374 if (!QueryServiceObjectSecurity((SC_HANDLE)handle,
375 SecurityInfo,
376 pSD,
377 SDSize,
378 &SDSize))
379 {
380 Ret = GetLastError();
381 }
382 break;
383 }
384
385 case SE_WINDOW_OBJECT:
386 {
387 if (!GetUserObjectSecurity(handle,
388 &SecurityInfo,
389 pSD,
390 SDSize,
391 &SDSize))
392 {
393 Ret = GetLastError();
394 }
395 break;
396 }
397
398 default:
399 {
400 UNIMPLEMENTED;
401 Ret = ERROR_CALL_NOT_IMPLEMENTED;
402 break;
403 }
404 }
405
406 } while (Ret == ERROR_INSUFFICIENT_BUFFER);
407
408 if (Ret == ERROR_SUCCESS)
409 {
410 BOOL Present, Defaulted;
411
412 if (SecurityInfo & OWNER_SECURITY_INFORMATION && ppsidOwner != NULL)
413 {
414 *ppsidOwner = NULL;
415 if (!GetSecurityDescriptorOwner(pSD,
416 ppsidOwner,
417 &Defaulted))
418 {
419 Ret = GetLastError();
420 goto Cleanup;
421 }
422 }
423
424 if (SecurityInfo & GROUP_SECURITY_INFORMATION && ppsidGroup != NULL)
425 {
426 *ppsidOwner = NULL;
427 if (!GetSecurityDescriptorGroup(pSD,
428 ppsidGroup,
429 &Defaulted))
430 {
431 Ret = GetLastError();
432 goto Cleanup;
433 }
434 }
435
436 if (SecurityInfo & DACL_SECURITY_INFORMATION && ppDacl != NULL)
437 {
438 *ppDacl = NULL;
439 if (!GetSecurityDescriptorDacl(pSD,
440 &Present,
441 ppDacl,
442 &Defaulted))
443 {
444 Ret = GetLastError();
445 goto Cleanup;
446 }
447 }
448
449 if (SecurityInfo & SACL_SECURITY_INFORMATION && ppSacl != NULL)
450 {
451 *ppSacl = NULL;
452 if (!GetSecurityDescriptorSacl(pSD,
453 &Present,
454 ppSacl,
455 &Defaulted))
456 {
457 Ret = GetLastError();
458 goto Cleanup;
459 }
460 }
461
462 *ppSecurityDescriptor = pSD;
463 }
464 else
465 {
466 Cleanup:
467 if (pSD != NULL)
468 {
469 LocalFree((HLOCAL)pSD);
470 }
471 }
472
473 /* restore the last error code */
474 SetLastError(LastErr);
475
476 return Ret;
477 }
478
479
480 /**********************************************************************
481 * AccRewriteSetHandleRights EXPORTED
482 *
483 * @unimplemented
484 */
485 DWORD WINAPI
486 AccRewriteSetHandleRights(HANDLE handle,
487 SE_OBJECT_TYPE ObjectType,
488 SECURITY_INFORMATION SecurityInfo,
489 PSECURITY_DESCRIPTOR pSecurityDescriptor)
490 {
491 NTSTATUS Status;
492 DWORD LastErr;
493 DWORD Ret = ERROR_SUCCESS;
494
495 /* save the last error code */
496 LastErr = GetLastError();
497
498 /* set the security according to the object type */
499 switch (ObjectType)
500 {
501 case SE_REGISTRY_KEY:
502 {
503 Ret = (DWORD)RegSetKeySecurity((HKEY)handle,
504 SecurityInfo,
505 pSecurityDescriptor);
506 break;
507 }
508
509 case SE_FILE_OBJECT:
510 /* FIXME - handle console handles? */
511 case SE_KERNEL_OBJECT:
512 {
513 Status = NtSetSecurityObject(handle,
514 SecurityInfo,
515 pSecurityDescriptor);
516 if (!NT_SUCCESS(Status))
517 {
518 Ret = RtlNtStatusToDosError(Status);
519 }
520 break;
521 }
522
523 case SE_SERVICE:
524 {
525 if (!SetServiceObjectSecurity((SC_HANDLE)handle,
526 SecurityInfo,
527 pSecurityDescriptor))
528 {
529 Ret = GetLastError();
530 }
531 break;
532 }
533
534 case SE_WINDOW_OBJECT:
535 {
536 if (!SetUserObjectSecurity(handle,
537 &SecurityInfo,
538 pSecurityDescriptor))
539 {
540 Ret = GetLastError();
541 }
542 break;
543 }
544
545 default:
546 {
547 UNIMPLEMENTED;
548 Ret = ERROR_CALL_NOT_IMPLEMENTED;
549 break;
550 }
551 }
552
553
554 /* restore the last error code */
555 SetLastError(LastErr);
556
557 return Ret;
558 }
559
560
561 static DWORD
562 AccpOpenNamedObject(LPWSTR pObjectName,
563 SE_OBJECT_TYPE ObjectType,
564 SECURITY_INFORMATION SecurityInfo,
565 PHANDLE Handle,
566 PHANDLE Handle2,
567 BOOL Write)
568 {
569 LPWSTR lpPath;
570 NTSTATUS Status;
571 ACCESS_MASK DesiredAccess = (ACCESS_MASK)0;
572 DWORD Ret = ERROR_SUCCESS;
573
574 /* determine the required access rights */
575 switch (ObjectType)
576 {
577 case SE_REGISTRY_KEY:
578 case SE_FILE_OBJECT:
579 case SE_KERNEL_OBJECT:
580 case SE_SERVICE:
581 case SE_WINDOW_OBJECT:
582 if (Write)
583 {
584 if (SecurityInfo & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
585 DesiredAccess |= WRITE_OWNER;
586 if (SecurityInfo & DACL_SECURITY_INFORMATION)
587 DesiredAccess |= WRITE_DAC;
588 if (SecurityInfo & SACL_SECURITY_INFORMATION)
589 DesiredAccess |= ACCESS_SYSTEM_SECURITY;
590 }
591 else
592 {
593 if (SecurityInfo & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
594 DACL_SECURITY_INFORMATION))
595 DesiredAccess |= READ_CONTROL;
596 if (SecurityInfo & SACL_SECURITY_INFORMATION)
597 DesiredAccess |= ACCESS_SYSTEM_SECURITY;
598 }
599 break;
600
601 default:
602 break;
603 }
604
605 /* make a copy of the path if we're modifying the string */
606 switch (ObjectType)
607 {
608 case SE_REGISTRY_KEY:
609 case SE_SERVICE:
610 lpPath = (LPWSTR)LocalAlloc(LMEM_FIXED,
611 (wcslen(pObjectName) + 1) * sizeof(WCHAR));
612 if (lpPath == NULL)
613 {
614 Ret = GetLastError();
615 goto Cleanup;
616 }
617
618 wcscpy(lpPath,
619 pObjectName);
620 break;
621
622 default:
623 lpPath = pObjectName;
624 break;
625 }
626
627 /* open a handle to the path depending on the object type */
628 switch (ObjectType)
629 {
630 case SE_FILE_OBJECT:
631 {
632 IO_STATUS_BLOCK IoStatusBlock;
633 OBJECT_ATTRIBUTES ObjectAttributes;
634 UNICODE_STRING FileName;
635
636 if (!RtlDosPathNameToNtPathName_U(pObjectName,
637 &FileName,
638 NULL,
639 NULL))
640 {
641 Ret = ERROR_INVALID_NAME;
642 goto Cleanup;
643 }
644
645 InitializeObjectAttributes(&ObjectAttributes,
646 &FileName,
647 OBJ_CASE_INSENSITIVE,
648 NULL,
649 NULL);
650
651 Status = NtOpenFile(Handle,
652 DesiredAccess,
653 &ObjectAttributes,
654 &IoStatusBlock,
655 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
656 FILE_SYNCHRONOUS_IO_NONALERT);
657
658 RtlFreeHeap(RtlGetProcessHeap(),
659 0,
660 FileName.Buffer);
661
662 if (!NT_SUCCESS(Status))
663 {
664 Ret = RtlNtStatusToDosError(Status);
665 }
666 break;
667 }
668
669 case SE_REGISTRY_KEY:
670 {
671 static const struct
672 {
673 HKEY hRootKey;
674 LPCWSTR szRootKey;
675 } AccRegRootKeys[] =
676 {
677 {HKEY_CLASSES_ROOT, L"CLASSES_ROOT"},
678 {HKEY_CURRENT_USER, L"CURRENT_USER"},
679 {HKEY_LOCAL_MACHINE, L"MACHINE"},
680 {HKEY_USERS, L"USERS"},
681 {HKEY_CURRENT_CONFIG, L"CONFIG"},
682 };
683 LPWSTR lpMachineName, lpRootKeyName, lpKeyName;
684 HKEY hRootKey = NULL;
685 UINT i;
686
687 /* parse the registry path */
688 if (lpPath[0] == L'\\' && lpPath[1] == L'\\')
689 {
690 lpMachineName = lpPath;
691
692 lpRootKeyName = wcschr(lpPath + 2,
693 L'\\');
694 if (lpRootKeyName == NULL)
695 goto ParseRegErr;
696 else
697 *(lpRootKeyName++) = L'\0';
698 }
699 else
700 {
701 lpMachineName = NULL;
702 lpRootKeyName = lpPath;
703 }
704
705 lpKeyName = wcschr(lpRootKeyName,
706 L'\\');
707 if (lpKeyName != NULL)
708 {
709 *(lpKeyName++) = L'\0';
710 }
711
712 for (i = 0;
713 i != sizeof(AccRegRootKeys) / sizeof(AccRegRootKeys[0]);
714 i++)
715 {
716 if (!wcsicmp(lpRootKeyName,
717 AccRegRootKeys[i].szRootKey))
718 {
719 hRootKey = AccRegRootKeys[i].hRootKey;
720 break;
721 }
722 }
723
724 if (hRootKey == NULL)
725 {
726 ParseRegErr:
727 /* FIXME - right error code? */
728 Ret = ERROR_INVALID_PARAMETER;
729 goto Cleanup;
730 }
731
732 /* open the registry key */
733 if (lpMachineName != NULL)
734 {
735 Ret = RegConnectRegistry(lpMachineName,
736 hRootKey,
737 (PHKEY)Handle2);
738
739 if (Ret != ERROR_SUCCESS)
740 goto Cleanup;
741
742 hRootKey = (HKEY)(*Handle2);
743 }
744
745 Ret = RegOpenKeyEx(hRootKey,
746 lpKeyName,
747 0,
748 (REGSAM)DesiredAccess,
749 (PHKEY)Handle);
750 if (Ret != ERROR_SUCCESS)
751 {
752 if (*Handle2 != NULL)
753 {
754 RegCloseKey((HKEY)(*Handle2));
755 }
756
757 goto Cleanup;
758 }
759 break;
760 }
761
762 case SE_SERVICE:
763 {
764 LPWSTR lpServiceName, lpMachineName;
765
766 /* parse the service path */
767 if (lpPath[0] == L'\\' && lpPath[1] == L'\\')
768 {
769 DesiredAccess |= SC_MANAGER_CONNECT;
770
771 lpMachineName = lpPath;
772
773 lpServiceName = wcschr(lpPath + 2,
774 L'\\');
775 if (lpServiceName == NULL)
776 {
777 /* FIXME - right error code? */
778 Ret = ERROR_INVALID_PARAMETER;
779 goto Cleanup;
780 }
781 else
782 *(lpServiceName++) = L'\0';
783 }
784 else
785 {
786 lpMachineName = NULL;
787 lpServiceName = lpPath;
788 }
789
790 /* open the service */
791 *Handle2 = (HANDLE)OpenSCManager(lpMachineName,
792 NULL,
793 (DWORD)DesiredAccess);
794 if (*Handle2 == NULL)
795 {
796 goto FailOpenService;
797 }
798
799 DesiredAccess &= ~SC_MANAGER_CONNECT;
800 *Handle = (HANDLE)OpenService((SC_HANDLE)(*Handle2),
801 lpServiceName,
802 (DWORD)DesiredAccess);
803 if (*Handle == NULL)
804 {
805 if (*Handle2 != NULL)
806 {
807 CloseServiceHandle((SC_HANDLE)(*Handle2));
808 }
809
810 FailOpenService:
811 Ret = GetLastError();
812 goto Cleanup;
813 }
814 break;
815 }
816
817 default:
818 {
819 UNIMPLEMENTED;
820 Ret = ERROR_CALL_NOT_IMPLEMENTED;
821 break;
822 }
823 }
824
825 Cleanup:
826 if (lpPath != NULL && lpPath != pObjectName)
827 {
828 LocalFree((HLOCAL)lpPath);
829 }
830
831 return Ret;
832 }
833
834
835 static VOID
836 AccpCloseObjectHandle(SE_OBJECT_TYPE ObjectType,
837 HANDLE Handle,
838 HANDLE Handle2)
839 {
840 ASSERT(Handle != NULL);
841
842 /* close allocated handlees depending on the object type */
843 switch (ObjectType)
844 {
845 case SE_REGISTRY_KEY:
846 RegCloseKey((HKEY)Handle);
847 if (Handle2 != NULL)
848 RegCloseKey((HKEY)Handle2);
849 break;
850
851 case SE_FILE_OBJECT:
852 NtClose(Handle);
853 break;
854
855 case SE_KERNEL_OBJECT:
856 case SE_WINDOW_OBJECT:
857 CloseHandle(Handle);
858 break;
859
860 case SE_SERVICE:
861 CloseServiceHandle((SC_HANDLE)Handle);
862 ASSERT(Handle2 != NULL);
863 CloseServiceHandle((SC_HANDLE)Handle2);
864 break;
865
866 default:
867 break;
868 }
869 }
870
871
872 /**********************************************************************
873 * AccRewriteGetNamedRights EXPORTED
874 *
875 * @unimplemented
876 */
877 DWORD WINAPI
878 AccRewriteGetNamedRights(LPWSTR pObjectName,
879 SE_OBJECT_TYPE ObjectType,
880 SECURITY_INFORMATION SecurityInfo,
881 PSID* ppsidOwner,
882 PSID* ppsidGroup,
883 PACL* ppDacl,
884 PACL* ppSacl,
885 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
886 {
887 HANDLE Handle = NULL;
888 HANDLE Handle2 = NULL;
889 DWORD LastErr;
890 DWORD Ret;
891
892 /* save the last error code */
893 LastErr = GetLastError();
894
895 /* create the handle */
896 Ret = AccpOpenNamedObject(pObjectName,
897 ObjectType,
898 SecurityInfo,
899 &Handle,
900 &Handle2,
901 FALSE);
902
903 if (Ret == ERROR_SUCCESS)
904 {
905 ASSERT(Handle != NULL);
906
907 /* perform the operation */
908 Ret = AccRewriteGetHandleRights(Handle,
909 ObjectType,
910 SecurityInfo,
911 ppsidOwner,
912 ppsidGroup,
913 ppDacl,
914 ppSacl,
915 ppSecurityDescriptor);
916
917 /* close opened handles */
918 AccpCloseObjectHandle(ObjectType,
919 Handle,
920 Handle2);
921 }
922
923 /* restore the last error code */
924 SetLastError(LastErr);
925
926 return Ret;
927 }
928
929
930 /**********************************************************************
931 * AccRewriteSetNamedRights EXPORTED
932 *
933 * @unimplemented
934 */
935 DWORD WINAPI
936 AccRewriteSetNamedRights(LPWSTR pObjectName,
937 SE_OBJECT_TYPE ObjectType,
938 SECURITY_INFORMATION SecurityInfo,
939 PSECURITY_DESCRIPTOR pSecurityDescriptor)
940 {
941 HANDLE Handle = NULL;
942 HANDLE Handle2 = NULL;
943 DWORD LastErr;
944 DWORD Ret;
945
946 /* save the last error code */
947 LastErr = GetLastError();
948
949 /* create the handle */
950 Ret = AccpOpenNamedObject(pObjectName,
951 ObjectType,
952 SecurityInfo,
953 &Handle,
954 &Handle2,
955 TRUE);
956
957 if (Ret == ERROR_SUCCESS)
958 {
959 ASSERT(Handle != NULL);
960
961 /* perform the operation */
962 Ret = AccRewriteSetHandleRights(Handle,
963 ObjectType,
964 SecurityInfo,
965 pSecurityDescriptor);
966
967 /* close opened handles */
968 AccpCloseObjectHandle(ObjectType,
969 Handle,
970 Handle2);
971 }
972
973 /* restore the last error code */
974 SetLastError(LastErr);
975
976 return Ret;
977 }
978
979
980 /**********************************************************************
981 * AccRewriteSetEntriesInAcl EXPORTED
982 *
983 * @unimplemented
984 */
985 DWORD WINAPI
986 AccRewriteSetEntriesInAcl(ULONG cCountOfExplicitEntries,
987 PEXPLICIT_ACCESS_W pListOfExplicitEntries,
988 PACL OldAcl,
989 PACL* NewAcl)
990 {
991 UNIMPLEMENTED;
992 return ERROR_CALL_NOT_IMPLEMENTED;
993 }
994
995
996 /**********************************************************************
997 * AccRewriteSetEntriesInAcl EXPORTED
998 *
999 * @unimplemented
1000 */
1001 DWORD WINAPI
1002 AccGetInheritanceSource(LPWSTR pObjectName,
1003 SE_OBJECT_TYPE ObjectType,
1004 SECURITY_INFORMATION SecurityInfo,
1005 BOOL Container,
1006 GUID** pObjectClassGuids,
1007 DWORD GuidCount,
1008 PACL pAcl,
1009 PFN_OBJECT_MGR_FUNCTS pfnArray,
1010 PGENERIC_MAPPING pGenericMapping,
1011 PINHERITED_FROMW pInheritArray)
1012 {
1013 UNIMPLEMENTED;
1014 return ERROR_CALL_NOT_IMPLEMENTED;
1015 }
1016
1017
1018 /**********************************************************************
1019 * AccFreeIndexArray EXPORTED
1020 *
1021 * @implemented
1022 */
1023 DWORD WINAPI
1024 AccFreeIndexArray(PINHERITED_FROMW pInheritArray,
1025 USHORT AceCnt,
1026 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL)
1027 {
1028 PINHERITED_FROMW pLast;
1029
1030 UNREFERENCED_PARAMETER(pfnArray);
1031
1032 pLast = pInheritArray + AceCnt;
1033 while (pInheritArray != pLast)
1034 {
1035 if (pInheritArray->AncestorName != NULL)
1036 {
1037 LocalFree((HLOCAL)pInheritArray->AncestorName);
1038 pInheritArray->AncestorName = NULL;
1039 }
1040
1041 pInheritArray++;
1042 }
1043
1044 return ERROR_SUCCESS;
1045 }
1046
1047
1048 /**********************************************************************
1049 * AccRewriteGetExplicitEntriesFromAcl EXPORTED
1050 *
1051 * @implemented
1052 */
1053 DWORD WINAPI
1054 AccRewriteGetExplicitEntriesFromAcl(PACL pacl,
1055 PULONG pcCountOfExplicitEntries,
1056 PEXPLICIT_ACCESS_W* pListOfExplicitEntries)
1057 {
1058 PACE_HEADER AceHeader;
1059 PSID Sid, SidTarget;
1060 ULONG ObjectAceCount = 0;
1061 POBJECTS_AND_SID ObjSid;
1062 SIZE_T Size;
1063 PEXPLICIT_ACCESS_W peaw;
1064 DWORD LastErr, SidLen;
1065 DWORD AceIndex = 0;
1066 DWORD ErrorCode = ERROR_SUCCESS;
1067
1068 /* save the last error code */
1069 LastErr = GetLastError();
1070
1071 if (pacl != NULL)
1072 {
1073 if (pacl->AceCount != 0)
1074 {
1075 Size = (SIZE_T)pacl->AceCount * sizeof(EXPLICIT_ACCESS_W);
1076
1077 /* calculate the space needed */
1078 while (GetAce(pacl,
1079 AceIndex,
1080 (LPVOID*)&AceHeader))
1081 {
1082 Sid = AccpGetAceSid(AceHeader);
1083 Size += GetLengthSid(Sid);
1084
1085 if (AccpIsObjectAce(AceHeader))
1086 ObjectAceCount++;
1087
1088 AceIndex++;
1089 }
1090
1091 Size += ObjectAceCount * sizeof(OBJECTS_AND_SID);
1092
1093 ASSERT(pacl->AceCount == AceIndex);
1094
1095 /* allocate the array */
1096 peaw = (PEXPLICIT_ACCESS_W)LocalAlloc(LMEM_FIXED,
1097 Size);
1098 if (peaw != NULL)
1099 {
1100 AceIndex = 0;
1101 ObjSid = (POBJECTS_AND_SID)(peaw + pacl->AceCount);
1102 SidTarget = (PSID)(ObjSid + ObjectAceCount);
1103
1104 /* initialize the array */
1105 while (GetAce(pacl,
1106 AceIndex,
1107 (LPVOID*)&AceHeader))
1108 {
1109 Sid = AccpGetAceSid(AceHeader);
1110 SidLen = GetLengthSid(Sid);
1111
1112 peaw[AceIndex].grfAccessPermissions = AccpGetAceAccessMask(AceHeader);
1113 peaw[AceIndex].grfAccessMode = AccpGetAceAccessMode(AceHeader);
1114 peaw[AceIndex].grfInheritance = AceHeader->AceFlags & VALID_INHERIT_FLAGS;
1115
1116 if (CopySid(SidLen,
1117 SidTarget,
1118 Sid))
1119 {
1120 if (AccpIsObjectAce(AceHeader))
1121 {
1122 BuildTrusteeWithObjectsAndSid(&peaw[AceIndex].Trustee,
1123 ObjSid++,
1124 AccpGetObjectAceObjectType(AceHeader),
1125 AccpGetObjectAceInheritedObjectType(AceHeader),
1126 SidTarget);
1127 }
1128 else
1129 {
1130 BuildTrusteeWithSid(&peaw[AceIndex].Trustee,
1131 SidTarget);
1132 }
1133
1134 SidTarget = (PSID)((ULONG_PTR)SidTarget + SidLen);
1135 }
1136 else
1137 {
1138 /* copying the SID failed, treat it as an fatal error... */
1139 ErrorCode = GetLastError();
1140
1141 /* free allocated resources */
1142 LocalFree(peaw);
1143 peaw = NULL;
1144 AceIndex = 0;
1145 break;
1146 }
1147
1148 AceIndex++;
1149 }
1150
1151 *pcCountOfExplicitEntries = AceIndex;
1152 *pListOfExplicitEntries = peaw;
1153 }
1154 else
1155 ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
1156 }
1157 else
1158 {
1159 goto EmptyACL;
1160 }
1161 }
1162 else
1163 {
1164 EmptyACL:
1165 *pcCountOfExplicitEntries = 0;
1166 *pListOfExplicitEntries = NULL;
1167 }
1168
1169 /* restore the last error code */
1170 SetLastError(LastErr);
1171
1172 return ErrorCode;
1173 }
1174
1175
1176 /**********************************************************************
1177 * AccTreeResetNamedSecurityInfo EXPORTED
1178 *
1179 * @unimplemented
1180 */
1181 DWORD WINAPI
1182 AccTreeResetNamedSecurityInfo(LPWSTR pObjectName,
1183 SE_OBJECT_TYPE ObjectType,
1184 SECURITY_INFORMATION SecurityInfo,
1185 PSID pOwner,
1186 PSID pGroup,
1187 PACL pDacl,
1188 PACL pSacl,
1189 BOOL KeepExplicit,
1190 FN_PROGRESSW fnProgress,
1191 PROG_INVOKE_SETTING ProgressInvokeSetting,
1192 PVOID Args)
1193 {
1194 UNIMPLEMENTED;
1195 return ERROR_CALL_NOT_IMPLEMENTED;
1196 }
1197
1198
1199 BOOL WINAPI
1200 DllMain(IN HINSTANCE hinstDLL,
1201 IN DWORD dwReason,
1202 IN LPVOID lpvReserved)
1203 {
1204 switch (dwReason)
1205 {
1206 case DLL_PROCESS_ATTACH:
1207 hDllInstance = hinstDLL;
1208 DisableThreadLibraryCalls(hinstDLL);
1209 break;
1210
1211 case DLL_PROCESS_DETACH:
1212 break;
1213 }
1214 return TRUE;
1215 }
1216