diff --git a/boot/freeldr/freeldr/arch/i386/i386bug.c b/boot/freeldr/freeldr/arch/i386/i386bug.c index d31796d16de..d8d5d8944bf 100644 --- a/boot/freeldr/freeldr/arch/i386/i386bug.c +++ b/boot/freeldr/freeldr/arch/i386/i386bug.c @@ -108,8 +108,7 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGIST i386_ScreenPosX = 0; i386_ScreenPosY = 0; - PrintText("An error occured in FreeLoader\n" - VERSION"\n" + PrintText("An error occured in " VERSION "\n" "Report this error to the ReactOS Development mailing list \n\n" "0x%02lx: %s\n", TrapIndex, i386ExceptionDescriptionText[TrapIndex]); #ifdef _M_IX86 diff --git a/boot/freeldr/freeldr/arch/i386/pcmem.c b/boot/freeldr/freeldr/arch/i386/pcmem.c index 76601e4118a..0c2d3cbb0ef 100644 --- a/boot/freeldr/freeldr/arch/i386/pcmem.c +++ b/boot/freeldr/freeldr/arch/i386/pcmem.c @@ -32,7 +32,6 @@ DBG_DEFAULT_CHANNEL(MEMORY); #define STACK_BASE_PAGE (STACKLOW / PAGE_SIZE) #define FREELDR_BASE_PAGE (FREELDR_BASE / PAGE_SIZE) #define DISKBUF_BASE_PAGE (DISKREADBUFFER / PAGE_SIZE) -#define BIOSBUF_BASE_PAGE (BIOSCALLBUFFER / PAGE_SIZE) #define STACK_PAGE_COUNT (FREELDR_BASE_PAGE - STACK_BASE_PAGE) #define FREELDR_PAGE_COUNT (DISKBUF_BASE_PAGE - FREELDR_BASE_PAGE) @@ -45,11 +44,10 @@ ULONG PcBiosMapCount; FREELDR_MEMORY_DESCRIPTOR PcMemoryMap[MAX_BIOS_DESCRIPTORS + 1] = { { LoaderFirmwarePermanent, 0x00, 1 }, // realmode int vectors - { LoaderFirmwareTemporary, 0x01, STACK_BASE_PAGE - 1 }, // freeldr stack + cmdline + { LoaderFirmwareTemporary, 0x01, STACK_BASE_PAGE - 1 }, // freeldr stack, cmdline, BIOS call buffer { LoaderOsloaderStack, STACK_BASE_PAGE, FREELDR_BASE_PAGE - STACK_BASE_PAGE }, // prot mode stack. { LoaderLoadedProgram, FREELDR_BASE_PAGE, FREELDR_PAGE_COUNT }, // freeldr image { LoaderFirmwareTemporary, DISKBUF_BASE_PAGE, DISKBUF_PAGE_COUNT }, // Disk read buffer for int 13h. DISKREADBUFFER - { LoaderFirmwareTemporary, BIOSBUF_BASE_PAGE, BIOSBUF_PAGE_COUNT }, // BIOSCALLBUFFER { LoaderFirmwarePermanent, 0x9F, 0x1 }, // EBDA { LoaderFirmwarePermanent, 0xA0, 0x50 }, // ROM / Video { LoaderSpecialMemory, 0xF0, 0x10 }, // ROM / Video @@ -203,13 +201,14 @@ PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSi bit value at address 0x413 inside the BDA, which gives us the usable size in KB */ Size = (*(PUSHORT)(ULONG_PTR)0x413) * 1024; - if (Size < 0x9F000) + if (Size < MEMORY_MARGIN) { FrLdrBugCheckWithMessage( MEMORY_INIT_FAILURE, __FILE__, __LINE__, - "The BIOS reported a usable memory range up to 0x%x, which is too small!\n", + "The BIOS reported a usable memory range up to 0x%x, which is too small!\n\n" + "If you see this, please report to the ReactOS team!", Size); } @@ -230,13 +229,13 @@ PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSi { /* Check if this is high enough */ ULONG EbdaBase = (ULONG)Regs.w.es << 4; - if (EbdaBase < 0x9F000) + if (EbdaBase < MEMORY_MARGIN) { FrLdrBugCheckWithMessage( MEMORY_INIT_FAILURE, __FILE__, __LINE__, - "The location of your EBDA is 0x%lx, which is too low!\n" + "The location of your EBDA is 0x%lx, which is too low!\n\n" "If you see this, please report to the ReactOS team!", EbdaBase); } diff --git a/boot/freeldr/freeldr/include/arch/pc/x86common.h b/boot/freeldr/freeldr/include/arch/pc/x86common.h index b238a8fd97a..325c1b233a6 100644 --- a/boot/freeldr/freeldr/include/arch/pc/x86common.h +++ b/boot/freeldr/freeldr/include/arch/pc/x86common.h @@ -9,6 +9,7 @@ #define PDP_ADDRESS HEX(2000) /* One page PDP page table */ #define PD_ADDRESS HEX(3000) /* One page PD page table */ //#endif +#define BIOSCALLBUFFER HEX(4000) /* Buffer to store temporary data for any Int386() call */ #define STACK16ADDR HEX(6F00) /* The 16-bit stack top will be at 0000:6F00 */ #define BSS_START HEX(6F00) #define STACKLOW HEX(7000) @@ -16,7 +17,7 @@ #define FREELDR_BASE HEX(F800) #define FREELDR_PE_BASE HEX(10000) #define DISKREADBUFFER HEX(8E000) /* Buffer to store data read in from the disk via the BIOS */ -#define BIOSCALLBUFFER HEX(9E000) /* Buffer to store temporary data for any Int386() call */ +#define MEMORY_MARGIN HEX(9E000) /* Highest usable address */ /* 9F000- 9FFFF is reserved for the EBDA */ #define DISKREADBUFFER_SIZE HEX(10000) diff --git a/dll/win32/advapi32/CMakeLists.txt b/dll/win32/advapi32/CMakeLists.txt index fe6bf4647de..e54d48cb7a5 100644 --- a/dll/win32/advapi32/CMakeLists.txt +++ b/dll/win32/advapi32/CMakeLists.txt @@ -28,22 +28,21 @@ list(APPEND SOURCE reg/reg.c sec/ac.c sec/audit.c - sec/cred.c sec/lsa.c sec/misc.c sec/safer.c sec/sec.c - sec/sid.c sec/trustee.c service/eventlog.c service/rpc.c service/scm.c service/sctrl.c - token/privilege.c token/token.c + wine/cred.c wine/crypt.c wine/crypt_des.c wine/crypt_lmhash.c + wine/security.c advapi32.h) add_library(advapi32 SHARED diff --git a/dll/win32/advapi32/token/privilege.c b/dll/win32/advapi32/token/privilege.c deleted file mode 100644 index 2b0762a1711..00000000000 --- a/dll/win32/advapi32/token/privilege.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * FILE: lib/advapi32/token/privilege.c - * PURPOSE: advapi32.dll token's privilege handling - * PROGRAMMER: E.Aliberti - * UPDATE HISTORY: - * 20010317 ea stubs - */ - -#include - - -/********************************************************************** - * PrivilegeCheck EXPORTED - * - * @implemented - */ -BOOL WINAPI -PrivilegeCheck(HANDLE ClientToken, - PPRIVILEGE_SET RequiredPrivileges, - LPBOOL pfResult) -{ - BOOLEAN Result; - NTSTATUS Status; - - Status = NtPrivilegeCheck(ClientToken, - RequiredPrivileges, - &Result); - if (!NT_SUCCESS(Status)) - { - SetLastError(RtlNtStatusToDosError(Status)); - return FALSE; - } - - *pfResult = (BOOL)Result; - - return TRUE; -} - -/* EOF */ diff --git a/dll/win32/advapi32/sec/cred.c b/dll/win32/advapi32/wine/cred.c similarity index 100% rename from dll/win32/advapi32/sec/cred.c rename to dll/win32/advapi32/wine/cred.c diff --git a/dll/win32/advapi32/sec/sid.c b/dll/win32/advapi32/wine/security.c similarity index 98% rename from dll/win32/advapi32/sec/sid.c rename to dll/win32/advapi32/wine/security.c index fe1bb856df6..130f6e5b43f 100644 --- a/dll/win32/advapi32/sec/sid.c +++ b/dll/win32/advapi32/wine/security.c @@ -7,8 +7,7 @@ * Copyright 2006 Hervé Poussineau * * PROJECT: ReactOS system libraries - * FILE: dll/win32/advapi32/sec/sid.c - * PURPOSE: Security ID functions + * FILE: dll/win32/advapi32/wine/security.c */ #include @@ -17,6 +16,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(advapi); +static DWORD ComputeStringSidSize(LPCWSTR StringSid); +static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes); + #define MAX_GUID_STRING_LEN 39 BOOL WINAPI @@ -258,42 +260,6 @@ static const ACEFLAG AceRights[] = { NULL, 0 }, }; -static const LPCWSTR AceRightBitNames[32] = { - SDDL_CREATE_CHILD, /* 0 */ - SDDL_DELETE_CHILD, - SDDL_LIST_CHILDREN, - SDDL_SELF_WRITE, - SDDL_READ_PROPERTY, /* 4 */ - SDDL_WRITE_PROPERTY, - SDDL_DELETE_TREE, - SDDL_LIST_OBJECT, - SDDL_CONTROL_ACCESS, /* 8 */ - NULL, - NULL, - NULL, - NULL, /* 12 */ - NULL, - NULL, - NULL, - SDDL_STANDARD_DELETE, /* 16 */ - SDDL_READ_CONTROL, - SDDL_WRITE_DAC, - SDDL_WRITE_OWNER, - NULL, /* 20 */ - NULL, - NULL, - NULL, - NULL, /* 24 */ - NULL, - NULL, - NULL, - SDDL_GENERIC_ALL, /* 28 */ - SDDL_GENERIC_EXECUTE, - SDDL_GENERIC_WRITE, - SDDL_GENERIC_READ -}; - - /* set last error code from NT status and get the proper boolean return value */ /* used for functions that are a simple wrapper around the corresponding ntdll API */ static __inline BOOL set_ntstatus( NTSTATUS status ) @@ -302,28 +268,51 @@ static __inline BOOL set_ntstatus( NTSTATUS status ) return !status; } +static const RECORD SidTable[] = +{ + { SDDL_ACCOUNT_OPERATORS, WinBuiltinAccountOperatorsSid }, + { SDDL_ALIAS_PREW2KCOMPACC, WinBuiltinPreWindows2000CompatibleAccessSid }, + { SDDL_ANONYMOUS, WinAnonymousSid }, + { SDDL_AUTHENTICATED_USERS, WinAuthenticatedUserSid }, + { SDDL_BUILTIN_ADMINISTRATORS, WinBuiltinAdministratorsSid }, + { SDDL_BUILTIN_GUESTS, WinBuiltinGuestsSid }, + { SDDL_BACKUP_OPERATORS, WinBuiltinBackupOperatorsSid }, + { SDDL_BUILTIN_USERS, WinBuiltinUsersSid }, + { SDDL_CERT_SERV_ADMINISTRATORS, WinAccountCertAdminsSid /* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ }, + { SDDL_CREATOR_GROUP, WinCreatorGroupSid }, + { SDDL_CREATOR_OWNER, WinCreatorOwnerSid }, + { SDDL_DOMAIN_ADMINISTRATORS, WinAccountDomainAdminsSid /* FIXME: DOMAIN_GROUP_RID_ADMINS */ }, + { SDDL_DOMAIN_COMPUTERS, WinAccountComputersSid /* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ }, + { SDDL_DOMAIN_DOMAIN_CONTROLLERS, WinAccountControllersSid /* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ }, + { SDDL_DOMAIN_GUESTS, WinAccountDomainGuestsSid /* FIXME: DOMAIN_GROUP_RID_GUESTS */ }, + { SDDL_DOMAIN_USERS, WinAccountDomainUsersSid /* FIXME: DOMAIN_GROUP_RID_USERS */ }, + { SDDL_ENTERPRISE_ADMINS, WinAccountEnterpriseAdminsSid /* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ }, + { SDDL_ENTERPRISE_DOMAIN_CONTROLLERS, WinEnterpriseControllersSid }, + { SDDL_EVERYONE, WinWorldSid }, + { SDDL_GROUP_POLICY_ADMINS, WinAccountPolicyAdminsSid /* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ }, + { SDDL_INTERACTIVE, WinInteractiveSid }, + { SDDL_LOCAL_ADMIN, WinAccountAdministratorSid /* FIXME: DOMAIN_USER_RID_ADMIN */ }, + { SDDL_LOCAL_GUEST, WinAccountGuestSid /* FIXME: DOMAIN_USER_RID_GUEST */ }, + { SDDL_LOCAL_SERVICE, WinLocalServiceSid }, + { SDDL_LOCAL_SYSTEM, WinLocalSystemSid }, + { SDDL_NETWORK, WinNetworkSid }, + { SDDL_NETWORK_CONFIGURATION_OPS, WinBuiltinNetworkConfigurationOperatorsSid }, + { SDDL_NETWORK_SERVICE, WinNetworkServiceSid }, + { SDDL_PRINTER_OPERATORS, WinBuiltinPrintOperatorsSid }, + { SDDL_PERSONAL_SELF, WinSelfSid }, + { SDDL_POWER_USERS, WinBuiltinPowerUsersSid }, + { SDDL_RAS_SERVERS, WinAccountRasAndIasServersSid /* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ }, + { SDDL_REMOTE_DESKTOP, WinBuiltinRemoteDesktopUsersSid }, + { SDDL_REPLICATOR, WinBuiltinReplicatorSid }, + { SDDL_RESTRICTED_CODE, WinRestrictedCodeSid }, + { SDDL_SCHEMA_ADMINISTRATORS, WinAccountSchemaAdminsSid /* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ }, + { SDDL_SERVER_OPERATORS, WinBuiltinSystemOperatorsSid }, + { SDDL_SERVICE, WinServiceSid }, + { NULL, 0 }, +}; /* Exported functions */ -/* - * @implemented - */ -BOOL WINAPI -AllocateLocallyUniqueId(PLUID Luid) -{ - NTSTATUS Status; - - Status = NtAllocateLocallyUniqueId (Luid); - if (!NT_SUCCESS (Status)) - { - SetLastError(RtlNtStatusToDosError(Status)); - return FALSE; - } - - return TRUE; -} - - /* * @implemented */ @@ -362,6 +351,19 @@ AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, return TRUE; } +/* + * @implemented + * + * RETURNS + * Docs says this function does NOT return a value + * even thou it's defined to return a PVOID... + */ +PVOID +WINAPI +FreeSid(PSID pSid) +{ + return RtlFreeSid(pSid); +} /* * @implemented @@ -385,531 +387,237 @@ CopySid(DWORD nDestinationSidLength, return TRUE; } -static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen) +/* + * @unimplemented + */ +BOOL +WINAPI +CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType, + IN PSID DomainSid OPTIONAL, + OUT PSID pSid, + IN OUT DWORD* cbSid) { - if (cch == -1) - cch = strlenW(string); + unsigned int i; + TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid); - if (plen) - *plen += cch; - - if (pwptr) + if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid))) { - memcpy(*pwptr, string, sizeof(WCHAR)*cch); - *pwptr += cch; - } -} - -static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen) -{ - DWORD i; - WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 }; - WCHAR subauthfmt[] = { '-','%','u',0 }; - WCHAR buf[26]; - SID *pisid = psid; - - if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION) - { - SetLastError(ERROR_INVALID_SID); + SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - if (pisid->IdentifierAuthority.Value[0] || - pisid->IdentifierAuthority.Value[1]) - { - FIXME("not matching MS' bugs\n"); - SetLastError(ERROR_INVALID_SID); - return FALSE; - } + for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) { + if (WellKnownSids[i].Type == WellKnownSidType) { + DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount); - sprintfW( buf, fmt, pisid->Revision, - MAKELONG( - MAKEWORD( pisid->IdentifierAuthority.Value[5], - pisid->IdentifierAuthority.Value[4] ), - MAKEWORD( pisid->IdentifierAuthority.Value[3], - pisid->IdentifierAuthority.Value[2] ) - ) ); - DumpString(buf, -1, pwptr, plen); - - for( i=0; iSubAuthorityCount; i++ ) - { - sprintfW( buf, subauthfmt, pisid->SubAuthority[i] ); - DumpString(buf, -1, pwptr, plen); - } - return TRUE; -} - -static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen) -{ - size_t i; - for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++) - { - if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision))) - { - DumpString(WellKnownSids[i].wstr, 2, pwptr, plen); + if (*cbSid < length) + { + *cbSid = length; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + if (!pSid) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length); + *cbSid = length; return TRUE; } } - return DumpSidNumeric(psid, pwptr, plen); -} - -static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen) -{ - static const WCHAR fmtW[] = {'0','x','%','x',0}; - WCHAR buf[15]; - size_t i; - - if (mask == 0) - return; - - /* first check if the right have name */ - for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++) - { - if (AceRights[i].wstr == NULL) - break; - if (mask == AceRights[i].value) - { - DumpString(AceRights[i].wstr, -1, pwptr, plen); - return; - } - } - - /* then check if it can be built from bit names */ - for (i = 0; i < 32; i++) - { - if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL)) - { - /* can't be built from bit names */ - sprintfW(buf, fmtW, mask); - DumpString(buf, -1, pwptr, plen); - return; - } - } - - /* build from bit names */ - for (i = 0; i < 32; i++) - if (mask & (1 << i)) - DumpString(AceRightBitNames[i], -1, pwptr, plen); -} - -static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen) -{ - ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */ - static const WCHAR openbr = '('; - static const WCHAR closebr = ')'; - static const WCHAR semicolon = ';'; - - if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE)) - { - SetLastError(ERROR_INVALID_ACL); - return FALSE; - } - - piace = pace; - DumpString(&openbr, 1, pwptr, plen); - switch (piace->Header.AceType) - { - case ACCESS_ALLOWED_ACE_TYPE: - DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen); - break; - case ACCESS_DENIED_ACE_TYPE: - DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen); - break; - case SYSTEM_AUDIT_ACE_TYPE: - DumpString(SDDL_AUDIT, -1, pwptr, plen); - break; - case SYSTEM_ALARM_ACE_TYPE: - DumpString(SDDL_ALARM, -1, pwptr, plen); - break; - } - DumpString(&semicolon, 1, pwptr, plen); - - if (piace->Header.AceFlags & OBJECT_INHERIT_ACE) - DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen); - if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE) - DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen); - if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE) - DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen); - if (piace->Header.AceFlags & INHERIT_ONLY_ACE) - DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen); - if (piace->Header.AceFlags & INHERITED_ACE) - DumpString(SDDL_INHERITED, -1, pwptr, plen); - if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) - DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen); - if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG) - DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen); - DumpString(&semicolon, 1, pwptr, plen); - DumpRights(piace->Mask, pwptr, plen); - DumpString(&semicolon, 1, pwptr, plen); - /* objects not supported */ - DumpString(&semicolon, 1, pwptr, plen); - /* objects not supported */ - DumpString(&semicolon, 1, pwptr, plen); - if (!DumpSid((PSID)&piace->SidStart, pwptr, plen)) - return FALSE; - DumpString(&closebr, 1, pwptr, plen); - return TRUE; -} - -static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited) -{ - WORD count; - int i; - - if (protected) - DumpString(SDDL_PROTECTED, -1, pwptr, plen); - if (autoInheritReq) - DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen); - if (autoInherited) - DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen); - - if (pacl == NULL) - return TRUE; - - if (!IsValidAcl(pacl)) - return FALSE; - - count = pacl->AceCount; - for (i = 0; i < count; i++) - { - LPVOID ace; - if (!GetAce(pacl, i, &ace)) - return FALSE; - if (!DumpAce(ace, pwptr, plen)) - return FALSE; - } - - return TRUE; -} - -static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) -{ - static const WCHAR prefix[] = {'O',':',0}; - BOOL bDefaulted; - PSID psid; - - if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted)) - return FALSE; - - if (psid == NULL) - return TRUE; - - DumpString(prefix, -1, pwptr, plen); - if (!DumpSid(psid, pwptr, plen)) - return FALSE; - return TRUE; -} - -static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) -{ - static const WCHAR prefix[] = {'G',':',0}; - BOOL bDefaulted; - PSID psid; - - if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted)) - return FALSE; - - if (psid == NULL) - return TRUE; - - DumpString(prefix, -1, pwptr, plen); - if (!DumpSid(psid, pwptr, plen)) - return FALSE; - return TRUE; -} - -static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) -{ - static const WCHAR dacl[] = {'D',':',0}; - SECURITY_DESCRIPTOR_CONTROL control; - BOOL present, defaulted; - DWORD revision; - PACL pacl; - - if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted)) - return FALSE; - - if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision)) - return FALSE; - - if (!present) - return TRUE; - - DumpString(dacl, 2, pwptr, plen); - if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED)) - return FALSE; - return TRUE; -} - -static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) -{ - static const WCHAR sacl[] = {'S',':',0}; - SECURITY_DESCRIPTOR_CONTROL control; - BOOL present, defaulted; - DWORD revision; - PACL pacl; - - if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted)) - return FALSE; - - if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision)) - return FALSE; - - if (!present) - return TRUE; - - DumpString(sacl, 2, pwptr, plen); - if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED)) - return FALSE; - return TRUE; -} - -/****************************************************************************** - * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@] - * @implemented - */ -BOOL WINAPI -ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, - DWORD SDRevision, - SECURITY_INFORMATION SecurityInformation, - LPWSTR *OutputString, - PULONG OutputLen) -{ - ULONG len; - WCHAR *wptr, *wstr; - - if (SDRevision != SDDL_REVISION_1) - { - ERR("Program requested unknown SDDL revision %d\n", SDRevision); - SetLastError(ERROR_UNKNOWN_REVISION); - return FALSE; - } - - len = 0; - if (SecurityInformation & OWNER_SECURITY_INFORMATION) - if (!DumpOwner(SecurityDescriptor, NULL, &len)) - return FALSE; - if (SecurityInformation & GROUP_SECURITY_INFORMATION) - if (!DumpGroup(SecurityDescriptor, NULL, &len)) - return FALSE; - if (SecurityInformation & DACL_SECURITY_INFORMATION) - if (!DumpDacl(SecurityDescriptor, NULL, &len)) - return FALSE; - if (SecurityInformation & SACL_SECURITY_INFORMATION) - if (!DumpSacl(SecurityDescriptor, NULL, &len)) - return FALSE; - - wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR)); - if (wstr == NULL) - return FALSE; - - if (SecurityInformation & OWNER_SECURITY_INFORMATION) - if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) - return FALSE; - if (SecurityInformation & GROUP_SECURITY_INFORMATION) - if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) - return FALSE; - if (SecurityInformation & DACL_SECURITY_INFORMATION) - if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) - return FALSE; - if (SecurityInformation & SACL_SECURITY_INFORMATION) - if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) - return FALSE; - *wptr = 0; - - TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len); - *OutputString = wstr; - if (OutputLen) - *OutputLen = strlenW(*OutputString)+1; - return TRUE; -} - - -/****************************************************************************** - * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@] - * @implemented - */ -BOOL WINAPI -ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, - DWORD SDRevision, - SECURITY_INFORMATION Information, - LPSTR *OutputString, - PULONG OutputLen) -{ - LPWSTR wstr; - ULONG len; - - if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len)) - { - int lenA; - - lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL); - *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA); - if (*OutputString == NULL) - { - LocalFree(wstr); - *OutputLen = 0; - return FALSE; - } - WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL); - LocalFree(wstr); - - if (OutputLen != NULL) - *OutputLen = lenA; - return TRUE; - } - else - { - *OutputString = NULL; - if (OutputLen) - *OutputLen = 0; - return FALSE; - } -} - - -/****************************************************************************** - * ComputeStringSidSize - */ -static DWORD ComputeStringSidSize(LPCWSTR StringSid) -{ - if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */ - { - int ctok = 0; - while (*StringSid) - { - if (*StringSid == '-') - ctok++; - StringSid++; - } - - if (ctok >= 3) - return GetSidLengthRequired(ctok - 2); - } - else /* String constant format - Only available in winxp and above */ - { - unsigned int i; - - for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) - if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2)) - return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount); - } - - return GetSidLengthRequired(0); -} - -/****************************************************************************** - * ParseStringSidToSid - */ -static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes) -{ - BOOL bret = FALSE; - SID* pisid=pSid; - - TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes); - if (!StringSid) + if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES) { SetLastError(ERROR_INVALID_PARAMETER); - TRACE("StringSid is NULL, returning FALSE\n"); return FALSE; } - while (*StringSid == ' ') - StringSid++; + for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++) + if (WellKnownRids[i].Type == WellKnownSidType) { + UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid); + DWORD domain_sid_length = GetSidLengthRequired(domain_subauth); + DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1); - *cBytes = ComputeStringSidSize(StringSid); - if (!pisid) /* Simply compute the size */ - { - TRACE("only size requested, returning TRUE\n"); - return TRUE; - } - - if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */ - { - DWORD i = 0, identAuth; - DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD)); - - StringSid += 2; /* Advance to Revision */ - pisid->Revision = atoiW(StringSid); - - if (pisid->Revision != SDDL_REVISION) - { - TRACE("Revision %d is unknown\n", pisid->Revision); - goto lend; /* ERROR_INVALID_SID */ - } - if (csubauth == 0) - { - TRACE("SubAuthorityCount is 0\n"); - goto lend; /* ERROR_INVALID_SID */ - } - - pisid->SubAuthorityCount = csubauth; - - /* Advance to identifier authority */ - while (*StringSid && *StringSid != '-') - StringSid++; - if (*StringSid == '-') - StringSid++; - - /* MS' implementation can't handle values greater than 2^32 - 1, so - * we don't either; assume most significant bytes are always 0 - */ - pisid->IdentifierAuthority.Value[0] = 0; - pisid->IdentifierAuthority.Value[1] = 0; - identAuth = atoiW(StringSid); - pisid->IdentifierAuthority.Value[5] = identAuth & 0xff; - pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8; - pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16; - pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24; - - /* Advance to first sub authority */ - while (*StringSid && *StringSid != '-') - StringSid++; - if (*StringSid == '-') - StringSid++; - - while (*StringSid) - { - pisid->SubAuthority[i++] = atoiW(StringSid); - - while (*StringSid && *StringSid != '-') - StringSid++; - if (*StringSid == '-') - StringSid++; - } - - if (i != pisid->SubAuthorityCount) - goto lend; /* ERROR_INVALID_SID */ - - bret = TRUE; - } - else /* String constant format - Only available in winxp and above */ - { - unsigned int i; - pisid->Revision = SDDL_REVISION; - - for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) - if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2)) + if (*cbSid < output_sid_length) { - DWORD j; - pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount; - pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority; - for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++) - pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j]; - bret = TRUE; + *cbSid = output_sid_length; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; } + if (!pSid) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + CopyMemory(pSid, DomainSid, domain_sid_length); + (*GetSidSubAuthorityCount(pSid))++; + (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid; + *cbSid = output_sid_length; + return TRUE; + } - if (!bret) - FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2)); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +IsWellKnownSid(IN PSID pSid, + IN WELL_KNOWN_SID_TYPE WellKnownSidType) +{ + unsigned int i; + TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType); + + for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++) + { + if (WellKnownSids[i].Type == WellKnownSidType) + { + if (EqualSid(pSid, (PSID)(&WellKnownSids[i].Sid.Revision))) + return TRUE; + } } -lend: - if (!bret) - SetLastError(ERROR_INVALID_SID); + return FALSE; +} - TRACE("returning %s\n", bret ? "TRUE" : "FALSE"); - return bret; +/* + * @implemented + */ +BOOL +WINAPI +IsValidSid(PSID pSid) +{ + return (BOOL)RtlValidSid(pSid); +} + +/* + * @implemented + */ +BOOL +WINAPI +EqualSid(PSID pSid1, + PSID pSid2) +{ + SetLastError(ERROR_SUCCESS); + return RtlEqualSid (pSid1, pSid2); +} + +/* + * @implemented + */ +BOOL +WINAPI +EqualPrefixSid(PSID pSid1, + PSID pSid2) +{ + return RtlEqualPrefixSid (pSid1, pSid2); +} + +/* + * @implemented + */ +DWORD +WINAPI +GetSidLengthRequired(UCHAR nSubAuthorityCount) +{ + return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount); +} + +/* + * @implemented + */ +BOOL +WINAPI +InitializeSid(PSID Sid, + PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, + BYTE nSubAuthorityCount) +{ + NTSTATUS Status; + + Status = RtlInitializeSid(Sid, + pIdentifierAuthority, + nSubAuthorityCount); + if (!NT_SUCCESS(Status)) + { + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; + } + + return TRUE; +} + +/* + * @implemented + */ +PSID_IDENTIFIER_AUTHORITY +WINAPI +GetSidIdentifierAuthority(PSID pSid) +{ + return RtlIdentifierAuthoritySid(pSid); +} + +/* + * @implemented + */ +PDWORD +WINAPI +GetSidSubAuthority(PSID pSid, + DWORD nSubAuthority) +{ + SetLastError(ERROR_SUCCESS); + return (PDWORD)RtlSubAuthoritySid(pSid, nSubAuthority); +} + +/* + * @implemented + */ +PUCHAR +WINAPI +GetSidSubAuthorityCount(PSID pSid) +{ + SetLastError(ERROR_SUCCESS); + return RtlSubAuthorityCountSid(pSid); +} + +/* + * @implemented + */ +DWORD +WINAPI +GetLengthSid(PSID pSid) +{ + return (DWORD)RtlLengthSid(pSid); +} + +/********************************************************************** + * PrivilegeCheck EXPORTED + * + * @implemented + */ +BOOL WINAPI +PrivilegeCheck(HANDLE ClientToken, + PPRIVILEGE_SET RequiredPrivileges, + LPBOOL pfResult) +{ + BOOLEAN Result; + NTSTATUS Status; + + Status = NtPrivilegeCheck(ClientToken, + RequiredPrivileges, + &Result); + if (!NT_SUCCESS(Status)) + { + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; + } + + *pfResult = (BOOL)Result; + + return TRUE; } /****************************************************************************** @@ -1328,6 +1036,37 @@ lend: return bret; } +/* Winehq cvs 20050916 */ +/****************************************************************************** + * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@] + * @implemented + */ +BOOL +WINAPI +ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor, + DWORD StringSDRevision, + PSECURITY_DESCRIPTOR* SecurityDescriptor, + PULONG SecurityDescriptorSize) +{ + UINT len; + BOOL ret = FALSE; + LPWSTR StringSecurityDescriptorW; + + len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0); + StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + + if (StringSecurityDescriptorW) + { + MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len); + + ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW, + StringSDRevision, SecurityDescriptor, + SecurityDescriptorSize); + HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW); + } + + return ret; +} /****************************************************************************** * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@] @@ -1389,470 +1128,422 @@ lend: return bret; } - -/* Winehq cvs 20050916 */ -/****************************************************************************** - * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@] - * @implemented - */ -BOOL -WINAPI -ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor, - DWORD StringSDRevision, - PSECURITY_DESCRIPTOR* SecurityDescriptor, - PULONG SecurityDescriptorSize) +static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen) { - UINT len; - BOOL ret = FALSE; - LPWSTR StringSecurityDescriptorW; + if (cch == -1) + cch = strlenW(string); - len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0); - StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (plen) + *plen += cch; - if (StringSecurityDescriptorW) + if (pwptr) { - MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len); - - ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW, - StringSDRevision, SecurityDescriptor, - SecurityDescriptorSize); - HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW); + memcpy(*pwptr, string, sizeof(WCHAR)*cch); + *pwptr += cch; } - - return ret; } -/* - * @implemented - */ -BOOL -WINAPI -EqualPrefixSid(PSID pSid1, - PSID pSid2) +static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen) { - return RtlEqualPrefixSid (pSid1, pSid2); -} + DWORD i; + WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 }; + WCHAR subauthfmt[] = { '-','%','u',0 }; + WCHAR buf[26]; + SID *pisid = psid; - -/* - * @implemented - */ -BOOL -WINAPI -EqualSid(PSID pSid1, - PSID pSid2) -{ - SetLastError(ERROR_SUCCESS); - return RtlEqualSid (pSid1, pSid2); -} - - -/* - * @implemented - * - * RETURNS - * Docs says this function does NOT return a value - * even thou it's defined to return a PVOID... - */ -PVOID -WINAPI -FreeSid(PSID pSid) -{ - return RtlFreeSid(pSid); -} - - -/* - * @implemented - */ -DWORD -WINAPI -GetLengthSid(PSID pSid) -{ - return (DWORD)RtlLengthSid(pSid); -} - - -/* - * @implemented - */ -PSID_IDENTIFIER_AUTHORITY -WINAPI -GetSidIdentifierAuthority(PSID pSid) -{ - return RtlIdentifierAuthoritySid(pSid); -} - - -/* - * @implemented - */ -DWORD -WINAPI -GetSidLengthRequired(UCHAR nSubAuthorityCount) -{ - return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount); -} - - -/* - * @implemented - */ -PDWORD -WINAPI -GetSidSubAuthority(PSID pSid, - DWORD nSubAuthority) -{ - SetLastError(ERROR_SUCCESS); - return (PDWORD)RtlSubAuthoritySid(pSid, nSubAuthority); -} - - -/* - * @implemented - */ -PUCHAR -WINAPI -GetSidSubAuthorityCount(PSID pSid) -{ - SetLastError(ERROR_SUCCESS); - return RtlSubAuthorityCountSid(pSid); -} - - -/* - * @implemented - */ -BOOL -WINAPI -InitializeSid(PSID Sid, - PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, - BYTE nSubAuthorityCount) -{ - NTSTATUS Status; - - Status = RtlInitializeSid(Sid, - pIdentifierAuthority, - nSubAuthorityCount); - if (!NT_SUCCESS(Status)) - { - SetLastError(RtlNtStatusToDosError(Status)); - return FALSE; - } - - return TRUE; -} - - -/* - * @implemented - */ -BOOL -WINAPI -IsValidSid(PSID pSid) -{ - return (BOOL)RtlValidSid(pSid); -} - - -/* - * @implemented - */ -BOOL -WINAPI -ConvertSidToStringSidW(PSID Sid, - LPWSTR *StringSid) -{ - NTSTATUS Status; - UNICODE_STRING UnicodeString; - WCHAR FixedBuffer[64]; - - if (!RtlValidSid(Sid)) + if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION) { SetLastError(ERROR_INVALID_SID); return FALSE; } - UnicodeString.Length = 0; - UnicodeString.MaximumLength = sizeof(FixedBuffer); - UnicodeString.Buffer = FixedBuffer; - Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, FALSE); - if (STATUS_BUFFER_TOO_SMALL == Status) + if (pisid->IdentifierAuthority.Value[0] || + pisid->IdentifierAuthority.Value[1]) { - Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, TRUE); - } - - if (!NT_SUCCESS(Status)) - { - SetLastError(RtlNtStatusToDosError(Status)); + FIXME("not matching MS' bugs\n"); + SetLastError(ERROR_INVALID_SID); return FALSE; } - *StringSid = LocalAlloc(LMEM_FIXED, UnicodeString.Length + sizeof(WCHAR)); - if (NULL == *StringSid) - { - if (UnicodeString.Buffer != FixedBuffer) - { - RtlFreeUnicodeString(&UnicodeString); - } - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } + sprintfW( buf, fmt, pisid->Revision, + MAKELONG( + MAKEWORD( pisid->IdentifierAuthority.Value[5], + pisid->IdentifierAuthority.Value[4] ), + MAKEWORD( pisid->IdentifierAuthority.Value[3], + pisid->IdentifierAuthority.Value[2] ) + ) ); + DumpString(buf, -1, pwptr, plen); - MoveMemory(*StringSid, UnicodeString.Buffer, UnicodeString.Length); - ZeroMemory((PCHAR) *StringSid + UnicodeString.Length, sizeof(WCHAR)); - if (UnicodeString.Buffer != FixedBuffer) + for( i=0; iSubAuthorityCount; i++ ) { - RtlFreeUnicodeString(&UnicodeString); + sprintfW( buf, subauthfmt, pisid->SubAuthority[i] ); + DumpString(buf, -1, pwptr, plen); } - return TRUE; } - -/* - * @implemented - */ -BOOL -WINAPI -ConvertSidToStringSidA(PSID Sid, - LPSTR *StringSid) +static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen) { - LPWSTR StringSidW; - int Len; - - if (!ConvertSidToStringSidW(Sid, &StringSidW)) - { - return FALSE; - } - - Len = WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, NULL, 0, NULL, NULL); - if (Len <= 0) - { - LocalFree(StringSidW); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - *StringSid = LocalAlloc(LMEM_FIXED, Len); - if (NULL == *StringSid) - { - LocalFree(StringSidW); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - if (!WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, *StringSid, Len, NULL, NULL)) - { - LocalFree(StringSid); - LocalFree(StringSidW); - return FALSE; - } - - LocalFree(StringSidW); - - return TRUE; -} - - -/* - * @unimplemented - */ -BOOL -WINAPI -EqualDomainSid(IN PSID pSid1, - IN PSID pSid2, - OUT BOOL* pfEqual) -{ - UNIMPLEMENTED; - return FALSE; -} - - -/* - * @unimplemented - */ -BOOL -WINAPI -GetWindowsAccountDomainSid(IN PSID pSid, - OUT PSID ppDomainSid, - IN OUT DWORD* cbSid) -{ - UNIMPLEMENTED; - return FALSE; -} - - -/* - * @unimplemented - */ -BOOL -WINAPI -CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType, - IN PSID DomainSid OPTIONAL, - OUT PSID pSid, - IN OUT DWORD* cbSid) -{ - unsigned int i; - TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid); - - if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid))) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) { - if (WellKnownSids[i].Type == WellKnownSidType) { - DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount); - - if (*cbSid < length) - { - *cbSid = length; - SetLastError(ERROR_INSUFFICIENT_BUFFER); - return FALSE; - } - if (!pSid) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length); - *cbSid = length; - return TRUE; - } - } - - if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++) - if (WellKnownRids[i].Type == WellKnownSidType) { - UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid); - DWORD domain_sid_length = GetSidLengthRequired(domain_subauth); - DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1); - - if (*cbSid < output_sid_length) - { - *cbSid = output_sid_length; - SetLastError(ERROR_INSUFFICIENT_BUFFER); - return FALSE; - } - if (!pSid) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - CopyMemory(pSid, DomainSid, domain_sid_length); - (*GetSidSubAuthorityCount(pSid))++; - (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid; - *cbSid = output_sid_length; - return TRUE; - } - - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; -} - - -/* - * @unimplemented - */ -BOOL -WINAPI -IsWellKnownSid(IN PSID pSid, - IN WELL_KNOWN_SID_TYPE WellKnownSidType) -{ - unsigned int i; - TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType); - + size_t i; for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++) { - if (WellKnownSids[i].Type == WellKnownSidType) + if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision))) { - if (EqualSid(pSid, (PSID)(&WellKnownSids[i].Sid.Revision))) - return TRUE; + DumpString(WellKnownSids[i].wstr, 2, pwptr, plen); + return TRUE; } } - return FALSE; + return DumpSidNumeric(psid, pwptr, plen); } +static const LPCWSTR AceRightBitNames[32] = { + SDDL_CREATE_CHILD, /* 0 */ + SDDL_DELETE_CHILD, + SDDL_LIST_CHILDREN, + SDDL_SELF_WRITE, + SDDL_READ_PROPERTY, /* 4 */ + SDDL_WRITE_PROPERTY, + SDDL_DELETE_TREE, + SDDL_LIST_OBJECT, + SDDL_CONTROL_ACCESS, /* 8 */ + NULL, + NULL, + NULL, + NULL, /* 12 */ + NULL, + NULL, + NULL, + SDDL_STANDARD_DELETE, /* 16 */ + SDDL_READ_CONTROL, + SDDL_WRITE_DAC, + SDDL_WRITE_OWNER, + NULL, /* 20 */ + NULL, + NULL, + NULL, + NULL, /* 24 */ + NULL, + NULL, + NULL, + SDDL_GENERIC_ALL, /* 28 */ + SDDL_GENERIC_EXECUTE, + SDDL_GENERIC_WRITE, + SDDL_GENERIC_READ +}; -/* +static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen) +{ + static const WCHAR fmtW[] = {'0','x','%','x',0}; + WCHAR buf[15]; + size_t i; + + if (mask == 0) + return; + + /* first check if the right have name */ + for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++) + { + if (AceRights[i].wstr == NULL) + break; + if (mask == AceRights[i].value) + { + DumpString(AceRights[i].wstr, -1, pwptr, plen); + return; + } + } + + /* then check if it can be built from bit names */ + for (i = 0; i < 32; i++) + { + if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL)) + { + /* can't be built from bit names */ + sprintfW(buf, fmtW, mask); + DumpString(buf, -1, pwptr, plen); + return; + } + } + + /* build from bit names */ + for (i = 0; i < 32; i++) + if (mask & (1 << i)) + DumpString(AceRightBitNames[i], -1, pwptr, plen); +} + +static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen) +{ + ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */ + static const WCHAR openbr = '('; + static const WCHAR closebr = ')'; + static const WCHAR semicolon = ';'; + + if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE)) + { + SetLastError(ERROR_INVALID_ACL); + return FALSE; + } + + piace = pace; + DumpString(&openbr, 1, pwptr, plen); + switch (piace->Header.AceType) + { + case ACCESS_ALLOWED_ACE_TYPE: + DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen); + break; + case ACCESS_DENIED_ACE_TYPE: + DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen); + break; + case SYSTEM_AUDIT_ACE_TYPE: + DumpString(SDDL_AUDIT, -1, pwptr, plen); + break; + case SYSTEM_ALARM_ACE_TYPE: + DumpString(SDDL_ALARM, -1, pwptr, plen); + break; + } + DumpString(&semicolon, 1, pwptr, plen); + + if (piace->Header.AceFlags & OBJECT_INHERIT_ACE) + DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen); + if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE) + DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen); + if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE) + DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen); + if (piace->Header.AceFlags & INHERIT_ONLY_ACE) + DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen); + if (piace->Header.AceFlags & INHERITED_ACE) + DumpString(SDDL_INHERITED, -1, pwptr, plen); + if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) + DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen); + if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG) + DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen); + DumpString(&semicolon, 1, pwptr, plen); + DumpRights(piace->Mask, pwptr, plen); + DumpString(&semicolon, 1, pwptr, plen); + /* objects not supported */ + DumpString(&semicolon, 1, pwptr, plen); + /* objects not supported */ + DumpString(&semicolon, 1, pwptr, plen); + if (!DumpSid((PSID)&piace->SidStart, pwptr, plen)) + return FALSE; + DumpString(&closebr, 1, pwptr, plen); + return TRUE; +} + +static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited) +{ + WORD count; + int i; + + if (protected) + DumpString(SDDL_PROTECTED, -1, pwptr, plen); + if (autoInheritReq) + DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen); + if (autoInherited) + DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen); + + if (pacl == NULL) + return TRUE; + + if (!IsValidAcl(pacl)) + return FALSE; + + count = pacl->AceCount; + for (i = 0; i < count; i++) + { + LPVOID ace; + if (!GetAce(pacl, i, &ace)) + return FALSE; + if (!DumpAce(ace, pwptr, plen)) + return FALSE; + } + + return TRUE; +} + +static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) +{ + static const WCHAR prefix[] = {'O',':',0}; + BOOL bDefaulted; + PSID psid; + + if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted)) + return FALSE; + + if (psid == NULL) + return TRUE; + + DumpString(prefix, -1, pwptr, plen); + if (!DumpSid(psid, pwptr, plen)) + return FALSE; + return TRUE; +} + +static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) +{ + static const WCHAR prefix[] = {'G',':',0}; + BOOL bDefaulted; + PSID psid; + + if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted)) + return FALSE; + + if (psid == NULL) + return TRUE; + + DumpString(prefix, -1, pwptr, plen); + if (!DumpSid(psid, pwptr, plen)) + return FALSE; + return TRUE; +} + +static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) +{ + static const WCHAR dacl[] = {'D',':',0}; + SECURITY_DESCRIPTOR_CONTROL control; + BOOL present, defaulted; + DWORD revision; + PACL pacl; + + if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted)) + return FALSE; + + if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision)) + return FALSE; + + if (!present) + return TRUE; + + DumpString(dacl, 2, pwptr, plen); + if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED)) + return FALSE; + return TRUE; +} + +static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) +{ + static const WCHAR sacl[] = {'S',':',0}; + SECURITY_DESCRIPTOR_CONTROL control; + BOOL present, defaulted; + DWORD revision; + PACL pacl; + + if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted)) + return FALSE; + + if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision)) + return FALSE; + + if (!present) + return TRUE; + + DumpString(sacl, 2, pwptr, plen); + if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED)) + return FALSE; + return TRUE; +} + +/****************************************************************************** + * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@] * @implemented */ -BOOL -WINAPI -ConvertStringSidToSidA(IN LPCSTR StringSid, - OUT PSID* sid) +BOOL WINAPI +ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, + DWORD SDRevision, + SECURITY_INFORMATION SecurityInformation, + LPWSTR *OutputString, + PULONG OutputLen) { - BOOL bRetVal = FALSE; + ULONG len; + WCHAR *wptr, *wstr; - TRACE("%s, %p\n", debugstr_a(StringSid), sid); - if (GetVersion() & 0x80000000) - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - else if (!StringSid || !sid) - SetLastError(ERROR_INVALID_PARAMETER); - else + if (SDRevision != SDDL_REVISION_1) { - UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0); - LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - if (wStringSid == NULL) - return FALSE; - MultiByteToWideChar(CP_ACP, 0, StringSid, - 1, wStringSid, len); - bRetVal = ConvertStringSidToSidW(wStringSid, sid); - HeapFree(GetProcessHeap(), 0, wStringSid); + ERR("Program requested unknown SDDL revision %d\n", SDRevision); + SetLastError(ERROR_UNKNOWN_REVISION); + return FALSE; } - return bRetVal; + + len = 0; + if (SecurityInformation & OWNER_SECURITY_INFORMATION) + if (!DumpOwner(SecurityDescriptor, NULL, &len)) + return FALSE; + if (SecurityInformation & GROUP_SECURITY_INFORMATION) + if (!DumpGroup(SecurityDescriptor, NULL, &len)) + return FALSE; + if (SecurityInformation & DACL_SECURITY_INFORMATION) + if (!DumpDacl(SecurityDescriptor, NULL, &len)) + return FALSE; + if (SecurityInformation & SACL_SECURITY_INFORMATION) + if (!DumpSacl(SecurityDescriptor, NULL, &len)) + return FALSE; + + wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR)); + if (wstr == NULL) + return FALSE; + + if (SecurityInformation & OWNER_SECURITY_INFORMATION) + if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) + return FALSE; + if (SecurityInformation & GROUP_SECURITY_INFORMATION) + if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) + return FALSE; + if (SecurityInformation & DACL_SECURITY_INFORMATION) + if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) + return FALSE; + if (SecurityInformation & SACL_SECURITY_INFORMATION) + if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) + return FALSE; + *wptr = 0; + + TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len); + *OutputString = wstr; + if (OutputLen) + *OutputLen = strlenW(*OutputString)+1; + return TRUE; } - -static const RECORD SidTable[] = +/****************************************************************************** + * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@] + * @implemented + */ +BOOL WINAPI +ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, + DWORD SDRevision, + SECURITY_INFORMATION Information, + LPSTR *OutputString, + PULONG OutputLen) { - { SDDL_ACCOUNT_OPERATORS, WinBuiltinAccountOperatorsSid }, - { SDDL_ALIAS_PREW2KCOMPACC, WinBuiltinPreWindows2000CompatibleAccessSid }, - { SDDL_ANONYMOUS, WinAnonymousSid }, - { SDDL_AUTHENTICATED_USERS, WinAuthenticatedUserSid }, - { SDDL_BUILTIN_ADMINISTRATORS, WinBuiltinAdministratorsSid }, - { SDDL_BUILTIN_GUESTS, WinBuiltinGuestsSid }, - { SDDL_BACKUP_OPERATORS, WinBuiltinBackupOperatorsSid }, - { SDDL_BUILTIN_USERS, WinBuiltinUsersSid }, - { SDDL_CERT_SERV_ADMINISTRATORS, WinAccountCertAdminsSid /* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ }, - { SDDL_CREATOR_GROUP, WinCreatorGroupSid }, - { SDDL_CREATOR_OWNER, WinCreatorOwnerSid }, - { SDDL_DOMAIN_ADMINISTRATORS, WinAccountDomainAdminsSid /* FIXME: DOMAIN_GROUP_RID_ADMINS */ }, - { SDDL_DOMAIN_COMPUTERS, WinAccountComputersSid /* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ }, - { SDDL_DOMAIN_DOMAIN_CONTROLLERS, WinAccountControllersSid /* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ }, - { SDDL_DOMAIN_GUESTS, WinAccountDomainGuestsSid /* FIXME: DOMAIN_GROUP_RID_GUESTS */ }, - { SDDL_DOMAIN_USERS, WinAccountDomainUsersSid /* FIXME: DOMAIN_GROUP_RID_USERS */ }, - { SDDL_ENTERPRISE_ADMINS, WinAccountEnterpriseAdminsSid /* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ }, - { SDDL_ENTERPRISE_DOMAIN_CONTROLLERS, WinEnterpriseControllersSid }, - { SDDL_EVERYONE, WinWorldSid }, - { SDDL_GROUP_POLICY_ADMINS, WinAccountPolicyAdminsSid /* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ }, - { SDDL_INTERACTIVE, WinInteractiveSid }, - { SDDL_LOCAL_ADMIN, WinAccountAdministratorSid /* FIXME: DOMAIN_USER_RID_ADMIN */ }, - { SDDL_LOCAL_GUEST, WinAccountGuestSid /* FIXME: DOMAIN_USER_RID_GUEST */ }, - { SDDL_LOCAL_SERVICE, WinLocalServiceSid }, - { SDDL_LOCAL_SYSTEM, WinLocalSystemSid }, - { SDDL_NETWORK, WinNetworkSid }, - { SDDL_NETWORK_CONFIGURATION_OPS, WinBuiltinNetworkConfigurationOperatorsSid }, - { SDDL_NETWORK_SERVICE, WinNetworkServiceSid }, - { SDDL_PRINTER_OPERATORS, WinBuiltinPrintOperatorsSid }, - { SDDL_PERSONAL_SELF, WinSelfSid }, - { SDDL_POWER_USERS, WinBuiltinPowerUsersSid }, - { SDDL_RAS_SERVERS, WinAccountRasAndIasServersSid /* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ }, - { SDDL_REMOTE_DESKTOP, WinBuiltinRemoteDesktopUsersSid }, - { SDDL_REPLICATOR, WinBuiltinReplicatorSid }, - { SDDL_RESTRICTED_CODE, WinRestrictedCodeSid }, - { SDDL_SCHEMA_ADMINISTRATORS, WinAccountSchemaAdminsSid /* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ }, - { SDDL_SERVER_OPERATORS, WinBuiltinSystemOperatorsSid }, - { SDDL_SERVICE, WinServiceSid }, - { NULL, 0 }, -}; + LPWSTR wstr; + ULONG len; + + if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len)) + { + int lenA; + + lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL); + *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA); + if (*OutputString == NULL) + { + LocalFree(wstr); + *OutputLen = 0; + return FALSE; + } + WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL); + LocalFree(wstr); + + if (OutputLen != NULL) + *OutputLen = lenA; + return TRUE; + } + else + { + *OutputString = NULL; + if (OutputLen) + *OutputLen = 0; + return FALSE; + } +} /* * @implemented @@ -1984,4 +1675,317 @@ lend: return ret; } +/* + * @implemented + */ +BOOL +WINAPI +ConvertStringSidToSidA(IN LPCSTR StringSid, + OUT PSID* sid) +{ + BOOL bRetVal = FALSE; + + TRACE("%s, %p\n", debugstr_a(StringSid), sid); + if (GetVersion() & 0x80000000) + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + else if (!StringSid || !sid) + SetLastError(ERROR_INVALID_PARAMETER); + else + { + UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0); + LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (wStringSid == NULL) + return FALSE; + MultiByteToWideChar(CP_ACP, 0, StringSid, - 1, wStringSid, len); + bRetVal = ConvertStringSidToSidW(wStringSid, sid); + HeapFree(GetProcessHeap(), 0, wStringSid); + } + return bRetVal; +} + +/* + * @implemented + */ +BOOL +WINAPI +ConvertSidToStringSidW(PSID Sid, + LPWSTR *StringSid) +{ + NTSTATUS Status; + UNICODE_STRING UnicodeString; + WCHAR FixedBuffer[64]; + + if (!RtlValidSid(Sid)) + { + SetLastError(ERROR_INVALID_SID); + return FALSE; + } + + UnicodeString.Length = 0; + UnicodeString.MaximumLength = sizeof(FixedBuffer); + UnicodeString.Buffer = FixedBuffer; + Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, FALSE); + if (STATUS_BUFFER_TOO_SMALL == Status) + { + Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, TRUE); + } + + if (!NT_SUCCESS(Status)) + { + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; + } + + *StringSid = LocalAlloc(LMEM_FIXED, UnicodeString.Length + sizeof(WCHAR)); + if (NULL == *StringSid) + { + if (UnicodeString.Buffer != FixedBuffer) + { + RtlFreeUnicodeString(&UnicodeString); + } + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + MoveMemory(*StringSid, UnicodeString.Buffer, UnicodeString.Length); + ZeroMemory((PCHAR) *StringSid + UnicodeString.Length, sizeof(WCHAR)); + if (UnicodeString.Buffer != FixedBuffer) + { + RtlFreeUnicodeString(&UnicodeString); + } + + return TRUE; +} + +/* + * @implemented + */ +BOOL +WINAPI +ConvertSidToStringSidA(PSID Sid, + LPSTR *StringSid) +{ + LPWSTR StringSidW; + int Len; + + if (!ConvertSidToStringSidW(Sid, &StringSidW)) + { + return FALSE; + } + + Len = WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, NULL, 0, NULL, NULL); + if (Len <= 0) + { + LocalFree(StringSidW); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + *StringSid = LocalAlloc(LMEM_FIXED, Len); + if (NULL == *StringSid) + { + LocalFree(StringSidW); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + if (!WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, *StringSid, Len, NULL, NULL)) + { + LocalFree(StringSid); + LocalFree(StringSidW); + return FALSE; + } + + LocalFree(StringSidW); + + return TRUE; +} + +/* + * @implemented + */ +BOOL WINAPI +AllocateLocallyUniqueId(PLUID Luid) +{ + NTSTATUS Status; + + Status = NtAllocateLocallyUniqueId (Luid); + if (!NT_SUCCESS (Status)) + { + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; + } + + return TRUE; +} + +/****************************************************************************** + * ComputeStringSidSize + */ +static DWORD ComputeStringSidSize(LPCWSTR StringSid) +{ + if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */ + { + int ctok = 0; + while (*StringSid) + { + if (*StringSid == '-') + ctok++; + StringSid++; + } + + if (ctok >= 3) + return GetSidLengthRequired(ctok - 2); + } + else /* String constant format - Only available in winxp and above */ + { + unsigned int i; + + for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) + if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2)) + return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount); + } + + return GetSidLengthRequired(0); +} + +/****************************************************************************** + * ParseStringSidToSid + */ +static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes) +{ + BOOL bret = FALSE; + SID* pisid=pSid; + + TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes); + if (!StringSid) + { + SetLastError(ERROR_INVALID_PARAMETER); + TRACE("StringSid is NULL, returning FALSE\n"); + return FALSE; + } + + while (*StringSid == ' ') + StringSid++; + + *cBytes = ComputeStringSidSize(StringSid); + if (!pisid) /* Simply compute the size */ + { + TRACE("only size requested, returning TRUE\n"); + return TRUE; + } + + if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */ + { + DWORD i = 0, identAuth; + DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD)); + + StringSid += 2; /* Advance to Revision */ + pisid->Revision = atoiW(StringSid); + + if (pisid->Revision != SDDL_REVISION) + { + TRACE("Revision %d is unknown\n", pisid->Revision); + goto lend; /* ERROR_INVALID_SID */ + } + if (csubauth == 0) + { + TRACE("SubAuthorityCount is 0\n"); + goto lend; /* ERROR_INVALID_SID */ + } + + pisid->SubAuthorityCount = csubauth; + + /* Advance to identifier authority */ + while (*StringSid && *StringSid != '-') + StringSid++; + if (*StringSid == '-') + StringSid++; + + /* MS' implementation can't handle values greater than 2^32 - 1, so + * we don't either; assume most significant bytes are always 0 + */ + pisid->IdentifierAuthority.Value[0] = 0; + pisid->IdentifierAuthority.Value[1] = 0; + identAuth = atoiW(StringSid); + pisid->IdentifierAuthority.Value[5] = identAuth & 0xff; + pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8; + pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16; + pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24; + + /* Advance to first sub authority */ + while (*StringSid && *StringSid != '-') + StringSid++; + if (*StringSid == '-') + StringSid++; + + while (*StringSid) + { + pisid->SubAuthority[i++] = atoiW(StringSid); + + while (*StringSid && *StringSid != '-') + StringSid++; + if (*StringSid == '-') + StringSid++; + } + + if (i != pisid->SubAuthorityCount) + goto lend; /* ERROR_INVALID_SID */ + + bret = TRUE; + } + else /* String constant format - Only available in winxp and above */ + { + unsigned int i; + pisid->Revision = SDDL_REVISION; + + for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) + if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2)) + { + DWORD j; + pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount; + pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority; + for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++) + pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j]; + bret = TRUE; + } + + if (!bret) + FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2)); + } + +lend: + if (!bret) + SetLastError(ERROR_INVALID_SID); + + TRACE("returning %s\n", bret ? "TRUE" : "FALSE"); + return bret; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +GetWindowsAccountDomainSid(IN PSID pSid, + OUT PSID ppDomainSid, + IN OUT DWORD* cbSid) +{ + UNIMPLEMENTED; + return FALSE; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +EqualDomainSid(IN PSID pSid1, + IN PSID pSid2, + OUT BOOL* pfEqual) +{ + UNIMPLEMENTED; + return FALSE; +} + /* EOF */ diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 14c16741d8d..d8915e789a3 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -256,11 +256,11 @@ check Wine current souces first as it may already be fixed. reactos/lib/3rdparty/strmbase # Synced to Wine-1.7.27 advapi32 - + reactos/dll/win32/advapi32/wine/cred.c # Synced to Wine-1.7.27 reactos/dll/win32/advapi32/wine/crypt.c # Synced to Wine-1.7.27 reactos/dll/win32/advapi32/wine/crypt_des.c # Synced to Wine-1.7.27 reactos/dll/win32/advapi32/wine/crypt_lmhash.c # Synced to Wine-1.7.27 - reactos/dll/win32/advapi32/sec/cred.c # Synced to Wine-1.7.27 - reactos/dll/win32/advapi32/sec/sid.c # Out of Sync + reactos/dll/win32/advapi32/wine/security.c # Out of Sync gdi32 - reactos/dll/win32/gdi32/objects/linedda.c # Synced at 20090410 diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h index b6901db8452..778bf6d8073 100644 --- a/ntoskrnl/include/internal/io.h +++ b/ntoskrnl/include/internal/io.h @@ -1277,6 +1277,8 @@ extern ULONG IopNumTriageDumpDataBlocks; extern PVOID IopTriageDumpDataBlocks[64]; extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList; extern PDRIVER_OBJECT IopRootDriverObject; +extern KSPIN_LOCK IopDeviceRelationsSpinLock; +extern LIST_ENTRY IopDeviceRelationsRequestList; // // Inlined Functions diff --git a/ntoskrnl/include/internal/tag.h b/ntoskrnl/include/internal/tag.h index 1507685b44b..88181397596 100644 --- a/ntoskrnl/include/internal/tag.h +++ b/ntoskrnl/include/internal/tag.h @@ -81,6 +81,9 @@ /* formerly located in io/mdl.c */ #define TAG_MDL ' LDM' +/* formerly located in io/pnpmgr.c */ +#define TAG_IO_DEVNODE 'donD' + /* formerly located in io/pnpnotify.c */ #define TAG_PNP_NOTIFY 'NPnP' diff --git a/ntoskrnl/io/iomgr/driver.c b/ntoskrnl/io/iomgr/driver.c index fbe571b44f9..9f54c174776 100644 --- a/ntoskrnl/io/iomgr/driver.c +++ b/ntoskrnl/io/iomgr/driver.c @@ -16,6 +16,8 @@ /* GLOBALS ********************************************************************/ +ERESOURCE IopDriverLoadResource; + LIST_ENTRY DriverReinitListHead; KSPIN_LOCK DriverReinitListLock; PLIST_ENTRY DriverReinitTailEntry; @@ -113,6 +115,7 @@ IopGetDriverObject( DPRINT("IopGetDriverObject(%p '%wZ' %x)\n", DriverObject, ServiceName, FileSystem); + ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource)); *DriverObject = NULL; /* Create ModuleName string */ @@ -239,39 +242,44 @@ IopNormalizeImagePath( PUNICODE_STRING ImagePath, _In_ PUNICODE_STRING ServiceName) { + UNICODE_STRING SystemRootString = RTL_CONSTANT_STRING(L"\\SystemRoot\\"); + UNICODE_STRING DriversPathString = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\drivers\\"); + UNICODE_STRING DotSysString = RTL_CONSTANT_STRING(L".sys"); UNICODE_STRING InputImagePath; DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName); - RtlCopyMemory(&InputImagePath, - ImagePath, - sizeof(UNICODE_STRING)); - + InputImagePath = *ImagePath; if (InputImagePath.Length == 0) { ImagePath->Length = 0; - ImagePath->MaximumLength = - (33 * sizeof(WCHAR)) + ServiceName->Length + sizeof(UNICODE_NULL); - ImagePath->Buffer = ExAllocatePool(NonPagedPool, - ImagePath->MaximumLength); + ImagePath->MaximumLength = DriversPathString.Length + + ServiceName->Length + + DotSysString.Length + + sizeof(UNICODE_NULL); + ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool, + ImagePath->MaximumLength, + TAG_IO); if (ImagePath->Buffer == NULL) return STATUS_NO_MEMORY; - RtlAppendUnicodeToString(ImagePath, L"\\SystemRoot\\system32\\drivers\\"); + RtlCopyUnicodeString(ImagePath, &DriversPathString); RtlAppendUnicodeStringToString(ImagePath, ServiceName); - RtlAppendUnicodeToString(ImagePath, L".sys"); + RtlAppendUnicodeStringToString(ImagePath, &DotSysString); } else if (InputImagePath.Buffer[0] != L'\\') { ImagePath->Length = 0; - ImagePath->MaximumLength = - 12 * sizeof(WCHAR) + InputImagePath.Length + sizeof(UNICODE_NULL); - ImagePath->Buffer = ExAllocatePool(NonPagedPool, - ImagePath->MaximumLength); + ImagePath->MaximumLength = SystemRootString.Length + + InputImagePath.Length + + sizeof(UNICODE_NULL); + ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool, + ImagePath->MaximumLength, + TAG_IO); if (ImagePath->Buffer == NULL) return STATUS_NO_MEMORY; - RtlAppendUnicodeToString(ImagePath, L"\\SystemRoot\\"); + RtlCopyUnicodeString(ImagePath, &SystemRootString); RtlAppendUnicodeStringToString(ImagePath, &InputImagePath); /* Free caller's string */ @@ -308,6 +316,7 @@ IopLoadServiceModule( HANDLE CCSKey, ServiceKey; PVOID BaseAddress; + ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource)); ASSERT(ServiceName->Length); DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject); @@ -319,8 +328,7 @@ IopLoadServiceModule( ServiceStart = 0; /* IopNormalizeImagePath will do all of the work for us if we give it an empty string */ - ServiceImagePath.Length = ServiceImagePath.MaximumLength = 0; - ServiceImagePath.Buffer = NULL; + RtlInitEmptyUnicodeString(&ServiceImagePath, NULL, 0); } else { @@ -563,6 +571,8 @@ IopAttachFilterDriversCallback( ServiceName.MaximumLength = ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR); + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE); Status = IopGetDriverObject(&DriverObject, &ServiceName, FALSE); @@ -571,7 +581,11 @@ IopAttachFilterDriversCallback( /* Load and initialize the filter driver */ Status = IopLoadServiceModule(&ServiceName, &ModuleObject); if (!NT_SUCCESS(Status)) + { + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); return Status; + } Status = IopInitializeDriverModule(DeviceNode, ModuleObject, @@ -579,9 +593,16 @@ IopAttachFilterDriversCallback( FALSE, &DriverObject); if (!NT_SUCCESS(Status)) + { + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); return Status; + } } + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); + Status = IopInitializeDevice(DeviceNode, DriverObject); /* Remove extra reference */ @@ -926,7 +947,6 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry) if (!NT_SUCCESS(Status)) { - IopFreeDeviceNode(DeviceNode); return Status; } @@ -990,7 +1010,6 @@ IopInitializeBootDrivers(VOID) if (!NT_SUCCESS(Status)) { /* Fail */ - IopFreeDeviceNode(DeviceNode); return; } @@ -999,7 +1018,6 @@ IopInitializeBootDrivers(VOID) if (!NT_SUCCESS(Status)) { /* Fail */ - IopFreeDeviceNode(DeviceNode); ObDereferenceObject(DriverObject); return; } @@ -1009,7 +1027,6 @@ IopInitializeBootDrivers(VOID) if (!NT_SUCCESS(Status)) { /* Fail */ - IopFreeDeviceNode(DeviceNode); ObDereferenceObject(DriverObject); return; } @@ -1971,6 +1988,8 @@ IopLoadUnloadDriver( DPRINT("FullImagePath: '%wZ'\n", &ImagePath); DPRINT("Type: %lx\n", Type); + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE); /* * Get existing DriverObject pointer (in case the driver * has already been loaded and initialized). @@ -1990,6 +2009,8 @@ IopLoadUnloadDriver( if (!NT_SUCCESS(Status)) { DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status); + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); return Status; } @@ -2000,6 +2021,8 @@ IopLoadUnloadDriver( if (!NT_SUCCESS(Status)) { DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status); + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); MmUnloadSystemImage(ModuleObject); return Status; } @@ -2015,17 +2038,24 @@ IopLoadUnloadDriver( if (!NT_SUCCESS(Status)) { DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status); + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); MmUnloadSystemImage(ModuleObject); - IopFreeDeviceNode(DeviceNode); return Status; } + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); + /* Initialize and start device */ IopInitializeDevice(DeviceNode, *DriverObject); Status = IopStartDevice(DeviceNode); } else { + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); + DPRINT("DriverObject already exist in ObjectManager\n"); Status = STATUS_IMAGE_ALREADY_LOADED; diff --git a/ntoskrnl/io/iomgr/iomgr.c b/ntoskrnl/io/iomgr/iomgr.c index b1d4a136731..b61e8e4fce1 100644 --- a/ntoskrnl/io/iomgr/iomgr.c +++ b/ntoskrnl/io/iomgr/iomgr.c @@ -54,6 +54,7 @@ extern KSPIN_LOCK ShutdownListLock; extern POBJECT_TYPE IoAdapterObjectType; extern ERESOURCE IopDatabaseResource; ERESOURCE IopSecurityResource; +extern ERESOURCE IopDriverLoadResource; extern KGUARDED_MUTEX PnpNotifyListLock; extern LIST_ENTRY IopDiskFileSystemQueueHead; extern LIST_ENTRY IopCdRomFileSystemQueueHead; @@ -476,8 +477,9 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock) IopInitLookasideLists(); /* Initialize all locks and lists */ - ExInitializeResource(&IopDatabaseResource); - ExInitializeResource(&IopSecurityResource); + ExInitializeResourceLite(&IopDatabaseResource); + ExInitializeResourceLite(&IopSecurityResource); + ExInitializeResourceLite(&IopDriverLoadResource); KeInitializeGuardedMutex(&PnpNotifyListLock); InitializeListHead(&IopDiskFileSystemQueueHead); InitializeListHead(&IopCdRomFileSystemQueueHead); diff --git a/ntoskrnl/io/iomgr/irp.c b/ntoskrnl/io/iomgr/irp.c index f768c7649d2..940c3e3461b 100644 --- a/ntoskrnl/io/iomgr/irp.c +++ b/ntoskrnl/io/iomgr/irp.c @@ -324,17 +324,21 @@ IopCompleteRequest(IN PKAPC Apc, Key = FileObject->CompletionContext->Key; } - /* Use SEH to make sure we don't write somewhere invalid */ - _SEH2_TRY + /* Check for UserIos */ + if (Irp->UserIosb != NULL) { - /* Save the IOSB Information */ - *Irp->UserIosb = Irp->IoStatus; + /* Use SEH to make sure we don't write somewhere invalid */ + _SEH2_TRY + { + /* Save the IOSB Information */ + *Irp->UserIosb = Irp->IoStatus; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Ignore any error */ + } + _SEH2_END; } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Ignore any error */ - } - _SEH2_END; /* Check if we have an event or a file object */ if (Irp->UserEvent) diff --git a/ntoskrnl/io/pnpmgr/pnpinit.c b/ntoskrnl/io/pnpmgr/pnpinit.c index c51e326229a..504565f978a 100644 --- a/ntoskrnl/io/pnpmgr/pnpinit.c +++ b/ntoskrnl/io/pnpmgr/pnpinit.c @@ -385,6 +385,8 @@ IopInitializePlugPlayServices(VOID) /* Initialize locks and such */ KeInitializeSpinLock(&IopDeviceTreeLock); + KeInitializeSpinLock(&IopDeviceRelationsSpinLock); + InitializeListHead(&IopDeviceRelationsRequestList); /* Get the default interface */ PnpDefaultInterfaceType = IopDetermineDefaultInterfaceType(); diff --git a/ntoskrnl/io/pnpmgr/pnpmgr.c b/ntoskrnl/io/pnpmgr/pnpmgr.c index 09284d62a44..3fe5e6e2957 100644 --- a/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -21,6 +21,7 @@ ERESOURCE PpRegistryDeviceResource; KGUARDED_MUTEX PpDeviceReferenceTableLock; RTL_AVL_TABLE PpDeviceReferenceTable; +extern ERESOURCE IopDriverLoadResource; extern ULONG ExpInitializationPhase; extern BOOLEAN ExpInTextModeSetup; extern BOOLEAN PnpSystemInit; @@ -29,12 +30,16 @@ extern BOOLEAN PnpSystemInit; PDRIVER_OBJECT IopRootDriverObject; PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList = NULL; +LIST_ENTRY IopDeviceRelationsRequestList; +WORK_QUEUE_ITEM IopDeviceRelationsWorkItem; +BOOLEAN IopDeviceRelationsRequestInProgress; +KSPIN_LOCK IopDeviceRelationsSpinLock; typedef struct _INVALIDATE_DEVICE_RELATION_DATA { + LIST_ENTRY RequestListEntry; PDEVICE_OBJECT DeviceObject; DEVICE_RELATION_TYPE Type; - PIO_WORKITEM WorkItem; } INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA; /* FUNCTIONS *****************************************************************/ @@ -889,20 +894,34 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode, return Status; } -static VOID NTAPI -IopAsynchronousInvalidateDeviceRelations( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID InvalidateContext) +static +VOID +NTAPI +IopDeviceRelationsWorker( + _In_ PVOID Context) { - PINVALIDATE_DEVICE_RELATION_DATA Data = InvalidateContext; + PLIST_ENTRY ListEntry; + PINVALIDATE_DEVICE_RELATION_DATA Data; + KIRQL OldIrql; - IoSynchronousInvalidateDeviceRelations( - Data->DeviceObject, - Data->Type); + KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql); + while (!IsListEmpty(&IopDeviceRelationsRequestList)) + { + ListEntry = RemoveHeadList(&IopDeviceRelationsRequestList); + KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql); + Data = CONTAINING_RECORD(ListEntry, + INVALIDATE_DEVICE_RELATION_DATA, + RequestListEntry); - ObDereferenceObject(Data->DeviceObject); - IoFreeWorkItem(Data->WorkItem); - ExFreePool(Data); + IoSynchronousInvalidateDeviceRelations(Data->DeviceObject, + Data->Type); + + ObDereferenceObject(Data->DeviceObject); + ExFreePool(Data); + KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql); + } + IopDeviceRelationsRequestInProgress = FALSE; + KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql); } NTSTATUS @@ -1024,7 +1043,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, DPRINT("ParentNode 0x%p PhysicalDeviceObject 0x%p ServiceName %wZ\n", ParentNode, PhysicalDeviceObject, ServiceName); - Node = (PDEVICE_NODE)ExAllocatePool(NonPagedPool, sizeof(DEVICE_NODE)); + Node = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE), TAG_IO_DEVNODE); if (!Node) { return STATUS_INSUFFICIENT_RESOURCES; @@ -1044,7 +1063,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, FullServiceName.Buffer = ExAllocatePool(PagedPool, FullServiceName.MaximumLength); if (!FullServiceName.Buffer) { - ExFreePool(Node); + ExFreePoolWithTag(Node, TAG_IO_DEVNODE); return STATUS_INSUFFICIENT_RESOURCES; } @@ -1055,7 +1074,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, if (!NT_SUCCESS(Status)) { DPRINT1("PnpRootCreateDevice() failed with status 0x%08X\n", Status); - ExFreePool(Node); + ExFreePoolWithTag(Node, TAG_IO_DEVNODE); return Status; } @@ -1064,7 +1083,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, if (!NT_SUCCESS(Status)) { ZwClose(InstanceHandle); - ExFreePool(Node); + ExFreePoolWithTag(Node, TAG_IO_DEVNODE); ExFreePool(FullServiceName.Buffer); return Status; } @@ -1073,7 +1092,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, if (!Node->ServiceName.Buffer) { ZwClose(InstanceHandle); - ExFreePool(Node); + ExFreePoolWithTag(Node, TAG_IO_DEVNODE); ExFreePool(FullServiceName.Buffer); return Status; } @@ -1122,7 +1141,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, if (!NT_SUCCESS(Status)) { - ExFreePool(Node); + ExFreePoolWithTag(Node, TAG_IO_DEVNODE); return Status; } @@ -1225,7 +1244,8 @@ IopFreeDeviceNode(PDEVICE_NODE DeviceNode) ExFreePool(DeviceNode->BootResources); } - ExFreePool(DeviceNode); + ((PEXTENDED_DEVOBJ_EXTENSION)DeviceNode->PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode = NULL; + ExFreePoolWithTag(DeviceNode, TAG_IO_DEVNODE); return STATUS_SUCCESS; } @@ -2560,7 +2580,7 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode, DPRINT("IopActionInitChildServices(%p, %p)\n", DeviceNode, Context); - ParentDeviceNode = (PDEVICE_NODE)Context; + ParentDeviceNode = Context; /* * We are called for the parent too, but we don't need to do special @@ -2610,6 +2630,8 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode, PLDR_DATA_TABLE_ENTRY ModuleObject; PDRIVER_OBJECT DriverObject; + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE); /* Get existing DriverObject pointer (in case the driver has already been loaded and initialized) */ Status = IopGetDriverObject( @@ -2641,6 +2663,8 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode, if (!BootDrivers) DeviceNode->Problem = CM_PROB_DRIVER_FAILED_LOAD; } } + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); /* Driver is loaded and initialized at this point */ if (NT_SUCCESS(Status)) @@ -3545,7 +3569,7 @@ PipAllocateDeviceNode(IN PDEVICE_OBJECT PhysicalDeviceObject) PAGED_CODE(); /* Allocate it */ - DeviceNode = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE), 'donD'); + DeviceNode = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE), TAG_IO_DEVNODE); if (!DeviceNode) return DeviceNode; /* Statistics */ @@ -4664,29 +4688,32 @@ IoInvalidateDeviceRelations( IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type) { - PIO_WORKITEM WorkItem; PINVALIDATE_DEVICE_RELATION_DATA Data; + KIRQL OldIrql; Data = ExAllocatePool(NonPagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA)); if (!Data) return; - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) - { - ExFreePool(Data); - return; - } ObReferenceObject(DeviceObject); Data->DeviceObject = DeviceObject; Data->Type = Type; - Data->WorkItem = WorkItem; - IoQueueWorkItem( - WorkItem, - IopAsynchronousInvalidateDeviceRelations, - DelayedWorkQueue, - Data); + KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql); + InsertTailList(&IopDeviceRelationsRequestList, &Data->RequestListEntry); + if (IopDeviceRelationsRequestInProgress) + { + KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql); + return; + } + IopDeviceRelationsRequestInProgress = TRUE; + KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql); + + ExInitializeWorkItem(&IopDeviceRelationsWorkItem, + IopDeviceRelationsWorker, + NULL); + ExQueueWorkItem(&IopDeviceRelationsWorkItem, + DelayedWorkQueue); } /* diff --git a/win32ss/gdi/dib/dib.c b/win32ss/gdi/dib/dib.c index 516b4bd3ae9..21a91078cf6 100644 --- a/win32ss/gdi/dib/dib.c +++ b/win32ss/gdi/dib/dib.c @@ -47,7 +47,7 @@ DIB_FUNCTIONS DibFunctionsForBitmapFormat[] = { DIB_16BPP_PutPixel, DIB_16BPP_GetPixel, DIB_16BPP_HLine, DIB_16BPP_VLine, DIB_16BPP_BitBlt, DIB_16BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt, - DIB_16BPP_TransparentBlt, DIB_16BPP_ColorFill, DIB_XXBPP_AlphaBlend + DIB_16BPP_TransparentBlt, DIB_16BPP_ColorFill, DIB_16BPP_AlphaBlend }, /* BMF_24BPP */ { diff --git a/win32ss/gdi/dib/dib.h b/win32ss/gdi/dib/dib.h index 440162a744f..685cd00cc58 100644 --- a/win32ss/gdi/dib/dib.h +++ b/win32ss/gdi/dib/dib.h @@ -101,6 +101,7 @@ BOOLEAN DIB_16BPP_BitBlt(PBLTINFO); BOOLEAN DIB_16BPP_BitBltSrcCopy(PBLTINFO); BOOLEAN DIB_16BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG); BOOLEAN DIB_16BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); +BOOLEAN DIB_16BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); VOID DIB_24BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG); ULONG DIB_24BPP_GetPixel(SURFOBJ*,LONG,LONG); diff --git a/win32ss/gdi/dib/dib16bpp.c b/win32ss/gdi/dib/dib16bpp.c index e4f415367a9..713529533f0 100644 --- a/win32ss/gdi/dib/dib16bpp.c +++ b/win32ss/gdi/dib/dib16bpp.c @@ -525,4 +525,135 @@ DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, return TRUE; } +typedef union +{ + ULONG ul; + struct + { + UCHAR red; + UCHAR green; + UCHAR blue; + UCHAR alpha; + } col; +} NICEPIXEL32; + +typedef union +{ + USHORT us; + struct + { + USHORT red :5; + USHORT green :6; + USHORT blue :5; + } col; +} NICEPIXEL16; + +static __inline UCHAR +Clamp6(ULONG val) +{ + return (val > 63) ? 63 : (UCHAR)val; +} + +static __inline UCHAR +Clamp5(ULONG val) +{ + return (val > 31) ? 31 : (UCHAR)val; +} + +BOOLEAN +DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, + RECTL* SourceRect, CLIPOBJ* ClipRegion, + XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj) +{ + INT DstX, DstY, SrcX, SrcY; + BLENDFUNCTION BlendFunc; + NICEPIXEL32 SrcPixel32; + NICEPIXEL16 DstPixel16; + UCHAR Alpha, Alpha6, Alpha5; + EXLATEOBJ* pexlo; + EXLATEOBJ exloSrcRGB; + + DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", + SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, + DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); + + BlendFunc = BlendObj->BlendFunction; + if (BlendFunc.BlendOp != AC_SRC_OVER) + { + DPRINT1("BlendOp != AC_SRC_OVER\n"); + return FALSE; + } + if (BlendFunc.BlendFlags != 0) + { + DPRINT1("BlendFlags != 0\n"); + return FALSE; + } + if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0) + { + DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat); + return FALSE; + } + if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 && + (BitsPerFormat(Source->iBitmapFormat) != 32)) + { + DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n"); + return FALSE; + } + + if (!ColorTranslation) + { + DPRINT1("ColorTranslation must not be NULL!\n"); + return FALSE; + } + + pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo); + EXLATEOBJ_vInitialize(&exloSrcRGB, pexlo->ppalSrc, &gpalRGB, 0, 0, 0); + + SrcY = SourceRect->top; + DstY = DestRect->top; + while ( DstY < DestRect->bottom ) + { + SrcX = SourceRect->left; + DstX = DestRect->left; + while(DstX < DestRect->right) + { + SrcPixel32.ul = DIB_GetSource(Source, SrcX, SrcY, &exloSrcRGB.xlo); + SrcPixel32.col.red = (SrcPixel32.col.red * BlendFunc.SourceConstantAlpha) / 255; + SrcPixel32.col.green = (SrcPixel32.col.green * BlendFunc.SourceConstantAlpha) / 255; + SrcPixel32.col.blue = (SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha) / 255; + + Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? + (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha) / 255 : + BlendFunc.SourceConstantAlpha; + + Alpha6 = Alpha >> 2; + Alpha5 = Alpha >> 3; + + DstPixel16.us = DIB_16BPP_GetPixel(Dest, DstX, DstY) & 0xFFFF; + /* Perform bit loss */ + SrcPixel32.col.red >>= 3; + SrcPixel32.col.green >>= 2; + SrcPixel32.col.blue >>= 3; + + /* Do the blend in the right bit depth */ + DstPixel16.col.red = Clamp5((DstPixel16.col.red * (31 - Alpha5)) / 31 + SrcPixel32.col.red); + DstPixel16.col.green = Clamp6((DstPixel16.col.green * (63 - Alpha6)) / 63 + SrcPixel32.col.green); + DstPixel16.col.blue = Clamp5((DstPixel16.col.blue * (31 - Alpha5)) / 31 + SrcPixel32.col.blue); + + DIB_16BPP_PutPixel(Dest, DstX, DstY, DstPixel16.us); + + DstX++; + SrcX = SourceRect->left + ((DstX-DestRect->left)*(SourceRect->right - SourceRect->left)) + /(DestRect->right-DestRect->left); + } + DstY++; + SrcY = SourceRect->top + ((DstY-DestRect->top)*(SourceRect->bottom - SourceRect->top)) + /(DestRect->bottom-DestRect->top); + } + + EXLATEOBJ_vCleanup(&exloSrcRGB); + + return TRUE; +} + /* EOF */ diff --git a/win32ss/gdi/ntgdi/bitmaps.c b/win32ss/gdi/ntgdi/bitmaps.c index ec44b9f8b9a..430622bf014 100644 --- a/win32ss/gdi/ntgdi/bitmaps.c +++ b/win32ss/gdi/ntgdi/bitmaps.c @@ -249,6 +249,7 @@ IntCreateCompatibleBitmap( /* Set flags */ psurf->flags = API_BITMAP; psurf->hdc = NULL; // FIXME: + psurf->SurfObj.hdev = (HDEV)Dc->ppdev; SURFACE_ShareUnlockSurface(psurf); } else @@ -277,6 +278,7 @@ IntCreateCompatibleBitmap( /* Set flags */ psurfBmp->flags = API_BITMAP; psurfBmp->hdc = NULL; // FIXME: + psurf->SurfObj.hdev = (HDEV)Dc->ppdev; SURFACE_ShareUnlockSurface(psurfBmp); } else if (Count == sizeof(DIBSECTION)) diff --git a/win32ss/gdi/ntgdi/dcobjs.c b/win32ss/gdi/ntgdi/dcobjs.c index 72b34c25a85..6d034aa9d28 100644 --- a/win32ss/gdi/ntgdi/dcobjs.c +++ b/win32ss/gdi/ntgdi/dcobjs.c @@ -330,6 +330,10 @@ DC_bIsBitmapCompatible(PDC pdc, PSURFACE psurf) /* DIB sections are always compatible */ if (psurf->hSecure != NULL) return TRUE; + /* See if this is the same PDEV */ + if (psurf->SurfObj.hdev == (HDEV)pdc->ppdev) + return TRUE; + /* Get the bit depth of the bitmap */ cBitsPixel = gajBitsPerFormat[psurf->SurfObj.iBitmapFormat]; diff --git a/win32ss/user/ntuser/hook.c b/win32ss/user/ntuser/hook.c index 88d922af1fc..33c748ad30d 100644 --- a/win32ss/user/ntuser/hook.c +++ b/win32ss/user/ntuser/hook.c @@ -1294,12 +1294,14 @@ IntUnhookWindowsHook(int HookId, HOOKPROC pfnFilterProc) { Hook = CONTAINING_RECORD(pElement, HOOK, Chain); + /* Get the next element now, we might free the hook in what follows */ + pElement = Hook->Chain.Flink; + if (Hook->Proc == pfnFilterProc) { if (Hook->head.pti == pti) { IntRemoveHook(Hook); - UserDereferenceObject(Hook); return TRUE; } else @@ -1308,8 +1310,6 @@ IntUnhookWindowsHook(int HookId, HOOKPROC pfnFilterProc) return FALSE; } } - - pElement = Hook->Chain.Flink; } } return FALSE; diff --git a/win32ss/user/user32/windows/message.c b/win32ss/user/user32/windows/message.c index 8c37e37ba4b..04eea6a17ca 100644 --- a/win32ss/user/user32/windows/message.c +++ b/win32ss/user/user32/windows/message.c @@ -2648,6 +2648,7 @@ SendMessageTimeoutA( dsm.uFlags = fuFlags; dsm.uTimeout = uTimeout; + dsm.Result = 0; AnsiMsg.hwnd = hWnd; AnsiMsg.message = Msg; @@ -2709,6 +2710,7 @@ SendMessageTimeoutW( dsm.uFlags = fuFlags; dsm.uTimeout = uTimeout; + dsm.Result = 0; Result = NtUserMessageCall( hWnd, Msg,