Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

rtdmpsec.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 rtdmpsec.c 00008 00009 Abstract: 00010 00011 NT level registry security test program #1, basic non-error paths. 00012 00013 Dump out the security descriptors of a sub-tree of the registry. 00014 00015 rtdmpsec <KeyPath> 00016 00017 Will ennumerate and dump out the subkeys and values of KeyPath, 00018 and then apply itself recursively to each subkey it finds. 00019 00020 It assumes data values are null terminated strings. 00021 00022 Example: 00023 00024 rtdmpsec \REGISTRY\MACHINE\TEST\bigkey 00025 00026 Author: 00027 00028 John Vert (jvert) 24-Jan-92 00029 00030 based on rtdmp.c by 00031 00032 Bryan Willman (bryanwi) 10-Dec-91 00033 00034 and getdacl.c by RobertRe 00035 00036 Revision History: 00037 00038 Richard Ward (richardw) 14 April 1992 Changed ACE_HEADER 00039 00040 --*/ 00041 00042 #include "cmp.h" 00043 #include <stdio.h> 00044 #include <stdlib.h> 00045 #include <string.h> 00046 00047 #define WORK_SIZE 1024 00048 00049 // 00050 // Get a pointer to the first ace in an acl 00051 // 00052 00053 #define FirstAce(Acl) ((PVOID)((PUCHAR)(Acl) + sizeof(ACL))) 00054 00055 // 00056 // Get a pointer to the following ace 00057 // 00058 00059 #define NextAce(Ace) ((PVOID)((PUCHAR)(Ace) + ((PACE_HEADER)(Ace))->AceSize)) 00060 00061 // 00062 // Generic ACE structure, to be used for casting ACE's of known types 00063 // 00064 00065 typedef struct _KNOWN_ACE { 00066 ACE_HEADER Header; 00067 ACCESS_MASK Mask; 00068 ULONG SidStart; 00069 } KNOWN_ACE, *PKNOWN_ACE; 00070 00071 00072 00073 VOID 00074 InitVars(); 00075 00076 VOID 00077 PrintAcl ( 00078 IN PACL Acl 00079 ); 00080 00081 VOID 00082 PrintAccessMask( 00083 IN ACCESS_MASK AccessMask 00084 ); 00085 00086 void __cdecl main(int, char *); 00087 void processargs(); 00088 00089 void print(PUNICODE_STRING); 00090 00091 void 00092 DumpSecurity( 00093 HANDLE Handle 00094 ); 00095 00096 void 00097 Dump( 00098 HANDLE Handle 00099 ); 00100 00101 UNICODE_STRING WorkName; 00102 WCHAR workbuffer[WORK_SIZE]; 00103 00104 // 00105 // Universal well known SIDs 00106 // 00107 00108 PSID NullSid; 00109 PSID WorldSid; 00110 PSID LocalSid; 00111 PSID CreatorOwnerSid; 00112 00113 // 00114 // Sids defined by NT 00115 // 00116 00117 PSID NtAuthoritySid; 00118 00119 PSID DialupSid; 00120 PSID NetworkSid; 00121 PSID BatchSid; 00122 PSID InteractiveSid; 00123 PSID LocalSystemSid; 00124 00125 void 00126 __cdecl main( 00127 int argc, 00128 char *argv[] 00129 ) 00130 { 00131 NTSTATUS status; 00132 OBJECT_ATTRIBUTES ObjectAttributes; 00133 HANDLE BaseHandle; 00134 00135 InitVars(); 00136 00137 // 00138 // Process args 00139 // 00140 00141 WorkName.MaximumLength = WORK_SIZE; 00142 WorkName.Length = 0L; 00143 WorkName.Buffer = &(workbuffer[0]); 00144 00145 processargs(argc, argv); 00146 00147 00148 // 00149 // Set up and open KeyPath 00150 // 00151 00152 printf("rtdmpsec: starting\n"); 00153 00154 InitializeObjectAttributes( 00155 &ObjectAttributes, 00156 &WorkName, 00157 0, 00158 (HANDLE)NULL, 00159 NULL 00160 ); 00161 ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; 00162 00163 status = NtOpenKey( 00164 &BaseHandle, 00165 MAXIMUM_ALLOWED, 00166 &ObjectAttributes 00167 ); 00168 if (!NT_SUCCESS(status)) { 00169 printf("rtdmpsec: t0: %08lx\n", status); 00170 exit(1); 00171 } 00172 00173 Dump(BaseHandle); 00174 } 00175 00176 00177 void 00178 Dump( 00179 HANDLE Handle 00180 ) 00181 { 00182 NTSTATUS status; 00183 PKEY_BASIC_INFORMATION KeyInformation; 00184 OBJECT_ATTRIBUTES ObjectAttributes; 00185 ULONG NamePos; 00186 ULONG index; 00187 STRING enumname; 00188 HANDLE WorkHandle; 00189 ULONG ResultLength; 00190 static char buffer[WORK_SIZE]; 00191 PUCHAR p; 00192 00193 KeyInformation = (PKEY_BASIC_INFORMATION)buffer; 00194 NamePos = WorkName.Length; 00195 00196 // 00197 // Print name of node we are about to dump out 00198 // 00199 printf("\n"); 00200 print(&WorkName); 00201 printf("::\n"); 00202 00203 // 00204 // Print out node's values 00205 // 00206 DumpSecurity(Handle); 00207 00208 // 00209 // Enumerate node's children and apply ourselves to each one 00210 // 00211 00212 for (index = 0; TRUE; index++) { 00213 00214 RtlZeroMemory(KeyInformation, WORK_SIZE); 00215 status = NtEnumerateKey( 00216 Handle, 00217 index, 00218 KeyBasicInformation, 00219 KeyInformation, 00220 WORK_SIZE, 00221 &ResultLength 00222 ); 00223 00224 if (status == STATUS_NO_MORE_ENTRIES) { 00225 00226 WorkName.Length = NamePos; 00227 return; 00228 00229 } else if (!NT_SUCCESS(status)) { 00230 00231 printf("rtdmpsec: dump1: status = %08lx\n", status); 00232 exit(1); 00233 00234 } 00235 00236 enumname.Buffer = &(KeyInformation->Name[0]); 00237 enumname.Length = KeyInformation->NameLength; 00238 enumname.MaximumLength = KeyInformation->NameLength; 00239 00240 p = WorkName.Buffer; 00241 p += WorkName.Length; 00242 *p = '\\'; 00243 p++; 00244 *p = '\0'; 00245 WorkName.Length += 2; 00246 00247 RtlAppendStringToString((PSTRING)&WorkName, (PSTRING)&enumname); 00248 00249 InitializeObjectAttributes( 00250 &ObjectAttributes, 00251 &enumname, 00252 0, 00253 Handle, 00254 NULL 00255 ); 00256 ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; 00257 00258 status = NtOpenKey( 00259 &WorkHandle, 00260 MAXIMUM_ALLOWED, 00261 &ObjectAttributes 00262 ); 00263 if (!NT_SUCCESS(status)) { 00264 if (status == STATUS_ACCESS_DENIED) { 00265 printf("\n"); 00266 print(&WorkName); 00267 printf("::\n\tAccess denied!\n"); 00268 } else { 00269 printf("rtdmpsec: dump2: %08lx\n", status); 00270 exit(1); 00271 } 00272 } else { 00273 Dump(WorkHandle); 00274 NtClose(WorkHandle); 00275 } 00276 00277 WorkName.Length = NamePos; 00278 } 00279 } 00280 00281 00282 void 00283 DumpSecurity( 00284 HANDLE Handle 00285 ) 00286 { 00287 PSECURITY_DESCRIPTOR SecurityDescriptor; 00288 NTSTATUS Status; 00289 ULONG Length; 00290 PACL Dacl; 00291 BOOLEAN DaclPresent; 00292 BOOLEAN DaclDefaulted; 00293 00294 Status = NtQuerySecurityObject( Handle, 00295 DACL_SECURITY_INFORMATION, 00296 NULL, 00297 0, 00298 &Length ); 00299 00300 if (Status != STATUS_BUFFER_TOO_SMALL) { 00301 printf("DumpSecurity t0: NtQuerySecurityObject failed %lx\n",Status); 00302 exit(1); 00303 } 00304 00305 SecurityDescriptor = malloc(Length); 00306 if (SecurityDescriptor == NULL) { 00307 printf("DumpSecurity: couldn't malloc buffer\n"); 00308 exit(1); 00309 } 00310 00311 Status = NtQuerySecurityObject( Handle, 00312 DACL_SECURITY_INFORMATION, 00313 SecurityDescriptor, 00314 Length, 00315 &Length ); 00316 00317 if (!NT_SUCCESS(Status)) { 00318 printf("DumpSecurity t1: NtQuerySecurityObject failed %lx\n",Status); 00319 exit(1); 00320 } 00321 00322 Dacl = NULL; 00323 00324 Status = RtlGetDaclSecurityDescriptor( SecurityDescriptor, 00325 &DaclPresent, 00326 &Dacl, 00327 &DaclDefaulted ); 00328 if (!NT_SUCCESS(Status)) { 00329 printf("DumpSecurity t2: RtlGetDaclSecurityDescriptor failed %lx\n",Status); 00330 } 00331 00332 if (DaclPresent) { 00333 PrintAcl(Dacl); 00334 } else { 00335 printf("\tAcl not present\n"); 00336 } 00337 00338 } 00339 00340 00341 void 00342 print( 00343 PUNICODE_STRING String 00344 ) 00345 { 00346 static ANSI_STRING temp; 00347 static char tempbuffer[WORK_SIZE]; 00348 00349 temp.MaximumLength = WORK_SIZE; 00350 temp.Length = 0L; 00351 temp.Buffer = tempbuffer; 00352 00353 RtlUnicodeStringToAnsiString(&temp, String, FALSE); 00354 printf("%s", temp.Buffer); 00355 return; 00356 } 00357 00358 00359 void 00360 processargs( 00361 int argc, 00362 char *argv[] 00363 ) 00364 { 00365 ANSI_STRING temp; 00366 00367 if ( (argc != 2) ) 00368 { 00369 printf("Usage: %s <KeyPath>\n", 00370 argv[0]); 00371 exit(1); 00372 } 00373 00374 RtlInitAnsiString( 00375 &temp, 00376 argv[1] 00377 ); 00378 00379 RtlAnsiStringToUnicodeString( 00380 &WorkName, 00381 &temp, 00382 FALSE 00383 ); 00384 00385 return; 00386 } 00387 00388 00389 BOOLEAN 00390 SidTranslation( 00391 PSID Sid, 00392 PSTRING AccountName 00393 ) 00394 // AccountName is expected to have a large maximum length 00395 00396 { 00397 if (RtlEqualSid(Sid, WorldSid)) { 00398 RtlInitString( AccountName, "WORLD"); 00399 return(TRUE); 00400 } 00401 00402 if (RtlEqualSid(Sid, LocalSid)) { 00403 RtlInitString( AccountName, "LOCAL"); 00404 00405 return(TRUE); 00406 } 00407 00408 if (RtlEqualSid(Sid, NetworkSid)) { 00409 RtlInitString( AccountName, "NETWORK"); 00410 00411 return(TRUE); 00412 } 00413 00414 if (RtlEqualSid(Sid, BatchSid)) { 00415 RtlInitString( AccountName, "BATCH"); 00416 00417 return(TRUE); 00418 } 00419 00420 if (RtlEqualSid(Sid, InteractiveSid)) { 00421 RtlInitString( AccountName, "INTERACTIVE"); 00422 return(TRUE); 00423 } 00424 00425 if (RtlEqualSid(Sid, LocalSystemSid)) { 00426 RtlInitString( AccountName, "SYSTEM"); 00427 return(TRUE); 00428 } 00429 00430 // 00431 // if (RtlEqualSid(Sid, LocalManagerSid)) { 00432 // RtlInitString( AccountName, "LOCAL MANAGER"); 00433 // return(TRUE); 00434 // } 00435 00436 // if (RtlEqualSid(Sid, LocalAdminSid)) { 00437 // RtlInitString( AccountName, "LOCAL ADMIN"); 00438 // return(TRUE); 00439 // } 00440 00441 return(FALSE); 00442 00443 } 00444 00445 00446 VOID 00447 DisplayAccountSid( 00448 PSID Sid 00449 ) 00450 { 00451 UCHAR Buffer[128]; 00452 STRING AccountName; 00453 UCHAR i; 00454 ULONG Tmp; 00455 PSID_IDENTIFIER_AUTHORITY IdentifierAuthority; 00456 UCHAR SubAuthorityCount; 00457 00458 Buffer[0] = 0; 00459 00460 AccountName.MaximumLength = 127; 00461 AccountName.Length = 0; 00462 AccountName.Buffer = (PVOID)&Buffer[0]; 00463 00464 00465 00466 if (SidTranslation( (PSID)Sid, &AccountName) ) { 00467 00468 printf("%s\n", AccountName.Buffer ); 00469 00470 } else { 00471 IdentifierAuthority = RtlIdentifierAuthoritySid(Sid); 00472 00473 // 00474 // HACK! HACK! 00475 // The next line prints the revision of the SID. Since there is no 00476 // rtl routine which gives us the SID revision, we must make due. 00477 // luckily, the revision field is the first field in the SID, so we 00478 // can just cast the pointer. 00479 // 00480 00481 printf("S-%u-", (USHORT) *((PUCHAR) Sid) ); 00482 00483 if ( (IdentifierAuthority->Value[0] != 0) || 00484 (IdentifierAuthority->Value[1] != 0) ){ 00485 printf("0x%02hx%02hx%02hx%02hx%02hx%02hx", 00486 IdentifierAuthority->Value[0], 00487 IdentifierAuthority->Value[1], 00488 IdentifierAuthority->Value[2], 00489 IdentifierAuthority->Value[3], 00490 IdentifierAuthority->Value[4], 00491 IdentifierAuthority->Value[5] ); 00492 } else { 00493 Tmp = IdentifierAuthority->Value[5] + 00494 (IdentifierAuthority->Value[4] << 8) + 00495 (IdentifierAuthority->Value[3] << 16) + 00496 (IdentifierAuthority->Value[2] << 24); 00497 printf("%lu", Tmp); 00498 } 00499 00500 SubAuthorityCount = *RtlSubAuthorityCountSid(Sid); 00501 for (i=0;i<SubAuthorityCount ;i++ ) { 00502 printf("-%lu", (*RtlSubAuthoritySid(Sid, i))); 00503 } 00504 printf("\n"); 00505 00506 } 00507 00508 } 00509 00510 VOID 00511 InitVars() 00512 { 00513 ULONG SidWithZeroSubAuthorities; 00514 ULONG SidWithOneSubAuthority; 00515 ULONG SidWithThreeSubAuthorities; 00516 ULONG SidWithFourSubAuthorities; 00517 00518 SID_IDENTIFIER_AUTHORITY NullSidAuthority = SECURITY_NULL_SID_AUTHORITY; 00519 SID_IDENTIFIER_AUTHORITY WorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY; 00520 SID_IDENTIFIER_AUTHORITY LocalSidAuthority = SECURITY_LOCAL_SID_AUTHORITY; 00521 SID_IDENTIFIER_AUTHORITY CreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY; 00522 00523 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; 00524 00525 00526 // 00527 // The following SID sizes need to be allocated 00528 // 00529 00530 SidWithZeroSubAuthorities = RtlLengthRequiredSid( 0 ); 00531 SidWithOneSubAuthority = RtlLengthRequiredSid( 1 ); 00532 SidWithThreeSubAuthorities = RtlLengthRequiredSid( 3 ); 00533 SidWithFourSubAuthorities = RtlLengthRequiredSid( 4 ); 00534 00535 // 00536 // Allocate and initialize the universal SIDs 00537 // 00538 00539 NullSid = (PSID)malloc(SidWithOneSubAuthority); 00540 WorldSid = (PSID)malloc(SidWithOneSubAuthority); 00541 LocalSid = (PSID)malloc(SidWithOneSubAuthority); 00542 CreatorOwnerSid = (PSID)malloc(SidWithOneSubAuthority); 00543 00544 RtlInitializeSid( NullSid, &NullSidAuthority, 1 ); 00545 RtlInitializeSid( WorldSid, &WorldSidAuthority, 1 ); 00546 RtlInitializeSid( LocalSid, &LocalSidAuthority, 1 ); 00547 RtlInitializeSid( CreatorOwnerSid, &CreatorSidAuthority, 1 ); 00548 00549 *(RtlSubAuthoritySid( NullSid, 0 )) = SECURITY_NULL_RID; 00550 *(RtlSubAuthoritySid( WorldSid, 0 )) = SECURITY_WORLD_RID; 00551 *(RtlSubAuthoritySid( LocalSid, 0 )) = SECURITY_LOCAL_RID; 00552 *(RtlSubAuthoritySid( CreatorOwnerSid, 0 )) = SECURITY_CREATOR_OWNER_RID; 00553 00554 // 00555 // Allocate and initialize the NT defined SIDs 00556 // 00557 00558 NtAuthoritySid = (PSID)malloc(SidWithZeroSubAuthorities); 00559 DialupSid = (PSID)malloc(SidWithOneSubAuthority); 00560 NetworkSid = (PSID)malloc(SidWithOneSubAuthority); 00561 BatchSid = (PSID)malloc(SidWithOneSubAuthority); 00562 InteractiveSid = (PSID)malloc(SidWithOneSubAuthority); 00563 LocalSystemSid = (PSID)malloc(SidWithOneSubAuthority); 00564 00565 RtlInitializeSid( NtAuthoritySid, &NtAuthority, 0 ); 00566 RtlInitializeSid( DialupSid, &NtAuthority, 1 ); 00567 RtlInitializeSid( NetworkSid, &NtAuthority, 1 ); 00568 RtlInitializeSid( BatchSid, &NtAuthority, 1 ); 00569 RtlInitializeSid( InteractiveSid, &NtAuthority, 1 ); 00570 RtlInitializeSid( LocalSystemSid, &NtAuthority, 1 ); 00571 00572 *(RtlSubAuthoritySid( DialupSid, 0 )) = SECURITY_DIALUP_RID; 00573 *(RtlSubAuthoritySid( NetworkSid, 0 )) = SECURITY_NETWORK_RID; 00574 *(RtlSubAuthoritySid( BatchSid, 0 )) = SECURITY_BATCH_RID; 00575 *(RtlSubAuthoritySid( InteractiveSid, 0 )) = SECURITY_INTERACTIVE_RID; 00576 *(RtlSubAuthoritySid( LocalSystemSid, 0 )) = SECURITY_LOCAL_SYSTEM_RID; 00577 00578 return; 00579 00580 } 00581 00582 00583 00584 VOID 00585 PrintAcl ( 00586 IN PACL Acl 00587 ) 00588 00589 /*++ 00590 00591 Routine Description: 00592 00593 This routine dumps an Acl for debug purposes (via printf). It is 00594 specialized to dump standard aces. 00595 00596 Arguments: 00597 00598 Acl - Supplies the Acl to dump 00599 00600 Return Value: 00601 00602 None 00603 00604 --*/ 00605 00606 00607 { 00608 ULONG i; 00609 PKNOWN_ACE Ace; 00610 BOOLEAN KnownType; 00611 PCHAR AceTypes[] = { "Access Allowed", 00612 "Access Denied ", 00613 "System Audit ", 00614 "System Alarm " 00615 }; 00616 00617 if (Acl == NULL) { 00618 00619 printf("\tAcl == ALL ACCESS GRANTED!\n"); 00620 return; 00621 00622 } 00623 00624 // 00625 // Dump the Acl header 00626 // 00627 00628 printf("\tRevision: %02x", Acl->AclRevision); 00629 printf(" Size: %04x", Acl->AclSize); 00630 printf(" AceCount: %04x\n", Acl->AceCount); 00631 00632 // 00633 // Now for each Ace we want do dump it 00634 // 00635 00636 for (i = 0, Ace = FirstAce(Acl); 00637 i < Acl->AceCount; 00638 i++, Ace = NextAce(Ace) ) { 00639 00640 // 00641 // print out the ace header 00642 // 00643 00644 printf("\n\tAceHeader: %08lx ", *(PULONG)Ace); 00645 00646 // 00647 // special case on the standard ace types 00648 // 00649 00650 if ((Ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) || 00651 (Ace->Header.AceType == ACCESS_DENIED_ACE_TYPE) || 00652 (Ace->Header.AceType == SYSTEM_AUDIT_ACE_TYPE) || 00653 (Ace->Header.AceType == SYSTEM_ALARM_ACE_TYPE)) { 00654 00655 // 00656 // The following array is indexed by ace types and must 00657 // follow the allowed, denied, audit, alarm seqeuence 00658 // 00659 00660 PCHAR AceTypes[] = { "Access Allowed", 00661 "Access Denied ", 00662 "System Audit ", 00663 "System Alarm " 00664 }; 00665 00666 printf(AceTypes[Ace->Header.AceType]); 00667 PrintAccessMask(Ace->Mask); 00668 KnownType = TRUE; 00669 00670 } else { 00671 00672 KnownType = FALSE; 00673 printf(" Unknown Ace Type\n"); 00674 00675 } 00676 00677 printf("\n"); 00678 00679 printf("\tAceSize = %d\n",Ace->Header.AceSize); 00680 00681 printf("\tAce Flags = "); 00682 if (Ace->Header.AceFlags & OBJECT_INHERIT_ACE) { 00683 printf("OBJECT_INHERIT_ACE\n"); 00684 printf(" "); 00685 } 00686 00687 if (Ace->Header.AceFlags & CONTAINER_INHERIT_ACE) { 00688 printf("CONTAINER_INHERIT_ACE\n"); 00689 printf(" "); 00690 } 00691 00692 if (Ace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE) { 00693 printf("NO_PROPAGATE_INHERIT_ACE\n"); 00694 printf(" "); 00695 } 00696 00697 if (Ace->Header.AceFlags & INHERIT_ONLY_ACE) { 00698 printf("INHERIT_ONLY_ACE\n"); 00699 printf(" "); 00700 } 00701 00702 if (Ace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) { 00703 printf("SUCCESSFUL_ACCESS_ACE_FLAG\n"); 00704 printf(" "); 00705 } 00706 00707 if (Ace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG) { 00708 printf("FAILED_ACCESS_ACE_FLAG\n"); 00709 printf(" "); 00710 } 00711 00712 printf("\n"); 00713 00714 printf("\tSid = "); 00715 DisplayAccountSid(&Ace->SidStart); 00716 } 00717 00718 } 00719 00720 00721 VOID 00722 PrintAccessMask( 00723 IN ACCESS_MASK AccessMask 00724 ) 00725 { 00726 printf("\n\tAccess Mask: "); 00727 00728 if (AccessMask == KEY_ALL_ACCESS) { 00729 printf("KEY_ALL_ACCESS\n\t "); 00730 return; 00731 } 00732 if (AccessMask == KEY_READ) { 00733 printf("KEY_READ\n\t "); 00734 return; 00735 } 00736 if (AccessMask == KEY_WRITE) { 00737 printf("KEY_WRITE\n\t "); 00738 return; 00739 } 00740 00741 if (AccessMask & KEY_QUERY_VALUE) { 00742 printf("KEY_QUERY_VALUE\n\t "); 00743 } 00744 if (AccessMask & KEY_SET_VALUE) { 00745 printf("KEY_SET_VALUE\n\t "); 00746 } 00747 if (AccessMask & KEY_CREATE_SUB_KEY) { 00748 printf("KEY_CREATE_SUB_KEY\n\t "); 00749 } 00750 if (AccessMask & KEY_ENUMERATE_SUB_KEYS) { 00751 printf("KEY_ENUMERATE_SUB_KEYS\n\t "); 00752 } 00753 if (AccessMask & KEY_NOTIFY) { 00754 printf("KEY_NOTIFY\n\t "); 00755 } 00756 if (AccessMask & KEY_CREATE_LINK) { 00757 printf("KEY_CREATE_LINK\n\t "); 00758 } 00759 if (AccessMask & GENERIC_ALL) { 00760 printf("GENERIC_ALL\n\t "); 00761 } 00762 if (AccessMask & GENERIC_EXECUTE) { 00763 printf("GENERIC_EXECUTE\n\t "); 00764 } 00765 if (AccessMask & GENERIC_WRITE) { 00766 printf("GENERIC_WRITE\n\t "); 00767 } 00768 if (AccessMask & GENERIC_READ) { 00769 printf("GENERIC_READ\n\t "); 00770 } 00771 if (AccessMask & GENERIC_READ) { 00772 printf("GENERIC_READ\n\t "); 00773 } 00774 if (AccessMask & MAXIMUM_ALLOWED) { 00775 printf("MAXIMUM_ALLOWED\n\t "); 00776 } 00777 if (AccessMask & ACCESS_SYSTEM_SECURITY) { 00778 printf("ACCESS_SYSTEM_SECURITY\n\t "); 00779 } 00780 if (AccessMask & WRITE_OWNER) { 00781 printf("WRITE_OWNER\n\t "); 00782 } 00783 if (AccessMask & WRITE_DAC) { 00784 printf("WRITE_DAC\n\t "); 00785 } 00786 if (AccessMask & READ_CONTROL) { 00787 printf("READ_CONTROL\n\t "); 00788 } 00789 if (AccessMask & DELETE) { 00790 printf("DELETE\n\t "); 00791 } 00792 }

Generated on Sat May 15 19:41:40 2004 for test by doxygen 1.3.7