1 #pragma once 2 3 typedef struct _KNOWN_ACE 4 { 5 ACE_HEADER Header; 6 ACCESS_MASK Mask; 7 ULONG SidStart; 8 } KNOWN_ACE, *PKNOWN_ACE; 9 10 typedef struct _KNOWN_OBJECT_ACE 11 { 12 ACE_HEADER Header; 13 ACCESS_MASK Mask; 14 ULONG Flags; 15 ULONG SidStart; 16 } KNOWN_OBJECT_ACE, *PKNOWN_OBJECT_ACE; 17 18 typedef struct _KNOWN_COMPOUND_ACE 19 { 20 ACE_HEADER Header; 21 ACCESS_MASK Mask; 22 USHORT CompoundAceType; 23 USHORT Reserved; 24 ULONG SidStart; 25 } KNOWN_COMPOUND_ACE, *PKNOWN_COMPOUND_ACE; 26 27 typedef struct _TOKEN_AUDIT_POLICY_INFORMATION 28 { 29 ULONG PolicyCount; 30 struct 31 { 32 ULONG Category; 33 UCHAR Value; 34 } Policies[1]; 35 } TOKEN_AUDIT_POLICY_INFORMATION, *PTOKEN_AUDIT_POLICY_INFORMATION; 36 37 FORCEINLINE 38 PSID 39 SepGetGroupFromDescriptor(PVOID _Descriptor) 40 { 41 PISECURITY_DESCRIPTOR Descriptor = (PISECURITY_DESCRIPTOR)_Descriptor; 42 PISECURITY_DESCRIPTOR_RELATIVE SdRel; 43 44 if (Descriptor->Control & SE_SELF_RELATIVE) 45 { 46 SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)Descriptor; 47 if (!SdRel->Group) return NULL; 48 return (PSID)((ULONG_PTR)Descriptor + SdRel->Group); 49 } 50 else 51 { 52 return Descriptor->Group; 53 } 54 } 55 56 FORCEINLINE 57 PSID 58 SepGetOwnerFromDescriptor(PVOID _Descriptor) 59 { 60 PISECURITY_DESCRIPTOR Descriptor = (PISECURITY_DESCRIPTOR)_Descriptor; 61 PISECURITY_DESCRIPTOR_RELATIVE SdRel; 62 63 if (Descriptor->Control & SE_SELF_RELATIVE) 64 { 65 SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)Descriptor; 66 if (!SdRel->Owner) return NULL; 67 return (PSID)((ULONG_PTR)Descriptor + SdRel->Owner); 68 } 69 else 70 { 71 return Descriptor->Owner; 72 } 73 } 74 75 FORCEINLINE 76 PACL 77 SepGetDaclFromDescriptor(PVOID _Descriptor) 78 { 79 PISECURITY_DESCRIPTOR Descriptor = (PISECURITY_DESCRIPTOR)_Descriptor; 80 PISECURITY_DESCRIPTOR_RELATIVE SdRel; 81 82 if (!(Descriptor->Control & SE_DACL_PRESENT)) return NULL; 83 84 if (Descriptor->Control & SE_SELF_RELATIVE) 85 { 86 SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)Descriptor; 87 if (!SdRel->Dacl) return NULL; 88 return (PACL)((ULONG_PTR)Descriptor + SdRel->Dacl); 89 } 90 else 91 { 92 return Descriptor->Dacl; 93 } 94 } 95 96 FORCEINLINE 97 PACL 98 SepGetSaclFromDescriptor(PVOID _Descriptor) 99 { 100 PISECURITY_DESCRIPTOR Descriptor = (PISECURITY_DESCRIPTOR)_Descriptor; 101 PISECURITY_DESCRIPTOR_RELATIVE SdRel; 102 103 if (!(Descriptor->Control & SE_SACL_PRESENT)) return NULL; 104 105 if (Descriptor->Control & SE_SELF_RELATIVE) 106 { 107 SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)Descriptor; 108 if (!SdRel->Sacl) return NULL; 109 return (PACL)((ULONG_PTR)Descriptor + SdRel->Sacl); 110 } 111 else 112 { 113 return Descriptor->Sacl; 114 } 115 } 116 117 #ifndef RTL_H 118 119 /* SID Authorities */ 120 extern SID_IDENTIFIER_AUTHORITY SeNullSidAuthority; 121 extern SID_IDENTIFIER_AUTHORITY SeWorldSidAuthority; 122 extern SID_IDENTIFIER_AUTHORITY SeLocalSidAuthority; 123 extern SID_IDENTIFIER_AUTHORITY SeCreatorSidAuthority; 124 extern SID_IDENTIFIER_AUTHORITY SeNtSidAuthority; 125 126 /* SIDs */ 127 extern PSID SeNullSid; 128 extern PSID SeWorldSid; 129 extern PSID SeLocalSid; 130 extern PSID SeCreatorOwnerSid; 131 extern PSID SeCreatorGroupSid; 132 extern PSID SeCreatorOwnerServerSid; 133 extern PSID SeCreatorGroupServerSid; 134 extern PSID SeNtAuthoritySid; 135 extern PSID SeDialupSid; 136 extern PSID SeNetworkSid; 137 extern PSID SeBatchSid; 138 extern PSID SeInteractiveSid; 139 extern PSID SeServiceSid; 140 extern PSID SeAnonymousLogonSid; 141 extern PSID SePrincipalSelfSid; 142 extern PSID SeLocalSystemSid; 143 extern PSID SeAuthenticatedUserSid; 144 extern PSID SeRestrictedCodeSid; 145 extern PSID SeAliasAdminsSid; 146 extern PSID SeAliasUsersSid; 147 extern PSID SeAliasGuestsSid; 148 extern PSID SeAliasPowerUsersSid; 149 extern PSID SeAliasAccountOpsSid; 150 extern PSID SeAliasSystemOpsSid; 151 extern PSID SeAliasPrintOpsSid; 152 extern PSID SeAliasBackupOpsSid; 153 extern PSID SeAuthenticatedUsersSid; 154 extern PSID SeRestrictedSid; 155 extern PSID SeAnonymousLogonSid; 156 extern PSID SeLocalServiceSid; 157 extern PSID SeNetworkServiceSid; 158 159 /* Privileges */ 160 extern const LUID SeCreateTokenPrivilege; 161 extern const LUID SeAssignPrimaryTokenPrivilege; 162 extern const LUID SeLockMemoryPrivilege; 163 extern const LUID SeIncreaseQuotaPrivilege; 164 extern const LUID SeUnsolicitedInputPrivilege; 165 extern const LUID SeTcbPrivilege; 166 extern const LUID SeSecurityPrivilege; 167 extern const LUID SeTakeOwnershipPrivilege; 168 extern const LUID SeLoadDriverPrivilege; 169 extern const LUID SeSystemProfilePrivilege; 170 extern const LUID SeSystemtimePrivilege; 171 extern const LUID SeProfileSingleProcessPrivilege; 172 extern const LUID SeIncreaseBasePriorityPrivilege; 173 extern const LUID SeCreatePagefilePrivilege; 174 extern const LUID SeCreatePermanentPrivilege; 175 extern const LUID SeBackupPrivilege; 176 extern const LUID SeRestorePrivilege; 177 extern const LUID SeShutdownPrivilege; 178 extern const LUID SeDebugPrivilege; 179 extern const LUID SeAuditPrivilege; 180 extern const LUID SeSystemEnvironmentPrivilege; 181 extern const LUID SeChangeNotifyPrivilege; 182 extern const LUID SeRemoteShutdownPrivilege; 183 extern const LUID SeUndockPrivilege; 184 extern const LUID SeSyncAgentPrivilege; 185 extern const LUID SeEnableDelegationPrivilege; 186 extern const LUID SeManageVolumePrivilege; 187 extern const LUID SeImpersonatePrivilege; 188 extern const LUID SeCreateGlobalPrivilege; 189 extern const LUID SeTrustedCredmanPrivilege; 190 extern const LUID SeRelabelPrivilege; 191 extern const LUID SeIncreaseWorkingSetPrivilege; 192 extern const LUID SeTimeZonePrivilege; 193 extern const LUID SeCreateSymbolicLinkPrivilege; 194 195 /* DACLs */ 196 extern PACL SePublicDefaultUnrestrictedDacl; 197 extern PACL SePublicOpenDacl; 198 extern PACL SePublicOpenUnrestrictedDacl; 199 extern PACL SeUnrestrictedDacl; 200 extern PACL SeSystemAnonymousLogonDacl; 201 202 /* SDs */ 203 extern PSECURITY_DESCRIPTOR SePublicDefaultSd; 204 extern PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd; 205 extern PSECURITY_DESCRIPTOR SePublicOpenSd; 206 extern PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd; 207 extern PSECURITY_DESCRIPTOR SeSystemDefaultSd; 208 extern PSECURITY_DESCRIPTOR SeUnrestrictedSd; 209 extern PSECURITY_DESCRIPTOR SeSystemAnonymousLogonSd; 210 211 /* Anonymous Logon Tokens */ 212 extern PTOKEN SeAnonymousLogonToken; 213 extern PTOKEN SeAnonymousLogonTokenNoEveryone; 214 215 216 #define SepAcquireTokenLockExclusive(Token) \ 217 { \ 218 KeEnterCriticalRegion(); \ 219 ExAcquireResourceExclusiveLite(((PTOKEN)Token)->TokenLock, TRUE); \ 220 } 221 #define SepAcquireTokenLockShared(Token) \ 222 { \ 223 KeEnterCriticalRegion(); \ 224 ExAcquireResourceSharedLite(((PTOKEN)Token)->TokenLock, TRUE); \ 225 } 226 227 #define SepReleaseTokenLock(Token) \ 228 { \ 229 ExReleaseResourceLite(((PTOKEN)Token)->TokenLock); \ 230 KeLeaveCriticalRegion(); \ 231 } 232 233 // 234 // Token Functions 235 // 236 BOOLEAN 237 NTAPI 238 SepTokenIsOwner( 239 IN PACCESS_TOKEN _Token, 240 IN PSECURITY_DESCRIPTOR SecurityDescriptor, 241 IN BOOLEAN TokenLocked 242 ); 243 244 BOOLEAN 245 NTAPI 246 SepSidInToken( 247 IN PACCESS_TOKEN _Token, 248 IN PSID Sid 249 ); 250 251 BOOLEAN 252 NTAPI 253 SepSidInTokenEx( 254 IN PACCESS_TOKEN _Token, 255 IN PSID PrincipalSelfSid, 256 IN PSID _Sid, 257 IN BOOLEAN Deny, 258 IN BOOLEAN Restricted 259 ); 260 261 BOOLEAN 262 NTAPI 263 SeTokenCanImpersonate( 264 _In_ PTOKEN ProcessToken, 265 _In_ PTOKEN TokenToImpersonate, 266 _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel); 267 268 /* Functions */ 269 CODE_SEG("INIT") 270 BOOLEAN 271 NTAPI 272 SeInitSystem(VOID); 273 274 CODE_SEG("INIT") 275 VOID 276 NTAPI 277 SepInitPrivileges(VOID); 278 279 CODE_SEG("INIT") 280 BOOLEAN 281 NTAPI 282 SepInitSecurityIDs(VOID); 283 284 CODE_SEG("INIT") 285 BOOLEAN 286 NTAPI 287 SepInitDACLs(VOID); 288 289 CODE_SEG("INIT") 290 BOOLEAN 291 NTAPI 292 SepInitSDs(VOID); 293 294 BOOLEAN 295 NTAPI 296 SeRmInitPhase0(VOID); 297 298 BOOLEAN 299 NTAPI 300 SeRmInitPhase1(VOID); 301 302 VOID 303 NTAPI 304 SeDeassignPrimaryToken(struct _EPROCESS *Process); 305 306 NTSTATUS 307 NTAPI 308 SeSubProcessToken( 309 IN PTOKEN Parent, 310 OUT PTOKEN *Token, 311 IN BOOLEAN InUse, 312 IN ULONG SessionId 313 ); 314 315 NTSTATUS 316 NTAPI 317 SeInitializeProcessAuditName( 318 IN PFILE_OBJECT FileObject, 319 IN BOOLEAN DoAudit, 320 OUT POBJECT_NAME_INFORMATION *AuditInfo 321 ); 322 323 NTSTATUS 324 NTAPI 325 SeCreateAccessStateEx( 326 IN PETHREAD Thread, 327 IN PEPROCESS Process, 328 IN OUT PACCESS_STATE AccessState, 329 IN PAUX_ACCESS_DATA AuxData, 330 IN ACCESS_MASK Access, 331 IN PGENERIC_MAPPING GenericMapping 332 ); 333 334 NTSTATUS 335 NTAPI 336 SeIsTokenChild( 337 IN PTOKEN Token, 338 OUT PBOOLEAN IsChild 339 ); 340 341 NTSTATUS 342 NTAPI 343 SeIsTokenSibling( 344 IN PTOKEN Token, 345 OUT PBOOLEAN IsSibling 346 ); 347 348 NTSTATUS 349 NTAPI 350 SepCreateImpersonationTokenDacl( 351 _In_ PTOKEN Token, 352 _In_ PTOKEN PrimaryToken, 353 _Out_ PACL* Dacl 354 ); 355 356 NTSTATUS 357 NTAPI 358 SepRmInsertLogonSessionIntoToken( 359 _Inout_ PTOKEN Token 360 ); 361 362 NTSTATUS 363 NTAPI 364 SepRmRemoveLogonSessionFromToken( 365 _Inout_ PTOKEN Token 366 ); 367 368 CODE_SEG("INIT") 369 VOID 370 NTAPI 371 SepInitializeTokenImplementation(VOID); 372 373 CODE_SEG("INIT") 374 PTOKEN 375 NTAPI 376 SepCreateSystemProcessToken(VOID); 377 378 CODE_SEG("INIT") 379 PTOKEN 380 SepCreateSystemAnonymousLogonToken(VOID); 381 382 CODE_SEG("INIT") 383 PTOKEN 384 SepCreateSystemAnonymousLogonTokenNoEveryone(VOID); 385 386 BOOLEAN 387 NTAPI 388 SeDetailedAuditingWithToken(IN PTOKEN Token); 389 390 VOID 391 NTAPI 392 SeAuditProcessExit(IN PEPROCESS Process); 393 394 VOID 395 NTAPI 396 SeAuditProcessCreate(IN PEPROCESS Process); 397 398 NTSTATUS 399 NTAPI 400 SeExchangePrimaryToken( 401 _In_ PEPROCESS Process, 402 _In_ PACCESS_TOKEN NewAccessToken, 403 _Out_ PACCESS_TOKEN* OldAccessToken 404 ); 405 406 VOID 407 NTAPI 408 SeCaptureSubjectContextEx( 409 IN PETHREAD Thread, 410 IN PEPROCESS Process, 411 OUT PSECURITY_SUBJECT_CONTEXT SubjectContext 412 ); 413 414 NTSTATUS 415 NTAPI 416 SeCaptureLuidAndAttributesArray( 417 PLUID_AND_ATTRIBUTES Src, 418 ULONG PrivilegeCount, 419 KPROCESSOR_MODE PreviousMode, 420 PLUID_AND_ATTRIBUTES AllocatedMem, 421 ULONG AllocatedLength, 422 POOL_TYPE PoolType, 423 BOOLEAN CaptureIfKernel, 424 PLUID_AND_ATTRIBUTES* Dest, 425 PULONG Length 426 ); 427 428 VOID 429 NTAPI 430 SeReleaseLuidAndAttributesArray( 431 PLUID_AND_ATTRIBUTES Privilege, 432 KPROCESSOR_MODE PreviousMode, 433 BOOLEAN CaptureIfKernel 434 ); 435 436 BOOLEAN 437 NTAPI 438 SepPrivilegeCheck( 439 PTOKEN Token, 440 PLUID_AND_ATTRIBUTES Privileges, 441 ULONG PrivilegeCount, 442 ULONG PrivilegeControl, 443 KPROCESSOR_MODE PreviousMode 444 ); 445 446 NTSTATUS 447 NTAPI 448 SePrivilegePolicyCheck( 449 _Inout_ PACCESS_MASK DesiredAccess, 450 _Inout_ PACCESS_MASK GrantedAccess, 451 _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, 452 _In_ PTOKEN Token, 453 _Out_opt_ PPRIVILEGE_SET *OutPrivilegeSet, 454 _In_ KPROCESSOR_MODE PreviousMode); 455 456 BOOLEAN 457 NTAPI 458 SeCheckPrivilegedObject( 459 IN LUID PrivilegeValue, 460 IN HANDLE ObjectHandle, 461 IN ACCESS_MASK DesiredAccess, 462 IN KPROCESSOR_MODE PreviousMode 463 ); 464 465 NTSTATUS 466 NTAPI 467 SepDuplicateToken( 468 _In_ PTOKEN Token, 469 _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 470 _In_ BOOLEAN EffectiveOnly, 471 _In_ TOKEN_TYPE TokenType, 472 _In_ SECURITY_IMPERSONATION_LEVEL Level, 473 _In_ KPROCESSOR_MODE PreviousMode, 474 _Out_ PTOKEN* NewAccessToken 475 ); 476 477 NTSTATUS 478 NTAPI 479 SepCaptureSecurityQualityOfService( 480 _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 481 _In_ KPROCESSOR_MODE AccessMode, 482 _In_ POOL_TYPE PoolType, 483 _In_ BOOLEAN CaptureIfKernel, 484 _Out_ PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService, 485 _Out_ PBOOLEAN Present 486 ); 487 488 VOID 489 NTAPI 490 SepReleaseSecurityQualityOfService( 491 _In_opt_ PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService, 492 _In_ KPROCESSOR_MODE AccessMode, 493 _In_ BOOLEAN CaptureIfKernel 494 ); 495 496 NTSTATUS 497 NTAPI 498 SepCaptureSid( 499 IN PSID InputSid, 500 IN KPROCESSOR_MODE AccessMode, 501 IN POOL_TYPE PoolType, 502 IN BOOLEAN CaptureIfKernel, 503 OUT PSID *CapturedSid 504 ); 505 506 VOID 507 NTAPI 508 SepReleaseSid( 509 IN PSID CapturedSid, 510 IN KPROCESSOR_MODE AccessMode, 511 IN BOOLEAN CaptureIfKernel 512 ); 513 514 NTSTATUS 515 NTAPI 516 SeCaptureSidAndAttributesArray( 517 _In_ PSID_AND_ATTRIBUTES SrcSidAndAttributes, 518 _In_ ULONG AttributeCount, 519 _In_ KPROCESSOR_MODE PreviousMode, 520 _In_opt_ PVOID AllocatedMem, 521 _In_ ULONG AllocatedLength, 522 _In_ POOL_TYPE PoolType, 523 _In_ BOOLEAN CaptureIfKernel, 524 _Out_ PSID_AND_ATTRIBUTES *CapturedSidAndAttributes, 525 _Out_ PULONG ResultLength); 526 527 VOID 528 NTAPI 529 SeReleaseSidAndAttributesArray( 530 _In_ _Post_invalid_ PSID_AND_ATTRIBUTES CapturedSidAndAttributes, 531 _In_ KPROCESSOR_MODE AccessMode, 532 _In_ BOOLEAN CaptureIfKernel); 533 534 NTSTATUS 535 NTAPI 536 SeComputeQuotaInformationSize( 537 _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, 538 _Out_ PULONG QuotaInfoSize); 539 540 NTSTATUS 541 NTAPI 542 SepCaptureAcl( 543 IN PACL InputAcl, 544 IN KPROCESSOR_MODE AccessMode, 545 IN POOL_TYPE PoolType, 546 IN BOOLEAN CaptureIfKernel, 547 OUT PACL *CapturedAcl 548 ); 549 550 VOID 551 NTAPI 552 SepReleaseAcl( 553 IN PACL CapturedAcl, 554 IN KPROCESSOR_MODE AccessMode, 555 IN BOOLEAN CaptureIfKernel 556 ); 557 558 NTSTATUS 559 SepPropagateAcl( 560 _Out_writes_bytes_opt_(DaclLength) PACL AclDest, 561 _Inout_ PULONG AclLength, 562 _In_reads_bytes_(AclSource->AclSize) PACL AclSource, 563 _In_ PSID Owner, 564 _In_ PSID Group, 565 _In_ BOOLEAN IsInherited, 566 _In_ BOOLEAN IsDirectoryObject, 567 _In_ PGENERIC_MAPPING GenericMapping); 568 569 PACL 570 SepSelectAcl( 571 _In_opt_ PACL ExplicitAcl, 572 _In_ BOOLEAN ExplicitPresent, 573 _In_ BOOLEAN ExplicitDefaulted, 574 _In_opt_ PACL ParentAcl, 575 _In_opt_ PACL DefaultAcl, 576 _Out_ PULONG AclLength, 577 _In_ PSID Owner, 578 _In_ PSID Group, 579 _Out_ PBOOLEAN AclPresent, 580 _Out_ PBOOLEAN IsInherited, 581 _In_ BOOLEAN IsDirectoryObject, 582 _In_ PGENERIC_MAPPING GenericMapping); 583 584 NTSTATUS 585 NTAPI 586 SeDefaultObjectMethod( 587 PVOID Object, 588 SECURITY_OPERATION_CODE OperationType, 589 PSECURITY_INFORMATION SecurityInformation, 590 PSECURITY_DESCRIPTOR NewSecurityDescriptor, 591 PULONG ReturnLength, 592 PSECURITY_DESCRIPTOR *OldSecurityDescriptor, 593 POOL_TYPE PoolType, 594 PGENERIC_MAPPING GenericMapping 595 ); 596 597 NTSTATUS 598 NTAPI 599 SeSetWorldSecurityDescriptor( 600 SECURITY_INFORMATION SecurityInformation, 601 PISECURITY_DESCRIPTOR SecurityDescriptor, 602 PULONG BufferLength 603 ); 604 605 NTSTATUS 606 NTAPI 607 SeCopyClientToken( 608 IN PACCESS_TOKEN Token, 609 IN SECURITY_IMPERSONATION_LEVEL Level, 610 IN KPROCESSOR_MODE PreviousMode, 611 OUT PACCESS_TOKEN* NewToken 612 ); 613 614 NTSTATUS 615 NTAPI 616 SepRegQueryHelper( 617 _In_ PCWSTR KeyName, 618 _In_ PCWSTR ValueName, 619 _In_ ULONG ValueType, 620 _In_ ULONG DataLength, 621 _Out_ PVOID ValueData); 622 623 VOID NTAPI 624 SeQuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, 625 OUT PACCESS_MASK DesiredAccess); 626 627 VOID NTAPI 628 SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, 629 OUT PACCESS_MASK DesiredAccess); 630 631 BOOLEAN 632 NTAPI 633 SeFastTraverseCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, 634 IN PACCESS_STATE AccessState, 635 IN ACCESS_MASK DesiredAccess, 636 IN KPROCESSOR_MODE AccessMode); 637 638 BOOLEAN 639 NTAPI 640 SeCheckAuditPrivilege( 641 _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, 642 _In_ KPROCESSOR_MODE PreviousMode); 643 644 VOID 645 NTAPI 646 SePrivilegedServiceAuditAlarm( 647 _In_opt_ PUNICODE_STRING ServiceName, 648 _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, 649 _In_ PPRIVILEGE_SET PrivilegeSet, 650 _In_ BOOLEAN AccessGranted); 651 652 NTSTATUS 653 SepRmReferenceLogonSession( 654 PLUID LogonLuid); 655 656 NTSTATUS 657 SepRmDereferenceLogonSession( 658 PLUID LogonLuid); 659 660 NTSTATUS 661 NTAPI 662 SeGetLogonIdDeviceMap( 663 IN PLUID LogonId, 664 OUT PDEVICE_MAP * DeviceMap); 665 666 #endif 667 668 /* EOF */ 669