00568                    :
00569 
00570     This routine will extract 
the desired information from 
the
00571     passed security descriptor and 
return the information in
00572     
the passed buffer as a security descriptor in 
self-relative
00573     
format.
00574 
00575 Arguments:
00576 
00577     SecurityInformation - Specifies what information 
is being queried.
00578 
00579     SecurityDescriptor - Supplies 
the buffer to output 
the requested
00580         information into.
00581 
00582         This buffer has been probed 
only to 
the size indicated by
00583         
the Length parameter.  Since 
it still points into user space,
00584         
it must always be accessed in a 
try clause.
00585 
00586     Length - Supplies 
the address of a variable containing 
the length of
00587         
the security descriptor buffer.  Upon 
return this variable will
00588         contain 
the length needed to store 
the requested information.
00589 
00590     ObjectsSecurityDescriptor - Supplies 
the address of a pointer to
00591         
the objects security descriptor.  The passed security descriptor
00592         must be in 
self-relative 
format.
00593 
00594 Return Value:
00595 
00596     
NTSTATUS - STATUS_SUCCESS 
if successful and an appropriate error value
00597         otherwise
00598 
00599 --*/
00600 
00601 {
00602     ULONG BufferLength;
00603 
00604     ULONG 
Size;
00605     ULONG OwnerLength;
00606     ULONG GroupLength;
00607     ULONG DaclLength;
00608     ULONG SaclLength;
00609     PUCHAR NextFree;
00610     SECURITY_DESCRIPTOR IObjectSecurity;
00611 
00612     
00613     
00614     
00615     
00616 
00617     SECURITY_DESCRIPTOR_RELATIVE *ISecurityDescriptor = SecurityDescriptor;
00618 
00619     
PAGED_CODE();
00620 
00621     
00622     
00623     
00624     
00625 
00626     
try {
00627 
00628         BufferLength = *Length;
00629 
00630         
00631         
00632         
00633         
00634 
00635         
if (*ObjectsSecurityDescriptor == 
NULL) {
00636 
00637             *Length = 
sizeof(SECURITY_DESCRIPTOR_RELATIVE);
00638 
00639             
00640             
00641             
00642             
00643 
00644             
if (BufferLength < 
sizeof(SECURITY_DESCRIPTOR_RELATIVE)) {
00645 
00646                 
return STATUS_BUFFER_TOO_SMALL;
00647 
00648             }
00649 
00650             
00651             
00652             
00653             
00654             
00655             
00656             
00657 
00658             
00659             
00660             
00661             
00662             
00663             
00664 
00665             
RtlCreateSecurityDescriptorRelative( SecurityDescriptor,
00666                                                  SECURITY_DESCRIPTOR_REVISION );
00667 
00668             
00669             
00670             
00671 
00672             RtlpSetControlBits( ISecurityDescriptor, SE_SELF_RELATIVE );
00673 
00674             
00675             
00676             
00677 
00678             
return STATUS_SUCCESS;
00679 
00680         }
00681 
00682         
00683         
00684         
00685         
00686 
00687         RtlCopyMemory( (&IObjectSecurity),
00688                       *ObjectsSecurityDescriptor,
00689                       
sizeof(SECURITY_DESCRIPTOR_RELATIVE) );
00690 
00691         IObjectSecurity.Owner = RtlpOwnerAddrSecurityDescriptor(
00692                     (SECURITY_DESCRIPTOR *) *ObjectsSecurityDescriptor );
00693         IObjectSecurity.Group = RtlpGroupAddrSecurityDescriptor(
00694                     (SECURITY_DESCRIPTOR *) *ObjectsSecurityDescriptor );
00695         IObjectSecurity.Dacl = RtlpDaclAddrSecurityDescriptor(
00696                     (SECURITY_DESCRIPTOR *) *ObjectsSecurityDescriptor );
00697         IObjectSecurity.Sacl = RtlpSaclAddrSecurityDescriptor(
00698                     (SECURITY_DESCRIPTOR *) *ObjectsSecurityDescriptor );
00699 
00700         IObjectSecurity.Control &= ~SE_SELF_RELATIVE;
00701 
00702         
00703         
00704         
00705         
00706         
00707 
00708         
Size = 
sizeof(SECURITY_DESCRIPTOR_RELATIVE);
00709 
00710         
if ( (((*SecurityInformation) & OWNER_SECURITY_INFORMATION)) &&
00711              (IObjectSecurity.Owner != 
NULL) ) {
00712 
00713             OwnerLength = 
SeLengthSid( IObjectSecurity.Owner );
00714             
Size += (ULONG)LongAlignSize(OwnerLength);
00715 
00716         }
00717 
00718         
if ( (((*SecurityInformation) & GROUP_SECURITY_INFORMATION)) &&
00719              (IObjectSecurity.Group != 
NULL) ) {
00720 
00721             GroupLength = 
SeLengthSid( IObjectSecurity.Group );
00722             
Size += (ULONG)LongAlignSize(GroupLength);
00723 
00724         }
00725 
00726         
if ( (((*SecurityInformation) & DACL_SECURITY_INFORMATION)) &&
00727              (IObjectSecurity.Control & SE_DACL_PRESENT) &&
00728              (IObjectSecurity.Dacl != 
NULL) ) {
00729 
00730 
00731             DaclLength = (ULONG)LongAlignSize((IObjectSecurity.Dacl)->AclSize);
00732             
Size += DaclLength;
00733 
00734         }
00735 
00736         
if ( (((*SecurityInformation) & SACL_SECURITY_INFORMATION)) &&
00737              (IObjectSecurity.Control & SE_SACL_PRESENT) &&
00738              (IObjectSecurity.Sacl != 
NULL) ) {
00739 
00740             SaclLength = (ULONG)LongAlignSize((IObjectSecurity.Sacl)->AclSize);
00741             
Size += SaclLength;
00742 
00743         }
00744 
00745         
00746         
00747         
00748         
00749 
00750         *Length = 
Size;
00751 
00752         
00753         
00754         
00755         
00756 
00757         
if (
Size > BufferLength) {
00758 
00759             
return STATUS_BUFFER_TOO_SMALL;
00760 
00761         }
00762 
00763         
00764         
00765         
00766         
00767         
00768         
00769         
00770         
00771         
00772         
00773         
00774         
00775         
00776         
00777 
00778         
RtlCreateSecurityDescriptorRelative( SecurityDescriptor,
00779                                              SECURITY_DESCRIPTOR_REVISION );
00780 
00781         
00782         
00783         
00784         
00785 
00786         RtlpSetControlBits( ISecurityDescriptor, SE_SELF_RELATIVE );
00787 
00788         
00789         
00790         
00791         
00792 
00793         NextFree = 
LongAlignPtr((PUCHAR)SecurityDescriptor +
00794                                         
sizeof(SECURITY_DESCRIPTOR_RELATIVE));
00795 
00796         
00797         
00798         
00799         
00800 
00801         
if ( ((*SecurityInformation) & OWNER_SECURITY_INFORMATION) &&
00802              ((IObjectSecurity.Owner) != 
NULL) ) {
00803 
00804                 RtlMoveMemory( NextFree,
00805                                IObjectSecurity.Owner,
00806                                OwnerLength );
00807 
00808                 ISecurityDescriptor->Owner = (ULONG)((PUCHAR)NextFree - (PUCHAR)SecurityDescriptor);
00809 
00810                 RtlpPropagateControlBits(
00811                     ISecurityDescriptor,
00812                     &IObjectSecurity,
00813                     SE_OWNER_DEFAULTED
00814                     );
00815 
00816                 NextFree += (ULONG)LongAlignSize(OwnerLength);
00817 
00818         }
00819 
00820 
00821         
00822         
00823         
00824         
00825 
00826         
if ( ((*SecurityInformation) & GROUP_SECURITY_INFORMATION) &&
00827              (IObjectSecurity.Group != 
NULL) ) {
00828 
00829                 RtlMoveMemory( NextFree,
00830                                IObjectSecurity.Group,
00831                                GroupLength );
00832 
00833                 ISecurityDescriptor->Group = (ULONG)((PUCHAR)NextFree - (PUCHAR)SecurityDescriptor);
00834 
00835                 RtlpPropagateControlBits(
00836                     ISecurityDescriptor,
00837                     &IObjectSecurity,
00838                     SE_GROUP_DEFAULTED
00839                     );
00840 
00841                 NextFree += (ULONG)LongAlignSize(GroupLength);
00842 
00843         }
00844 
00845 
00846         
00847         
00848         
00849         
00850         
00851 
00852         
if ( (*SecurityInformation) & DACL_SECURITY_INFORMATION) {
00853 
00854             RtlpPropagateControlBits(
00855                 ISecurityDescriptor,
00856                 &IObjectSecurity,
00857                 SE_DACL_PRESENT | SE_DACL_DEFAULTED | SE_DACL_PROTECTED | SE_DACL_AUTO_INHERITED
00858                 );
00859 
00860             
00861             
00862             
00863             
00864 
00865             
if ( (IObjectSecurity.Control & SE_DACL_PRESENT) != 0 &&
00866                  IObjectSecurity.Dacl != 
NULL) {
00867 
00868                 RtlMoveMemory( NextFree,
00869                                IObjectSecurity.Dacl,
00870                                (IObjectSecurity.Dacl)->AclSize );
00871 
00872                 ISecurityDescriptor->Dacl = (ULONG)((PUCHAR)NextFree - (PUCHAR)SecurityDescriptor);
00873 
00874                 NextFree += DaclLength;
00875 
00876             }
00877         }
00878 
00879 
00880         
00881         
00882         
00883         
00884         
00885 
00886         
if ( (*SecurityInformation) & SACL_SECURITY_INFORMATION) {
00887 
00888             RtlpPropagateControlBits(
00889                 ISecurityDescriptor,
00890                 &IObjectSecurity,
00891                 SE_SACL_PRESENT | SE_SACL_DEFAULTED | SE_SACL_PROTECTED | SE_SACL_AUTO_INHERITED
00892                 );
00893 
00894             
00895             
00896             
00897             
00898             
if ( (IObjectSecurity.Control & SE_SACL_PRESENT) != 0 &&
00899                  IObjectSecurity.Sacl != 
NULL) {
00900 
00901                 RtlMoveMemory( NextFree,
00902                                IObjectSecurity.Sacl,
00903                                (IObjectSecurity.Sacl)->AclSize );
00904 
00905                 ISecurityDescriptor->Sacl = (ULONG)((PUCHAR)NextFree - (PUCHAR)SecurityDescriptor);
00906 
00907             }
00908         }
00909 
00910     } except(EXCEPTION_EXECUTE_HANDLER) {
00911         
return(GetExceptionCode());
00912     }
00913 
00914     
return STATUS_SUCCESS;
00915 
00916 }