diff --git a/base/applications/cmdutils/doskey/doskey.c b/base/applications/cmdutils/doskey/doskey.c index 5a73dc07f94..b22cdd883ed 100644 --- a/base/applications/cmdutils/doskey/doskey.c +++ b/base/applications/cmdutils/doskey/doskey.c @@ -72,19 +72,19 @@ static INT SetMacro(LPWSTR definition) temp = *nameend; *nameend = L'\0'; /* Don't allow spaces in the name, since such a macro would be unusable */ - if (!wcschr(name, L' ') && AddConsoleAlias(name, text, pszExeName)) + if (!wcschr(name, L' ') && AddConsoleAliasW(name, text, pszExeName)) return 0; *nameend = temp; } - LoadString(GetModuleHandle(NULL), IDS_INVALID_MACRO_DEF, szStringBuf, MAX_STRING); + LoadStringW(GetModuleHandle(NULL), IDS_INVALID_MACRO_DEF, szStringBuf, MAX_STRING); wprintf(szStringBuf, definition); return 1; } static VOID PrintMacros(LPWSTR pszExeName, LPWSTR Indent) { - DWORD Length = GetConsoleAliasesLength(pszExeName); + DWORD Length = GetConsoleAliasesLengthW(pszExeName); PBYTE AliasBuf; WCHAR *Alias; WCHAR *AliasEnd; @@ -96,7 +96,7 @@ static VOID PrintMacros(LPWSTR pszExeName, LPWSTR Indent) Alias = (WCHAR *)AliasBuf; AliasEnd = (WCHAR *)&AliasBuf[Length]; - if (GetConsoleAliases(Alias, Length * sizeof(BYTE), pszExeName)) + if (GetConsoleAliasesW(Alias, Length * sizeof(BYTE), pszExeName)) for (; Alias < AliasEnd; Alias += wcslen(Alias) + 1) wprintf(L"%s%s\n", Indent, Alias); @@ -117,7 +117,7 @@ static VOID PrintAllMacros(VOID) ExeName = (WCHAR *)ExeNameBuf; ExeNameEnd = (WCHAR *)&ExeNameBuf[Length]; - if (GetConsoleAliasExes(ExeName, Length * sizeof(BYTE))) + if (GetConsoleAliasExesW(ExeName, Length * sizeof(BYTE))) { for (; ExeName < ExeNameEnd; ExeName += wcslen(ExeName) + 1) { @@ -199,7 +199,7 @@ wmain(VOID) /* Get the full command line using GetCommandLine(). We can't just use argv, * because then a parameter like "gotoroot=cd \" wouldn't be passed completely. */ - pArgEnd = GetCommandLine(); + pArgEnd = GetCommandLineW(); hKernel32 = LoadLibraryW(L"kernel32.dll"); /* Get function pointers */ @@ -222,7 +222,7 @@ wmain(VOID) if (!wcscmp(pArgStart, L"/?")) { - LoadString(GetModuleHandle(NULL), IDS_HELP, szStringBuf, MAX_STRING); + LoadStringW(GetModuleHandle(NULL), IDS_HELP, szStringBuf, MAX_STRING); wprintf(szStringBuf); break; } diff --git a/base/services/umpnpmgr/umpnpmgr.c b/base/services/umpnpmgr/umpnpmgr.c index 2a5697315d9..6acefa85f9f 100644 --- a/base/services/umpnpmgr/umpnpmgr.c +++ b/base/services/umpnpmgr/umpnpmgr.c @@ -3025,7 +3025,7 @@ IsConsoleBoot(VOID) if (rc != ERROR_SUCCESS) goto cleanup; - /* Check for CMDCONS in SystemStartOptions */ + /* Check for CONSOLE switch in SystemStartOptions */ CurrentOption = SystemStartOptions; while (CurrentOption) { diff --git a/base/system/diskpart/diskpart.c b/base/system/diskpart/diskpart.c index a22c967d82b..b44ad600b5e 100644 --- a/base/system/diskpart/diskpart.c +++ b/base/system/diskpart/diskpart.c @@ -31,7 +31,7 @@ ShowHeader(VOID) DWORD comp_size = MAX_STRING_SIZE; /* Get the name of the computer for us and change the value of comp_name */ - GetComputerName(szComputerName, &comp_size); + GetComputerNameW(szComputerName, &comp_size); /* TODO: Remove this section of code when program becomes stable enough for production use. */ wprintf(L"\n*WARNING*: This program is incomplete and may not work properly.\n"); diff --git a/base/system/services/driver.c b/base/system/services/driver.c index 236657d408f..b8023dcedb9 100644 --- a/base/system/services/driver.c +++ b/base/system/services/driver.c @@ -16,6 +16,50 @@ /* FUNCTIONS ****************************************************************/ +static DWORD EnablePrivilege(LPCWSTR lpszPrivilegeName, BOOL bEnablePrivilege) +{ + DWORD dwRet = ERROR_SUCCESS; + HANDLE hToken = NULL; + + if (OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES, + &hToken)) + { + TOKEN_PRIVILEGES tp; + + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = (bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0); + + if (LookupPrivilegeValueW(NULL, + lpszPrivilegeName, + &tp.Privileges[0].Luid)) + { + if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL)) + { + if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) + dwRet = ERROR_NOT_ALL_ASSIGNED; + } + else + { + dwRet = GetLastError(); + } + } + else + { + dwRet = GetLastError(); + } + + CloseHandle(hToken); + } + else + { + dwRet = GetLastError(); + } + + return dwRet; +} + + DWORD ScmLoadDriver(PSERVICE lpService) { @@ -40,18 +84,28 @@ ScmLoadDriver(PSERVICE lpService) RtlInitUnicodeString(&DriverPath, pszDriverPath); - /* FIXME: Acquire privilege */ - DPRINT(" Path: %wZ\n", &DriverPath); + + /* Acquire driver-loading privilege */ + dwError = EnablePrivilege(SE_LOAD_DRIVER_NAME, TRUE); + if (dwError != ERROR_SUCCESS) + { + /* We encountered a failure, exit properly */ + DPRINT1("SERVICES: Cannot acquire driver-loading privilege, error = %lu\n", dwError); + goto done; + } + Status = NtLoadDriver(&DriverPath); - /* FIXME: Release privilege */ + /* Release driver-loading privilege */ + EnablePrivilege(SE_LOAD_DRIVER_NAME, FALSE); if (!NT_SUCCESS(Status)) { dwError = RtlNtStatusToDosError(Status); } +done: HeapFree(GetProcessHeap(), 0, pszDriverPath); return dwError; @@ -82,17 +136,26 @@ ScmUnloadDriver(PSERVICE lpService) RtlInitUnicodeString(&DriverPath, pszDriverPath); - /* FIXME: Acquire privilege */ + /* Acquire driver-unloading privilege */ + dwError = EnablePrivilege(SE_LOAD_DRIVER_NAME, TRUE); + if (dwError != ERROR_SUCCESS) + { + /* We encountered a failure, exit properly */ + DPRINT1("SERVICES: Cannot acquire driver-unloading privilege, error = %lu\n", dwError); + goto done; + } Status = NtUnloadDriver(&DriverPath); - /* FIXME: Release privilege */ + /* Release driver-unloading privilege */ + EnablePrivilege(SE_LOAD_DRIVER_NAME, FALSE); if (!NT_SUCCESS(Status)) { dwError = RtlNtStatusToDosError(Status); } +done: HeapFree(GetProcessHeap(), 0, pszDriverPath); return dwError; diff --git a/base/system/services/services.c b/base/system/services/services.c index ca7401e5fc0..982e0fbdeb3 100644 --- a/base/system/services/services.c +++ b/base/system/services/services.c @@ -327,28 +327,6 @@ StartScmNamedPipeThreadListener(VOID) } -VOID FASTCALL -AcquireLoadDriverPrivilege(VOID) -{ - HANDLE hToken; - TOKEN_PRIVILEGES tkp; - - /* Get a token for this process */ - if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) - { - /* Get the LUID for the debug privilege */ - LookupPrivilegeValue(NULL, SE_LOAD_DRIVER_NAME, &tkp.Privileges[0].Luid); - - /* One privilege to set */ - tkp.PrivilegeCount = 1; - tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - /* Get the debug privilege for this process */ - AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); - } -} - - BOOL WINAPI ShutdownHandlerRoutine(DWORD dwCtrlType) { @@ -378,7 +356,7 @@ wWinMain(HINSTANCE hInstance, { HANDLE hScmStartEvent = NULL; SC_RPC_LOCK Lock = NULL; - BOOL bDeleteCriticalSection = FALSE; + BOOL bCanDeleteNamedPipeCriticalSection = FALSE; DWORD dwError; DPRINT("SERVICES: Service Control Manager\n"); @@ -400,6 +378,10 @@ wWinMain(HINSTANCE hInstance, goto done; } + /* Initialize our communication named pipe's critical section */ + ScmInitNamedPipeCriticalSection(); + bCanDeleteNamedPipeCriticalSection = TRUE; + // ScmInitThreadManager(); /* FIXME: more initialization */ @@ -422,12 +404,20 @@ wWinMain(HINSTANCE hInstance, /* Update service database */ ScmGetBootAndSystemDriverState(); - /* Start the RPC server */ - ScmStartRpcServer(); - /* Register service process with CSRSS */ RegisterServicesProcess(GetCurrentProcessId()); + /* Acquire the service start lock until autostart services have been started */ + dwError = ScmAcquireServiceStartLock(TRUE, &Lock); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("SERVICES: failed to acquire the service start lock (Error %lu)\n", dwError); + goto done; + } + + /* Start the RPC server */ + ScmStartRpcServer(); + DPRINT("SERVICES: Initialized.\n"); /* Signal start event */ @@ -439,20 +429,6 @@ wWinMain(HINSTANCE hInstance, /* Wait for the LSA server */ ScmWaitForLsa(); - /* Acquire privileges to load drivers */ - AcquireLoadDriverPrivilege(); - - ScmInitNamedPipeCriticalSection(); - bDeleteCriticalSection = TRUE; - - /* Acquire the service start lock until autostart services have been started */ - dwError = ScmAcquireServiceStartLock(TRUE, &Lock); - if (dwError != ERROR_SUCCESS) - { - DPRINT1("SERVICES: failed to acquire the service start lock (Error %lu)\n", dwError); - goto done; - } - /* Start auto-start services */ ScmAutoStartServices(); @@ -467,7 +443,8 @@ wWinMain(HINSTANCE hInstance, WaitForSingleObject(hScmShutdownEvent, INFINITE); done: - if (bDeleteCriticalSection == TRUE) + /* Delete our communication named pipe's critical section */ + if (bCanDeleteNamedPipeCriticalSection == TRUE) ScmDeleteNamedPipeCriticalSection(); /* Close the shutdown event */ diff --git a/base/system/userinit/userinit.c b/base/system/userinit/userinit.c index 77d81eda7a7..d19dda51cf7 100644 --- a/base/system/userinit/userinit.c +++ b/base/system/userinit/userinit.c @@ -114,7 +114,7 @@ BOOL IsConsoleShell(VOID) goto cleanup; } - /* Check for CONSOLE in SystemStartOptions */ + /* Check for CONSOLE switch in SystemStartOptions */ CurrentOption = SystemStartOptions; while (CurrentOption) { diff --git a/boot/freeldr/freeldr/windows/winldr.c b/boot/freeldr/freeldr/windows/winldr.c index 25eaa15ed12..e9d03cfb146 100644 --- a/boot/freeldr/freeldr/windows/winldr.c +++ b/boot/freeldr/freeldr/windows/winldr.c @@ -85,9 +85,10 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, //CHAR SystemRoot[] = "\\WINNT\\"; //CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)"; - CHAR HalPath[] = "\\"; - CHAR ArcBoot[256]; - CHAR MiscFiles[256]; + LPSTR LoadOptions, NewLoadOptions; + CHAR HalPath[] = "\\"; + CHAR ArcBoot[256]; + CHAR MiscFiles[256]; ULONG i; ULONG_PTR PathSeparator; PLOADER_PARAMETER_EXTENSION Extension; @@ -120,9 +121,18 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, strncpy(LoaderBlock->NtHalPathName, HalPath, MAX_PATH); LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName); - /* Fill load options */ - LoaderBlock->LoadOptions = WinLdrSystemBlock->LoadOptions; + /* Fill LoadOptions and strip the '/' commutator symbol in front of each option */ + NewLoadOptions = LoadOptions = LoaderBlock->LoadOptions = WinLdrSystemBlock->LoadOptions; strncpy(LoaderBlock->LoadOptions, Options, MAX_OPTIONS_LENGTH); + + do + { + while (*LoadOptions == '/') + ++LoadOptions; + + *NewLoadOptions++ = *LoadOptions; + } while (*LoadOptions++); + LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions); /* Arc devices */ @@ -136,8 +146,8 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, /* Allocate the ARC structure */ ArcDiskSig = HeapAllocate(FrLdrDefaultHeap, - sizeof(ARC_DISK_SIGNATURE_EX), - 'giSD'); + sizeof(ARC_DISK_SIGNATURE_EX), + 'giSD'); /* Copy the data over */ ArcDiskSig->DiskSignature.Signature = reactos_arc_disk_info[i].Signature; diff --git a/dll/win32/lsasrv/CMakeLists.txt b/dll/win32/lsasrv/CMakeLists.txt index 28d55339657..71b4d0a0265 100644 --- a/dll/win32/lsasrv/CMakeLists.txt +++ b/dll/win32/lsasrv/CMakeLists.txt @@ -18,6 +18,7 @@ list(APPEND SOURCE lsasrv.c policy.c privileges.c + security.c lsasrv.rc ${CMAKE_CURRENT_BINARY_DIR}/lsasrv_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/lsasrv.def diff --git a/dll/win32/lsasrv/database.c b/dll/win32/lsasrv/database.c index 2ea60f6b3dc..9303636a3f4 100644 --- a/dll/win32/lsasrv/database.c +++ b/dll/win32/lsasrv/database.c @@ -244,6 +244,8 @@ LsapCreateDatabaseObjects(VOID) GUID DnsDomainGuid; PLSA_DB_OBJECT PolicyObject = NULL; PSID AccountDomainSid = NULL; + PSECURITY_DESCRIPTOR PolicySd = NULL; + ULONG PolicySdSize = 0; ULONG AuditEventsCount; ULONG AuditEventsSize; ULONG i; @@ -269,7 +271,7 @@ LsapCreateDatabaseObjects(VOID) AuditEventsCount = AuditCategoryAccountLogon - AuditCategorySystem + 1; AuditEventsSize = sizeof(LSAP_POLICY_AUDIT_EVENTS_DATA) + AuditEventsCount * sizeof(DWORD); AuditEventsInfo = RtlAllocateHeap(RtlGetProcessHeap(), - 0, + HEAP_ZERO_MEMORY, AuditEventsSize); if (AuditEventsInfo == NULL) return STATUS_INSUFFICIENT_RESOURCES; @@ -291,6 +293,11 @@ LsapCreateDatabaseObjects(VOID) if (!NT_SUCCESS(Status)) goto done; + Status = LsapCreatePolicySd(&PolicySd, + &PolicySdSize); + if (!NT_SUCCESS(Status)) + goto done; + /* Open the 'Policy' object */ Status = LsapOpenDbObject(NULL, NULL, @@ -369,6 +376,12 @@ LsapCreateDatabaseObjects(VOID) &DnsDomainGuid, sizeof(GUID)); + /* Set the Sceurity Descriptor */ + LsapSetObjectAttribute(PolicyObject, + L"SecDesc", + PolicySd, + PolicySdSize); + done: if (AuditEventsInfo != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, AuditEventsInfo); @@ -379,6 +392,9 @@ done: if (AccountDomainSid != NULL) RtlFreeSid(AccountDomainSid); + if (PolicySd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, PolicySd); + return Status; } diff --git a/dll/win32/lsasrv/lsarpc.c b/dll/win32/lsasrv/lsarpc.c index ac4c86b5ee0..4bb17cedbd9 100644 --- a/dll/win32/lsasrv/lsarpc.c +++ b/dll/win32/lsasrv/lsarpc.c @@ -138,8 +138,80 @@ NTSTATUS WINAPI LsarQuerySecurityObject( SECURITY_INFORMATION SecurityInformation, PLSAPR_SR_SECURITY_DESCRIPTOR *SecurityDescriptor) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PLSA_DB_OBJECT DbObject = NULL; + PSECURITY_DESCRIPTOR RelativeSd = NULL; + PLSAPR_SR_SECURITY_DESCRIPTOR SdData = NULL; + ACCESS_MASK DesiredAccess = 0; + ULONG RelativeSdSize = 0; + NTSTATUS Status; + + if (SecurityDescriptor == NULL) + return STATUS_INVALID_PARAMETER; + + if ((SecurityInformation & OWNER_SECURITY_INFORMATION) || + (SecurityInformation & GROUP_SECURITY_INFORMATION) || + (SecurityInformation & DACL_SECURITY_INFORMATION)) + DesiredAccess |= READ_CONTROL; + + if (SecurityInformation & SACL_SECURITY_INFORMATION) + DesiredAccess |= ACCESS_SYSTEM_SECURITY; + + /* Validate the ObjectHandle */ + Status = LsapValidateDbObject(ObjectHandle, + LsaDbIgnoreObject, + DesiredAccess, + &DbObject); + if (!NT_SUCCESS(Status)) + return Status; + + /* Get the size of the SD */ + Status = LsapGetObjectAttribute(DbObject, + L"SecDesc", + NULL, + &RelativeSdSize); + if (!NT_SUCCESS(Status)) + return Status; + + /* Allocate a buffer for the SD */ + RelativeSd = MIDL_user_allocate(RelativeSdSize); + if (RelativeSd == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + /* Get the SD */ + Status = LsapGetObjectAttribute(DbObject, + L"SecDesc", + RelativeSd, + &RelativeSdSize); + if (!NT_SUCCESS(Status)) + goto done; + + /* + * FIXME: Invalidate the SD information that was not requested. + * (see SecurityInformation) + */ + + /* Allocate the SD data buffer */ + SdData = MIDL_user_allocate(sizeof(LSAPR_SR_SECURITY_DESCRIPTOR)); + if (SdData == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + /* Fill the SD data buffer and return it to the caller */ + SdData->Length = RelativeSdSize; + SdData->SecurityDescriptor = (PBYTE)RelativeSd; + + *SecurityDescriptor = SdData; + +done: + if (!NT_SUCCESS(Status)) + { + if (RelativeSd != NULL) + MIDL_user_free(RelativeSd); + } + + return Status; } @@ -206,7 +278,7 @@ NTSTATUS WINAPI LsarQueryInformationPolicy( POLICY_INFORMATION_CLASS InformationClass, PLSAPR_POLICY_INFORMATION *PolicyInformation) { - PLSA_DB_OBJECT DbObject; + PLSA_DB_OBJECT PolicyObject; ACCESS_MASK DesiredAccess = 0; NTSTATUS Status; @@ -250,74 +322,74 @@ NTSTATUS WINAPI LsarQueryInformationPolicy( Status = LsapValidateDbObject(PolicyHandle, LsaDbPolicyObject, DesiredAccess, - &DbObject); + &PolicyObject); if (!NT_SUCCESS(Status)) return Status; switch (InformationClass) { case PolicyAuditLogInformation: /* 1 */ - Status = LsarQueryAuditLog(PolicyHandle, + Status = LsarQueryAuditLog(PolicyObject, PolicyInformation); break; case PolicyAuditEventsInformation: /* 2 */ - Status = LsarQueryAuditEvents(PolicyHandle, + Status = LsarQueryAuditEvents(PolicyObject, PolicyInformation); break; case PolicyPrimaryDomainInformation: /* 3 */ - Status = LsarQueryPrimaryDomain(PolicyHandle, + Status = LsarQueryPrimaryDomain(PolicyObject, PolicyInformation); break; case PolicyPdAccountInformation: /* 4 */ - Status = LsarQueryPdAccount(PolicyHandle, + Status = LsarQueryPdAccount(PolicyObject, PolicyInformation); break; case PolicyAccountDomainInformation: /* 5 */ - Status = LsarQueryAccountDomain(PolicyHandle, + Status = LsarQueryAccountDomain(PolicyObject, PolicyInformation); break; case PolicyLsaServerRoleInformation: /* 6 */ - Status = LsarQueryServerRole(PolicyHandle, + Status = LsarQueryServerRole(PolicyObject, PolicyInformation); break; case PolicyReplicaSourceInformation: /* 7 */ - Status = LsarQueryReplicaSource(PolicyHandle, + Status = LsarQueryReplicaSource(PolicyObject, PolicyInformation); break; case PolicyDefaultQuotaInformation: /* 8 */ - Status = LsarQueryDefaultQuota(PolicyHandle, + Status = LsarQueryDefaultQuota(PolicyObject, PolicyInformation); break; case PolicyModificationInformation: /* 9 */ - Status = LsarQueryModification(PolicyHandle, + Status = LsarQueryModification(PolicyObject, PolicyInformation); break; case PolicyAuditFullQueryInformation: /* 11 (0xB) */ - Status = LsarQueryAuditFull(PolicyHandle, + Status = LsarQueryAuditFull(PolicyObject, PolicyInformation); break; case PolicyDnsDomainInformation: /* 12 (0xC) */ - Status = LsarQueryDnsDomain(PolicyHandle, + Status = LsarQueryDnsDomain(PolicyObject, PolicyInformation); break; case PolicyDnsDomainInformationInt: /* 13 (0xD) */ - Status = LsarQueryDnsDomainInt(PolicyHandle, + Status = LsarQueryDnsDomainInt(PolicyObject, PolicyInformation); break; case PolicyLocalAccountDomainInformation: /* 14 (0xE) */ - Status = LsarQueryLocalAccountDomain(PolicyHandle, + Status = LsarQueryLocalAccountDomain(PolicyObject, PolicyInformation); break; @@ -336,7 +408,7 @@ NTSTATUS WINAPI LsarSetInformationPolicy( POLICY_INFORMATION_CLASS InformationClass, PLSAPR_POLICY_INFORMATION PolicyInformation) { - PLSA_DB_OBJECT DbObject; + PLSA_DB_OBJECT PolicyObject; ACCESS_MASK DesiredAccess = 0; NTSTATUS Status; @@ -384,33 +456,70 @@ NTSTATUS WINAPI LsarSetInformationPolicy( Status = LsapValidateDbObject(PolicyHandle, LsaDbPolicyObject, DesiredAccess, - &DbObject); + &PolicyObject); if (!NT_SUCCESS(Status)) return Status; switch (InformationClass) { - case PolicyAuditEventsInformation: - Status = STATUS_NOT_IMPLEMENTED; + case PolicyAuditLogInformation: /* 1 */ + Status = LsarSetAuditLog(PolicyObject, + (PPOLICY_AUDIT_LOG_INFO)PolicyInformation); break; - case PolicyPrimaryDomainInformation: - Status = LsarSetPrimaryDomain(PolicyHandle, + case PolicyAuditEventsInformation: /* 2 */ + Status = LsarSetAuditEvents(PolicyObject, + (PLSAPR_POLICY_AUDIT_EVENTS_INFO)PolicyInformation); + break; + + case PolicyPrimaryDomainInformation: /* 3 */ + Status = LsarSetPrimaryDomain(PolicyObject, (PLSAPR_POLICY_PRIMARY_DOM_INFO)PolicyInformation); break; - case PolicyAccountDomainInformation: - Status = LsarSetAccountDomain(PolicyHandle, + case PolicyAccountDomainInformation: /* 5 */ + Status = LsarSetAccountDomain(PolicyObject, (PLSAPR_POLICY_ACCOUNT_DOM_INFO)PolicyInformation); break; - case PolicyDnsDomainInformation: - Status = LsarSetDnsDomain(PolicyHandle, + case PolicyLsaServerRoleInformation: /* 6 */ + Status = LsarSetServerRole(PolicyObject, + (PPOLICY_LSA_SERVER_ROLE_INFO)PolicyInformation); + break; + + case PolicyReplicaSourceInformation: /* 7 */ + Status = LsarSetReplicaSource(PolicyObject, + (PPOLICY_LSA_REPLICA_SRCE_INFO)PolicyInformation); + break; + + case PolicyDefaultQuotaInformation: /* 8 */ + Status = LsarSetDefaultQuota(PolicyObject, + (PPOLICY_DEFAULT_QUOTA_INFO)PolicyInformation); + break; + + case PolicyModificationInformation: /* 9 */ + Status = LsarSetModification(PolicyObject, + (PPOLICY_MODIFICATION_INFO)PolicyInformation); + break; + + case PolicyAuditFullSetInformation: /* 10 (0xA) */ + Status = LsarSetAuditFull(PolicyObject, + (PPOLICY_AUDIT_FULL_QUERY_INFO)PolicyInformation); + break; + + case PolicyDnsDomainInformation: /* 12 (0xC) */ + Status = LsarSetDnsDomain(PolicyObject, (PLSAPR_POLICY_DNS_DOMAIN_INFO)PolicyInformation); break; - case PolicyLsaServerRoleInformation: - Status = STATUS_NOT_IMPLEMENTED; + case PolicyDnsDomainInformationInt: /* 13 (0xD) */ + Status = LsarSetDnsDomainInt(PolicyObject, + (PLSAPR_POLICY_DNS_DOMAIN_INFO)PolicyInformation); + break; + + case PolicyLocalAccountDomainInformation: /* 14 (0xE) */ + Status = LsarSetLocalAccountDomain(PolicyObject, + (PLSAPR_POLICY_ACCOUNT_DOM_INFO)PolicyInformation); break; default: @@ -441,6 +550,8 @@ NTSTATUS WINAPI LsarCreateAccount( PLSA_DB_OBJECT PolicyObject; PLSA_DB_OBJECT AccountObject = NULL; LPWSTR SidString = NULL; + PSECURITY_DESCRIPTOR AccountSd = NULL; + ULONG AccountSdSize; NTSTATUS Status = STATUS_SUCCESS; /* Validate the AccountSid */ @@ -467,6 +578,15 @@ NTSTATUS WINAPI LsarCreateAccount( goto done; } + /* Create a security descriptor for the account */ + Status = LsapCreateAccountSd(&AccountSd, + &AccountSdSize); + if (!NT_SUCCESS(Status)) + { + ERR("LsapCreateAccountSd returned 0x%08lx\n", Status); + return Status; + } + /* Create the Account object */ Status = LsapCreateDbObject(PolicyObject, L"Accounts", @@ -485,11 +605,22 @@ NTSTATUS WINAPI LsarCreateAccount( L"Sid", (PVOID)AccountSid, GetLengthSid(AccountSid)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the SecDesc attribute */ + Status = LsapSetObjectAttribute(AccountObject, + L"SecDesc", + AccountSd, + AccountSdSize); done: if (SidString != NULL) LocalFree(SidString); + if (AccountSd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, AccountSd); + if (!NT_SUCCESS(Status)) { if (AccountObject != NULL) @@ -673,6 +804,8 @@ NTSTATUS WINAPI LsarCreateSecret( PLSA_DB_OBJECT PolicyObject; PLSA_DB_OBJECT SecretObject = NULL; LARGE_INTEGER Time; + PSECURITY_DESCRIPTOR SecretSd = NULL; + ULONG SecretSdSize; NTSTATUS Status = STATUS_SUCCESS; /* Validate the PolicyHandle */ @@ -694,6 +827,15 @@ NTSTATUS WINAPI LsarCreateSecret( goto done; } + /* Create a security descriptor for the secret */ + Status = LsapCreateSecretSd(&SecretSd, + &SecretSdSize); + if (!NT_SUCCESS(Status)) + { + ERR("LsapCreateAccountSd returned 0x%08lx\n", Status); + return Status; + } + /* Create the Secret object */ Status = LsapCreateDbObject(PolicyObject, L"Secrets", @@ -723,8 +865,22 @@ NTSTATUS WINAPI LsarCreateSecret( L"OldTime", (PVOID)&Time, sizeof(LARGE_INTEGER)); + if (!NT_SUCCESS(Status)) + { + ERR("LsapSetObjectAttribute (OldTime) failed (Status 0x%08lx)\n", Status); + goto done; + } + + /* Set the SecDesc attribute */ + Status = LsapSetObjectAttribute(SecretObject, + L"SecDesc", + SecretSd, + SecretSdSize); done: + if (SecretSd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, SecretSd); + if (!NT_SUCCESS(Status)) { if (SecretObject != NULL) diff --git a/dll/win32/lsasrv/lsasrv.h b/dll/win32/lsasrv/lsasrv.h index 5f18e5a12f8..8849448f3f4 100644 --- a/dll/win32/lsasrv/lsasrv.h +++ b/dll/win32/lsasrv/lsasrv.h @@ -201,6 +201,14 @@ NTSTATUS LsarQueryLocalAccountDomain(PLSA_DB_OBJECT PolicyObject, PLSAPR_POLICY_INFORMATION *PolicyInformation); +NTSTATUS +LsarSetAuditLog(PLSA_DB_OBJECT PolicyObject, + PPOLICY_AUDIT_LOG_INFO Info); + +NTSTATUS +LsarSetAuditEvents(PLSA_DB_OBJECT PolicyObject, + PLSAPR_POLICY_AUDIT_EVENTS_INFO Info); + NTSTATUS LsarSetPrimaryDomain(PLSA_DB_OBJECT PolicyObject, PLSAPR_POLICY_PRIMARY_DOM_INFO Info); @@ -209,10 +217,38 @@ NTSTATUS LsarSetAccountDomain(PLSA_DB_OBJECT PolicyObject, PLSAPR_POLICY_ACCOUNT_DOM_INFO Info); +NTSTATUS +LsarSetServerRole(PLSA_DB_OBJECT PolicyObject, + PPOLICY_LSA_SERVER_ROLE_INFO Info); + +NTSTATUS +LsarSetReplicaSource(PLSA_DB_OBJECT PolicyObject, + PPOLICY_LSA_REPLICA_SRCE_INFO Info); + +NTSTATUS +LsarSetDefaultQuota(PLSA_DB_OBJECT PolicyObject, + PPOLICY_DEFAULT_QUOTA_INFO Info); + +NTSTATUS +LsarSetModification(PLSA_DB_OBJECT PolicyObject, + PPOLICY_MODIFICATION_INFO Info); + +NTSTATUS +LsarSetAuditFull(PLSA_DB_OBJECT PolicyObject, + PPOLICY_AUDIT_FULL_QUERY_INFO Info); + NTSTATUS LsarSetDnsDomain(PLSA_DB_OBJECT PolicyObject, PLSAPR_POLICY_DNS_DOMAIN_INFO Info); +NTSTATUS +LsarSetDnsDomainInt(PLSA_DB_OBJECT PolicyObject, + PLSAPR_POLICY_DNS_DOMAIN_INFO Info); + +NTSTATUS +LsarSetLocalAccountDomain(PLSA_DB_OBJECT PolicyObject, + PLSAPR_POLICY_ACCOUNT_DOM_INFO Info); + /* privileges.c */ NTSTATUS LsarpLookupPrivilegeName(PLUID Value, @@ -227,4 +263,17 @@ LsarpEnumeratePrivileges(DWORD *EnumerationContext, PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer, DWORD PreferedMaximumLength); +/* security.c */ +NTSTATUS +LsapCreatePolicySd(PSECURITY_DESCRIPTOR *PolicySd, + PULONG PolicySdSize); + +NTSTATUS +LsapCreateAccountSd(PSECURITY_DESCRIPTOR *AccountSd, + PULONG AccountSdSize); + +NTSTATUS +LsapCreateSecretSd(PSECURITY_DESCRIPTOR *SecretSd, + PULONG SecretSdSize); + /* EOF */ diff --git a/dll/win32/lsasrv/policy.c b/dll/win32/lsasrv/policy.c index fe8137235d8..8fe0735e19f 100644 --- a/dll/win32/lsasrv/policy.c +++ b/dll/win32/lsasrv/policy.c @@ -38,109 +38,6 @@ LsaIOpenPolicyTrusted(OUT LSAPR_HANDLE *PolicyHandle) } -NTSTATUS -LsarSetPrimaryDomain(PLSA_DB_OBJECT PolicyObject, - PLSAPR_POLICY_PRIMARY_DOM_INFO Info) -{ - PUNICODE_STRING Buffer; - ULONG Length = 0; - NTSTATUS Status; - LPWSTR Ptr; - - TRACE("(%p %p)\n", PolicyObject, Info); - - Length = sizeof(UNICODE_STRING) + Info->Name.MaximumLength; - Buffer = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - Length); - if (Buffer == NULL) - return STATUS_INSUFFICIENT_RESOURCES; - - Buffer->Length = Info->Name.Length; - Buffer->MaximumLength = Info->Name.MaximumLength; - Buffer->Buffer = (LPWSTR)sizeof(UNICODE_STRING); - Ptr = (LPWSTR)((ULONG_PTR)Buffer + sizeof(UNICODE_STRING)); - memcpy(Ptr, Info->Name.Buffer, Info->Name.MaximumLength); - - Status = LsapSetObjectAttribute(PolicyObject, - L"PolPrDmN", - Buffer, - Length); - - RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); - - if (!NT_SUCCESS(Status)) - return Status; - - Length = 0; - if (Info->Sid != NULL) - Length = RtlLengthSid(Info->Sid); - - Status = LsapSetObjectAttribute(PolicyObject, - L"PolPrDmS", - (LPBYTE)Info->Sid, - Length); - - return Status; -} - - -NTSTATUS -LsarSetAccountDomain(PLSA_DB_OBJECT PolicyObject, - PLSAPR_POLICY_ACCOUNT_DOM_INFO Info) -{ - PUNICODE_STRING Buffer; - ULONG Length = 0; - NTSTATUS Status; - LPWSTR Ptr; - - TRACE("(%p %p)\n", PolicyObject, Info); - - Length = sizeof(UNICODE_STRING) + Info->DomainName.MaximumLength; - Buffer = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - Length); - if (Buffer == NULL) - return STATUS_INSUFFICIENT_RESOURCES; - - Buffer->Length = Info->DomainName.Length; - Buffer->MaximumLength = Info->DomainName.MaximumLength; - Buffer->Buffer = (LPWSTR)sizeof(UNICODE_STRING); - Ptr = (LPWSTR)((ULONG_PTR)Buffer + sizeof(UNICODE_STRING)); - memcpy(Ptr, Info->DomainName.Buffer, Info->DomainName.MaximumLength); - - Status = LsapSetObjectAttribute(PolicyObject, - L"PolAcDmN", - Buffer, - Length); - - RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); - - if (!NT_SUCCESS(Status)) - return Status; - - Length = 0; - if (Info->Sid != NULL) - Length = RtlLengthSid(Info->Sid); - - Status = LsapSetObjectAttribute(PolicyObject, - L"PolAcDmS", - (LPBYTE)Info->Sid, - Length); - - return Status; -} - - -NTSTATUS -LsarSetDnsDomain(PLSA_DB_OBJECT PolicyObject, - PLSAPR_POLICY_DNS_DOMAIN_INFO Info) -{ - - return STATUS_NOT_IMPLEMENTED; -} - - NTSTATUS LsarQueryAuditLog(PLSA_DB_OBJECT PolicyObject, PLSAPR_POLICY_INFORMATION *PolicyInformation) @@ -525,6 +422,16 @@ LsarQueryServerRole(PLSA_DB_OBJECT PolicyObject, } +NTSTATUS +LsarQueryReplicaSource(PLSA_DB_OBJECT PolicyObject, + PLSAPR_POLICY_INFORMATION *PolicyInformation) +{ + FIXME("\n"); + *PolicyInformation = NULL; + return STATUS_NOT_IMPLEMENTED; +} + + NTSTATUS LsarQueryDefaultQuota(PLSA_DB_OBJECT PolicyObject, PLSAPR_POLICY_INFORMATION *PolicyInformation) @@ -557,16 +464,6 @@ LsarQueryDefaultQuota(PLSA_DB_OBJECT PolicyObject, } -NTSTATUS -LsarQueryReplicaSource(PLSA_DB_OBJECT PolicyObject, - PLSAPR_POLICY_INFORMATION *PolicyInformation) -{ - FIXME("\n"); - *PolicyInformation = NULL; - return STATUS_NOT_IMPLEMENTED; -} - - NTSTATUS LsarQueryModification(PLSA_DB_OBJECT PolicyObject, PLSAPR_POLICY_INFORMATION *PolicyInformation) @@ -867,4 +764,196 @@ LsarQueryLocalAccountDomain(PLSA_DB_OBJECT PolicyObject, return STATUS_NOT_IMPLEMENTED; } + +NTSTATUS +LsarSetAuditLog(PLSA_DB_OBJECT PolicyObject, + PPOLICY_AUDIT_LOG_INFO Info) +{ + TRACE("(%p %p)\n", PolicyObject, Info); + + return LsapSetObjectAttribute(PolicyObject, + L"PolAdtLg", + Info, + sizeof(POLICY_AUDIT_LOG_INFO)); +} + + +NTSTATUS +LsarSetAuditEvents(PLSA_DB_OBJECT PolicyObject, + PLSAPR_POLICY_AUDIT_EVENTS_INFO Info) +{ + FIXME("\n"); + return STATUS_NOT_IMPLEMENTED; +} + + +NTSTATUS +LsarSetPrimaryDomain(PLSA_DB_OBJECT PolicyObject, + PLSAPR_POLICY_PRIMARY_DOM_INFO Info) +{ + PUNICODE_STRING Buffer; + ULONG Length = 0; + NTSTATUS Status; + LPWSTR Ptr; + + TRACE("(%p %p)\n", PolicyObject, Info); + + Length = sizeof(UNICODE_STRING) + Info->Name.MaximumLength; + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + Length); + if (Buffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Buffer->Length = Info->Name.Length; + Buffer->MaximumLength = Info->Name.MaximumLength; + Buffer->Buffer = (LPWSTR)sizeof(UNICODE_STRING); + Ptr = (LPWSTR)((ULONG_PTR)Buffer + sizeof(UNICODE_STRING)); + memcpy(Ptr, Info->Name.Buffer, Info->Name.MaximumLength); + + Status = LsapSetObjectAttribute(PolicyObject, + L"PolPrDmN", + Buffer, + Length); + + RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + + if (!NT_SUCCESS(Status)) + return Status; + + Length = 0; + if (Info->Sid != NULL) + Length = RtlLengthSid(Info->Sid); + + Status = LsapSetObjectAttribute(PolicyObject, + L"PolPrDmS", + (LPBYTE)Info->Sid, + Length); + + return Status; +} + + +NTSTATUS +LsarSetAccountDomain(PLSA_DB_OBJECT PolicyObject, + PLSAPR_POLICY_ACCOUNT_DOM_INFO Info) +{ + PUNICODE_STRING Buffer; + ULONG Length = 0; + NTSTATUS Status; + LPWSTR Ptr; + + TRACE("(%p %p)\n", PolicyObject, Info); + + Length = sizeof(UNICODE_STRING) + Info->DomainName.MaximumLength; + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + Length); + if (Buffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Buffer->Length = Info->DomainName.Length; + Buffer->MaximumLength = Info->DomainName.MaximumLength; + Buffer->Buffer = (LPWSTR)sizeof(UNICODE_STRING); + Ptr = (LPWSTR)((ULONG_PTR)Buffer + sizeof(UNICODE_STRING)); + memcpy(Ptr, Info->DomainName.Buffer, Info->DomainName.MaximumLength); + + Status = LsapSetObjectAttribute(PolicyObject, + L"PolAcDmN", + Buffer, + Length); + + RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + + if (!NT_SUCCESS(Status)) + return Status; + + Length = 0; + if (Info->Sid != NULL) + Length = RtlLengthSid(Info->Sid); + + Status = LsapSetObjectAttribute(PolicyObject, + L"PolAcDmS", + (LPBYTE)Info->Sid, + Length); + + return Status; +} + + +NTSTATUS +LsarSetServerRole(PLSA_DB_OBJECT PolicyObject, + PPOLICY_LSA_SERVER_ROLE_INFO Info) +{ + FIXME("\n"); + return STATUS_NOT_IMPLEMENTED; +} + + +NTSTATUS +LsarSetReplicaSource(PLSA_DB_OBJECT PolicyObject, + PPOLICY_LSA_REPLICA_SRCE_INFO Info) +{ + FIXME("\n"); + return STATUS_NOT_IMPLEMENTED; +} + + +NTSTATUS +LsarSetDefaultQuota(PLSA_DB_OBJECT PolicyObject, + PPOLICY_DEFAULT_QUOTA_INFO Info) +{ + TRACE("(%p %p)\n", PolicyObject, Info); + + return LsapSetObjectAttribute(PolicyObject, + L"DefQuota", + Info, + sizeof(POLICY_DEFAULT_QUOTA_INFO)); +} + + +NTSTATUS +LsarSetModification(PLSA_DB_OBJECT PolicyObject, + PPOLICY_MODIFICATION_INFO Info) +{ + FIXME("\n"); + return STATUS_NOT_IMPLEMENTED; +} + + +NTSTATUS +LsarSetAuditFull(PLSA_DB_OBJECT PolicyObject, + PPOLICY_AUDIT_FULL_QUERY_INFO Info) +{ + FIXME("\n"); + return STATUS_NOT_IMPLEMENTED; +} + + +NTSTATUS +LsarSetDnsDomain(PLSA_DB_OBJECT PolicyObject, + PLSAPR_POLICY_DNS_DOMAIN_INFO Info) +{ + FIXME("\n"); + return STATUS_NOT_IMPLEMENTED; +} + + +NTSTATUS +LsarSetDnsDomainInt(PLSA_DB_OBJECT PolicyObject, + PLSAPR_POLICY_DNS_DOMAIN_INFO Info) +{ + FIXME("\n"); + return STATUS_NOT_IMPLEMENTED; +} + + +NTSTATUS +LsarSetLocalAccountDomain(PLSA_DB_OBJECT PolicyObject, + PLSAPR_POLICY_ACCOUNT_DOM_INFO Info) +{ + FIXME("\n"); + return STATUS_NOT_IMPLEMENTED; +} + /* EOF */ diff --git a/dll/win32/lsasrv/security.c b/dll/win32/lsasrv/security.c new file mode 100644 index 00000000000..7112470eb50 --- /dev/null +++ b/dll/win32/lsasrv/security.c @@ -0,0 +1,607 @@ +/* + * PROJECT: Local Security Authority Server DLL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/win32/lsasrv/security.c + * PURPOSE: LSA object security functions + * COPYRIGHT: Copyright 2012 Eric Kohl + */ + +/* INCLUDES ****************************************************************/ + +#include "lsasrv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(lsasrv); + + +/* FUNCTIONS ***************************************************************/ + +NTSTATUS +LsapCreatePolicySd(PSECURITY_DESCRIPTOR *PolicySd, + PULONG PolicySdSize) +{ + SECURITY_DESCRIPTOR AbsoluteSd; + PSECURITY_DESCRIPTOR RelativeSd = NULL; + ULONG RelativeSdSize = 0; + PSID AnonymousSid = NULL; + PSID AdministratorsSid = NULL; + PSID EveryoneSid = NULL; + PSID LocalServiceSid = NULL; + PSID NetworkServiceSid = NULL; + PSID LocalSystemSid = NULL; + PACL Dacl = NULL; + ULONG DaclSize; + NTSTATUS Status; + + if (PolicySd == NULL || PolicySdSize == NULL) + return STATUS_INVALID_PARAMETER; + + *PolicySd = NULL; + *PolicySdSize = 0; + + /* Initialize the SD */ + Status = RtlCreateSecurityDescriptor(&AbsoluteSd, + SECURITY_DESCRIPTOR_REVISION); + if (!NT_SUCCESS(Status)) + return Status; + + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, + SECURITY_ANONYMOUS_LOGON_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &AnonymousSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, + 0, + 0, + 0, + 0, + 0, + &AdministratorsSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAllocateAndInitializeSid(&WorldSidAuthority, + 1, + SECURITY_WORLD_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &EveryoneSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, + SECURITY_LOCAL_SERVICE_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &LocalServiceSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, + SECURITY_NETWORK_SERVICE_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &NetworkServiceSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, + SECURITY_LOCAL_SYSTEM_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &LocalSystemSid); + if (!NT_SUCCESS(Status)) + goto done; + + /* Allocate and initialize the DACL */ + DaclSize = sizeof(ACL) + + sizeof(ACCESS_DENIED_ACE) - sizeof(ULONG) + RtlLengthSid(AnonymousSid) + + sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AdministratorsSid) + + sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(EveryoneSid) + + sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AnonymousSid) + + sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(LocalServiceSid) + + sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(NetworkServiceSid); + + Dacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Dacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = RtlCreateAcl(Dacl, + DaclSize, + ACL_REVISION); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessDeniedAce(Dacl, + ACL_REVISION, + POLICY_LOOKUP_NAMES, + AnonymousSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + POLICY_ALL_ACCESS | POLICY_NOTIFICATION, + AdministratorsSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + POLICY_EXECUTE, + EveryoneSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION, + AnonymousSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + POLICY_NOTIFICATION, + LocalServiceSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + POLICY_NOTIFICATION, + NetworkServiceSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlSetDaclSecurityDescriptor(&AbsoluteSd, + TRUE, + Dacl, + FALSE); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlSetGroupSecurityDescriptor(&AbsoluteSd, + LocalSystemSid, + FALSE); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlSetOwnerSecurityDescriptor(&AbsoluteSd, + AdministratorsSid, + FALSE); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd, + RelativeSd, + &RelativeSdSize); + if (Status != STATUS_BUFFER_TOO_SMALL) + goto done; + + RelativeSd = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + RelativeSdSize); + if (RelativeSd == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd, + RelativeSd, + &RelativeSdSize); + if (!NT_SUCCESS(Status)) + goto done; + + *PolicySd = RelativeSd; + *PolicySdSize = RelativeSdSize; + +done: + if (Dacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl); + + if (AnonymousSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, AnonymousSid); + + if (AdministratorsSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, AdministratorsSid); + + if (EveryoneSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, EveryoneSid); + + if (LocalServiceSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, LocalServiceSid); + + if (NetworkServiceSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, NetworkServiceSid); + + if (LocalSystemSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSystemSid); + + if (!NT_SUCCESS(Status)) + { + if (RelativeSd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSd); + } + + return Status; +} + + +NTSTATUS +LsapCreateAccountSd(PSECURITY_DESCRIPTOR *AccountSd, + PULONG AccountSdSize) +{ + SECURITY_DESCRIPTOR AbsoluteSd; + PSECURITY_DESCRIPTOR RelativeSd = NULL; + ULONG RelativeSdSize = 0; + PSID AdministratorsSid = NULL; + PSID EveryoneSid = NULL; + PSID LocalSystemSid = NULL; + PACL Dacl = NULL; + ULONG DaclSize; + NTSTATUS Status; + + if (AccountSd == NULL || AccountSdSize == NULL) + return STATUS_INVALID_PARAMETER; + + *AccountSd = NULL; + *AccountSdSize = 0; + + /* Initialize the SD */ + Status = RtlCreateSecurityDescriptor(&AbsoluteSd, + SECURITY_DESCRIPTOR_REVISION); + if (!NT_SUCCESS(Status)) + return Status; + + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, + 0, + 0, + 0, + 0, + 0, + &AdministratorsSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAllocateAndInitializeSid(&WorldSidAuthority, + 1, + SECURITY_WORLD_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &EveryoneSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, + SECURITY_LOCAL_SYSTEM_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &LocalSystemSid); + if (!NT_SUCCESS(Status)) + goto done; + + /* Allocate and initialize the DACL */ + DaclSize = sizeof(ACL) + + sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AdministratorsSid) + + sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(EveryoneSid); + + Dacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Dacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = RtlCreateAcl(Dacl, + DaclSize, + ACL_REVISION); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + ACCOUNT_ALL_ACCESS, + AdministratorsSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + ACCOUNT_EXECUTE, + EveryoneSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlSetDaclSecurityDescriptor(&AbsoluteSd, + TRUE, + Dacl, + FALSE); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlSetGroupSecurityDescriptor(&AbsoluteSd, + LocalSystemSid, + FALSE); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlSetOwnerSecurityDescriptor(&AbsoluteSd, + AdministratorsSid, + FALSE); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd, + RelativeSd, + &RelativeSdSize); + if (Status != STATUS_BUFFER_TOO_SMALL) + goto done; + + RelativeSd = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + RelativeSdSize); + if (RelativeSd == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd, + RelativeSd, + &RelativeSdSize); + if (!NT_SUCCESS(Status)) + goto done; + + *AccountSd = RelativeSd; + *AccountSdSize = RelativeSdSize; + +done: + if (Dacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl); + + if (AdministratorsSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, AdministratorsSid); + + if (EveryoneSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, EveryoneSid); + + if (LocalSystemSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSystemSid); + + if (!NT_SUCCESS(Status)) + { + if (RelativeSd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSd); + } + + return Status; +} + + +NTSTATUS +LsapCreateSecretSd(PSECURITY_DESCRIPTOR *SecretSd, + PULONG SecretSdSize) +{ + SECURITY_DESCRIPTOR AbsoluteSd; + PSECURITY_DESCRIPTOR RelativeSd = NULL; + ULONG RelativeSdSize = 0; + PSID AdministratorsSid = NULL; + PSID EveryoneSid = NULL; + PSID LocalSystemSid = NULL; + PACL Dacl = NULL; + ULONG DaclSize; + NTSTATUS Status; + + if (SecretSd == NULL || SecretSdSize == NULL) + return STATUS_INVALID_PARAMETER; + + *SecretSd = NULL; + *SecretSdSize = 0; + + /* Initialize the SD */ + Status = RtlCreateSecurityDescriptor(&AbsoluteSd, + SECURITY_DESCRIPTOR_REVISION); + if (!NT_SUCCESS(Status)) + return Status; + + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, + 0, + 0, + 0, + 0, + 0, + &AdministratorsSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAllocateAndInitializeSid(&WorldSidAuthority, + 1, + SECURITY_WORLD_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &EveryoneSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, + SECURITY_LOCAL_SYSTEM_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &LocalSystemSid); + if (!NT_SUCCESS(Status)) + goto done; + + /* Allocate and initialize the DACL */ + DaclSize = sizeof(ACL) + + sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(AdministratorsSid) + + sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) + RtlLengthSid(EveryoneSid); + + Dacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Dacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = RtlCreateAcl(Dacl, + DaclSize, + ACL_REVISION); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + SECRET_ALL_ACCESS, + AdministratorsSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + SECRET_EXECUTE, + EveryoneSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlSetDaclSecurityDescriptor(&AbsoluteSd, + TRUE, + Dacl, + FALSE); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlSetGroupSecurityDescriptor(&AbsoluteSd, + LocalSystemSid, + FALSE); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlSetOwnerSecurityDescriptor(&AbsoluteSd, + AdministratorsSid, + FALSE); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd, + RelativeSd, + &RelativeSdSize); + if (Status != STATUS_BUFFER_TOO_SMALL) + goto done; + + RelativeSd = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + RelativeSdSize); + if (RelativeSd == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = RtlAbsoluteToSelfRelativeSD(&AbsoluteSd, + RelativeSd, + &RelativeSdSize); + if (!NT_SUCCESS(Status)) + goto done; + + *SecretSd = RelativeSd; + *SecretSdSize = RelativeSdSize; + +done: + if (Dacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl); + + if (AdministratorsSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, AdministratorsSid); + + if (EveryoneSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, EveryoneSid); + + if (LocalSystemSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSystemSid); + + if (!NT_SUCCESS(Status)) + { + if (RelativeSd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSd); + } + + return Status; +} + +/* EOF */ diff --git a/dll/win32/msgina/lang/bg-BG.rc b/dll/win32/msgina/lang/bg-BG.rc index b67ddc26239..8e327a3d256 100644 --- a/dll/win32/msgina/lang/bg-BG.rc +++ b/dll/win32/msgina/lang/bg-BG.rc @@ -1,11 +1,12 @@ LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Почакайте..." FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -22,7 +23,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Вход" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Потребител:",IDC_STATIC,36,75,45,8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "Парола:",IDC_STATIC,36,93,42,8 @@ -32,12 +33,12 @@ BEGIN PUSHBUTTON "Изключване",IDC_SHUTDOWN,179,122,50,14 END -IDD_LOGGEDON_DLG DIALOGEX 0,0,247,116 +IDD_LOGGEDON_DLG DIALOGEX 0,0,275,116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "Сигурност" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Какво желаете?",IDC_STATIC,86,60,87,8 PUSHBUTTON "Заключване на компютъра",IDC_LOCK,25,95,99,14 PUSHBUTTON "Изход",IDC_LOGOFF,90,76,75,14 diff --git a/dll/win32/msgina/lang/cs-CZ.rc b/dll/win32/msgina/lang/cs-CZ.rc index 2d65defeee0..e43ff0f458d 100644 --- a/dll/win32/msgina/lang/cs-CZ.rc +++ b/dll/win32/msgina/lang/cs-CZ.rc @@ -5,12 +5,13 @@ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Prosím čekejte..." FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -27,7 +28,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Přihlášení" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Jméno:",IDC_STATIC,36,75,40,8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "Heslo:",IDC_STATIC,36,93,42,8 @@ -37,12 +38,12 @@ BEGIN PUSHBUTTON "Vypnout",IDC_SHUTDOWN,179,122,50,14 END -IDD_LOGGEDON_DLG DIALOGEX 0,0,247,116 +IDD_LOGGEDON_DLG DIALOGEX 0,0,275,116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "Bezpečnost" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Co chcete udělat?",IDC_STATIC,86,60,87,8 PUSHBUTTON "Uzamknout počítač",IDC_LOCK,10,76,70,14 PUSHBUTTON "Odhlásit",IDC_LOGOFF,90,76,70,14 diff --git a/dll/win32/msgina/lang/de-DE.rc b/dll/win32/msgina/lang/de-DE.rc index cd35f0ac846..fc74a035347 100644 --- a/dll/win32/msgina/lang/de-DE.rc +++ b/dll/win32/msgina/lang/de-DE.rc @@ -1,11 +1,12 @@ LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Bitte warten..." FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -22,7 +23,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Logon" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Benutzername:",IDC_STATIC,26, 75, 54, 8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "Passwort:",IDC_STATIC,43, 93, 38, 8 @@ -32,12 +33,12 @@ BEGIN PUSHBUTTON "Herunterfahren",IDC_SHUTDOWN,165, 122, 64, 14 END -IDD_LOGGEDON_DLG DIALOGEX 0,0,247,116 +IDD_LOGGEDON_DLG DIALOGEX 0,0,275,116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "Sicherheit" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Was wollen Sie tun?",IDC_STATIC,86,60,87,8 PUSHBUTTON "Computer sperren",IDC_LOCK,10,76,70,14 PUSHBUTTON "Abmelden",IDC_LOGOFF,90,76,70,14 diff --git a/dll/win32/msgina/lang/en-US.rc b/dll/win32/msgina/lang/en-US.rc index 4324b99098c..27a2d634587 100644 --- a/dll/win32/msgina/lang/en-US.rc +++ b/dll/win32/msgina/lang/en-US.rc @@ -1,11 +1,12 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Please wait..." FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -22,7 +23,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Logon" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Username:",IDC_STATIC,36,75,40,8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "Password:",IDC_STATIC,36,93,42,8 @@ -32,12 +33,12 @@ BEGIN PUSHBUTTON "Shutdown",IDC_SHUTDOWN,179,122,50,14 END -IDD_LOGGEDON_DLG DIALOGEX 0,0,247,116 +IDD_LOGGEDON_DLG DIALOGEX 0,0,275,116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "Security" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "What do you want to do?",IDC_STATIC,86,60,87,8 PUSHBUTTON "Lock computer",IDC_LOCK,10,76,70,14 PUSHBUTTON "Log off",IDC_LOGOFF,90,76,70,14 diff --git a/dll/win32/msgina/lang/es-ES.rc b/dll/win32/msgina/lang/es-ES.rc index e09c41c75bc..ef9081caf8c 100644 --- a/dll/win32/msgina/lang/es-ES.rc +++ b/dll/win32/msgina/lang/es-ES.rc @@ -5,12 +5,13 @@ LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Por favor espere..." FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -27,7 +28,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Acceder" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Usuario:",IDC_STATIC,36,75,40,8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "Contraseña:",IDC_STATIC,36,93,42,8 @@ -37,12 +38,12 @@ BEGIN PUSHBUTTON "Cerrar",IDC_SHUTDOWN,179,122,50,14 END -IDD_LOGGEDON_DLG DIALOGEX 0, 0, 261, 116 +IDD_LOGGEDON_DLG DIALOGEX 0, 0, 275, 116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "Seguridad" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "¿Qué quieres hacer?",IDC_STATIC, 94, 60, 87, 8 PUSHBUTTON "Bloquear computadora",IDC_LOCK, 4, 76, 83, 14 PUSHBUTTON "Salir",IDC_LOGOFF, 92, 76, 88, 14 diff --git a/dll/win32/msgina/lang/fr-FR.rc b/dll/win32/msgina/lang/fr-FR.rc index 34590cd0cad..67a2214684c 100644 --- a/dll/win32/msgina/lang/fr-FR.rc +++ b/dll/win32/msgina/lang/fr-FR.rc @@ -1,11 +1,12 @@ LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Veuillez patienter..." FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -22,7 +23,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Connexion" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Utilisateur:",IDC_STATIC,36,75,40,8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "Mot de passe:",IDC_STATIC,36,93,42,8 @@ -32,12 +33,12 @@ BEGIN PUSHBUTTON "Éteindre",IDC_SHUTDOWN,179,122,50,14 END -IDD_LOGGEDON_DLG DIALOGEX 0, 0, 258, 116 +IDD_LOGGEDON_DLG DIALOGEX 0, 0, 275, 116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "Sécurité" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Que voulez vous faire?",IDC_STATIC, 94, 60, 87, 8 PUSHBUTTON "Verrouiller l'ordinateur",IDC_LOCK, 4, 76, 82, 14 PUSHBUTTON "Déconnecter",IDC_LOGOFF, 93, 76, 85, 14 diff --git a/dll/win32/msgina/lang/id-ID.rc b/dll/win32/msgina/lang/id-ID.rc index c73970da164..42352671ec3 100644 --- a/dll/win32/msgina/lang/id-ID.rc +++ b/dll/win32/msgina/lang/id-ID.rc @@ -1,11 +1,12 @@ LANGUAGE LANG_INDONESIAN, SUBLANG_DEFAULT -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Harap menunggu..." FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -22,7 +23,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Masuk" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Nama pengguna:",IDC_STATIC,22, 75, 61, 8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "Kata sandi:",IDC_STATIC, 40, 93, 42, 8 @@ -32,12 +33,12 @@ BEGIN PUSHBUTTON "Matikan",IDC_SHUTDOWN,179,122,50,14 END -IDD_LOGGEDON_DLG DIALOGEX 0,0,247,116 +IDD_LOGGEDON_DLG DIALOGEX 0,0,275,116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "Keamanan" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Apa yang ingin anda lakukan?",IDC_STATIC,86,60,87,8 PUSHBUTTON "Kunci komputer",IDC_LOCK,10,76,70,14 PUSHBUTTON "Keluar",IDC_LOGOFF,90,76,70,14 diff --git a/dll/win32/msgina/lang/it-IT.rc b/dll/win32/msgina/lang/it-IT.rc index 3d2526e07c9..911360511be 100644 --- a/dll/win32/msgina/lang/it-IT.rc +++ b/dll/win32/msgina/lang/it-IT.rc @@ -8,12 +8,13 @@ LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Attendere..." FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -30,7 +31,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Logon" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Utente:",IDC_STATIC,36,75,40,8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "Password:",IDC_STATIC,36,93,42,8 @@ -40,12 +41,12 @@ BEGIN PUSHBUTTON "Spegnimento",IDC_SHUTDOWN,179,122,50,14 END -IDD_LOGGEDON_DLG DIALOGEX 0,0,247,116 +IDD_LOGGEDON_DLG DIALOGEX 0,0,275,116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "Sicurezza" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Cosa volete fare?",IDC_STATIC,86,60,87,8 PUSHBUTTON "Bloccare il computer",IDC_LOCK,10,76,70,14 PUSHBUTTON "Fine sessione",IDC_LOGOFF,90,76,70,14 diff --git a/dll/win32/msgina/lang/ja-JP.rc b/dll/win32/msgina/lang/ja-JP.rc index 05a1dd7ee66..187a3b164bd 100644 --- a/dll/win32/msgina/lang/ja-JP.rc +++ b/dll/win32/msgina/lang/ja-JP.rc @@ -1,11 +1,12 @@ LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "お待ちください..." FONT 9, "MS UI Gothic",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -22,7 +23,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "ログオン" FONT 9, "MS UI Gothic",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "ユーザー名:",IDC_STATIC,36,75,40,8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "パスワード:",IDC_STATIC,36,93,42,8 @@ -32,12 +33,12 @@ BEGIN PUSHBUTTON "シャットダウン",IDC_SHUTDOWN,179,122,50,14 END -IDD_LOGGEDON_DLG DIALOGEX 0,0,247,116 +IDD_LOGGEDON_DLG DIALOGEX 0,0,275,116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "セキュリティ" FONT 9, "MS UI Gothic",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "何をしますか?",IDC_STATIC,86,60,87,8 PUSHBUTTON "コンピュータのロック",IDC_LOCK,10,76,70,14 PUSHBUTTON "ログオフ",IDC_LOGOFF,90,76,70,14 diff --git a/dll/win32/msgina/lang/no-NO.rc b/dll/win32/msgina/lang/no-NO.rc index bf230ac6601..46b827e0793 100644 --- a/dll/win32/msgina/lang/no-NO.rc +++ b/dll/win32/msgina/lang/no-NO.rc @@ -1,11 +1,12 @@ LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Vent litt..." FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -22,7 +23,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Logg på ReactOS" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Brukernavn:",IDC_STATIC,36,75,40,8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "Passord:",IDC_STATIC,36,93,42,8 @@ -32,12 +33,12 @@ BEGIN PUSHBUTTON "Avslutt",IDC_SHUTDOWN,179,122,50,14 END -IDD_LOGGEDON_DLG DIALOGEX 0, 0, 247, 116 +IDD_LOGGEDON_DLG DIALOGEX 0, 0, 275, 116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "ReactOS-sikkerhet" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Hva vil du gjøre?",IDC_STATIC, 92, 60, 87, 8 PUSHBUTTON "Lås datamaskinen...",IDC_LOCK, 7, 76, 74, 14 PUSHBUTTON "Logg av...",IDC_LOGOFF, 86, 76, 78, 14 diff --git a/dll/win32/msgina/lang/pl-PL.rc b/dll/win32/msgina/lang/pl-PL.rc index e84685e5ce8..a539dc39a06 100644 --- a/dll/win32/msgina/lang/pl-PL.rc +++ b/dll/win32/msgina/lang/pl-PL.rc @@ -8,12 +8,13 @@ LANGUAGE LANG_POLISH, SUBLANG_DEFAULT -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Proszę czekać..." FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -30,7 +31,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Logon" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Nazwa użytkownika:",IDC_STATIC, 11, 75, 70, 8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "Hasło:",IDC_STATIC, 56, 93, 27, 8 @@ -40,12 +41,12 @@ BEGIN PUSHBUTTON "Wyłącz",IDC_SHUTDOWN,179,122,50,14 END -IDD_LOGGEDON_DLG DIALOGEX 0,0,247,116 +IDD_LOGGEDON_DLG DIALOGEX 0,0,275,116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "Bezpieczeństwo" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Co chcesz teraz zrobić?",IDC_STATIC,86,60,87,8 PUSHBUTTON "Blokada komputera",IDC_LOCK,10,76,70,14 PUSHBUTTON "Wyloguj",IDC_LOGOFF,90,76,70,14 diff --git a/dll/win32/msgina/lang/ro-RO.rc b/dll/win32/msgina/lang/ro-RO.rc index 09aa598a212..06aa1215c8d 100644 --- a/dll/win32/msgina/lang/ro-RO.rc +++ b/dll/win32/msgina/lang/ro-RO.rc @@ -1,12 +1,13 @@ //2011.12.10 - Fulea Ștefan: minor changes (corrections) LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Așteptați…" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -23,7 +24,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Autentificare" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Nume utilizator:", IDC_STATIC,36,75,40,8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "Parolă:", IDC_STATIC,36,93,42,8 @@ -33,12 +34,12 @@ BEGIN PUSHBUTTON "&Oprește", IDC_SHUTDOWN,179,122,50,14 END -IDD_LOGGEDON_DLG DIALOGEX 0,0,247,116 +IDD_LOGGEDON_DLG DIALOGEX 0,0,275,116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "Securitate" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Ce acțiune preferați?", IDC_STATIC,86,60,87,8 PUSHBUTTON "&Blochează calculatorul", IDC_LOCK,10,76,70,14 PUSHBUTTON "&Deautentifică-mă", IDC_LOGOFF,90,76,70,14 diff --git a/dll/win32/msgina/lang/ru-RU.rc b/dll/win32/msgina/lang/ru-RU.rc index 9c25b94d9fc..38b1e6907a0 100644 --- a/dll/win32/msgina/lang/ru-RU.rc +++ b/dll/win32/msgina/lang/ru-RU.rc @@ -2,12 +2,13 @@ LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Пожалуйста подождите..." FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -24,7 +25,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Вход" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 RTEXT "Имя пользователя:", IDC_STATIC, 6, 75, 70, 8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL RTEXT "Пароль:", IDC_STATIC, 6, 93, 70, 8 @@ -39,7 +40,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Безопасность" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Выберите необходимое действие:", IDC_STATIC, 7, 60, 123, 8 PUSHBUTTON "Заблокировать", IDC_LOCK, 7, 76, 86, 14 PUSHBUTTON "Завершение сеанса", IDC_LOGOFF, 102, 76, 86, 14 diff --git a/dll/win32/msgina/lang/sk-SK.rc b/dll/win32/msgina/lang/sk-SK.rc index 790a6925448..2266f5acb76 100644 --- a/dll/win32/msgina/lang/sk-SK.rc +++ b/dll/win32/msgina/lang/sk-SK.rc @@ -4,12 +4,13 @@ LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Počkajte, prosím ..." FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -26,7 +27,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Prihlásenie" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Meno používateľa:",IDC_STATIC,18, 75, 64, 8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "Heslo:",IDC_STATIC,56, 93, 24, 8 @@ -36,12 +37,12 @@ BEGIN PUSHBUTTON "Vypnúť",IDC_SHUTDOWN,179,122,50,14 END -IDD_LOGGEDON_DLG DIALOGEX 0,0,247,116 +IDD_LOGGEDON_DLG DIALOGEX 0,0,275,116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "Bezpečnosť" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Čo chcete urobiť?",IDC_STATIC,86,60,87,8 PUSHBUTTON "Uzamknúť počítač",IDC_LOCK,10,76,70,14 PUSHBUTTON "Odhlásiť",IDC_LOGOFF,90,76,70,14 diff --git a/dll/win32/msgina/lang/uk-UA.rc b/dll/win32/msgina/lang/uk-UA.rc index ffffcb84511..31de3767d77 100644 --- a/dll/win32/msgina/lang/uk-UA.rc +++ b/dll/win32/msgina/lang/uk-UA.rc @@ -8,12 +8,13 @@ LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -IDD_STATUSWINDOW_DLG DIALOGEX 0,0,274,26 +IDD_STATUSWINDOW_DLG DIALOGEX 0,0,275,80 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP CAPTION "Зачекайте..." FONT 8,"MS Shell Dlg",400,0,1 BEGIN - LTEXT "",IDC_STATUSLABEL,7,8,234,12,SS_WORDELLIPSIS + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 + LTEXT "",IDC_STATUSLABEL,7,62,261,12,SS_WORDELLIPSIS END IDD_NOTICE_DLG DIALOGEX 0, 0, 186, 32 @@ -30,7 +31,7 @@ STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS CAPTION "Вхід" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,59 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Користувач:",IDC_STATIC,33, 75, 48, 8 EDITTEXT IDC_USERNAME,84,72,119,14,ES_AUTOHSCROLL LTEXT "Пароль:",IDC_STATIC,48, 93, 34, 8 @@ -40,12 +41,12 @@ BEGIN PUSHBUTTON "Завершення роботи...",IDC_SHUTDOWN,148, 122, 86, 14 END -IDD_LOGGEDON_DLG DIALOGEX 0, 0, 257, 116 +IDD_LOGGEDON_DLG DIALOGEX 0, 0, 275, 116 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "Безпека" FONT 8,"MS Shell Dlg",400,0,1 BEGIN - CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,247,53 + CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 LTEXT "Що Ви хочете зробити?",IDC_STATIC, 86, 60, 87, 8 PUSHBUTTON "Блокування",IDC_LOCK, 6, 76, 70, 14 PUSHBUTTON "Вихід із системи...",IDC_LOGOFF, 80, 76, 80, 14 diff --git a/dll/win32/msgina/msgina.c b/dll/win32/msgina/msgina.c index 9ae65d5091f..1760da70023 100644 --- a/dll/win32/msgina/msgina.c +++ b/dll/win32/msgina/msgina.c @@ -108,7 +108,7 @@ ChooseGinaUI(VOID) if (rc != ERROR_SUCCESS) goto cleanup; - /* Check for CMDCONS in SystemStartOptions */ + /* Check for CONSOLE switch in SystemStartOptions */ CurrentOption = SystemStartOptions; while (CurrentOption) { diff --git a/dll/win32/msgina/resources/reactos.bmp b/dll/win32/msgina/resources/reactos.bmp index b5775aebecc..7fd0563b79e 100644 Binary files a/dll/win32/msgina/resources/reactos.bmp and b/dll/win32/msgina/resources/reactos.bmp differ diff --git a/dll/win32/netapi32/local_group.c b/dll/win32/netapi32/local_group.c index a02d1cceb84..546eed45a87 100644 --- a/dll/win32/netapi32/local_group.c +++ b/dll/win32/netapi32/local_group.c @@ -246,14 +246,17 @@ NET_API_STATUS WINAPI NetLocalGroupEnum( PSAM_RID_ENUMERATION CurrentAlias; PENUM_CONTEXT EnumContext = NULL; PSID DomainSid = NULL; + PLOCALGROUP_INFO_0 LocalInfo0; + PLOCALGROUP_INFO_1 LocalInfo1; + LPWSTR Ptr; ULONG i; + ULONG Size; SAM_HANDLE AliasHandle = NULL; PALIAS_GENERAL_INFORMATION AliasInfo = NULL; - + LPVOID Buffer = NULL; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status = STATUS_SUCCESS; - FIXME("(%s %d %p %d %p %p %p) stub!\n", debugstr_w(servername), level, bufptr, prefmaxlen, entriesread, totalentries, resumehandle); @@ -263,7 +266,7 @@ NET_API_STATUS WINAPI NetLocalGroupEnum( if (resumehandle != NULL && *resumehandle != 0) { - EnumContext = (PENUM_CONTEXT)resumehandle; + EnumContext = (PENUM_CONTEXT)*resumehandle; } else { @@ -334,16 +337,18 @@ NET_API_STATUS WINAPI NetLocalGroupEnum( } - while (TRUE) - { +// while (TRUE) +// { + TRACE("EnumContext->Index: %lu\n", EnumContext->Index); + TRACE("EnumContext->Returned: %lu\n", EnumContext->Returned); if (EnumContext->Index >= EnumContext->Returned) { - if (EnumContext->BuiltinDone == TRUE) - { - ApiStatus = NERR_Success; - goto done; - } +// if (EnumContext->BuiltinDone == TRUE) +// { +// ApiStatus = NERR_Success; +// goto done; +// } TRACE("Calling SamEnumerateAliasesInDomain\n"); @@ -408,6 +413,62 @@ NET_API_STATUS WINAPI NetLocalGroupEnum( TRACE("Name: %S\n", AliasInfo->Name.Buffer); TRACE("Comment: %S\n", AliasInfo->AdminComment.Buffer); + switch (level) + { + case 0: + Size = sizeof(LOCALGROUP_INFO_0) + + AliasInfo->Name.Length + sizeof(WCHAR); + break; + + case 1: + Size = sizeof(LOCALGROUP_INFO_1) + + AliasInfo->Name.Length + sizeof(WCHAR) + + AliasInfo->AdminComment.Length + sizeof(WCHAR); + break; + + default: + ApiStatus = ERROR_INVALID_LEVEL; + goto done; + } + + ApiStatus = NetApiBufferAllocate(Size, &Buffer); + if (ApiStatus != NERR_Success) + goto done; + + switch (level) + { + case 0: + LocalInfo0 = (PLOCALGROUP_INFO_0)Buffer; + + Ptr = (LPWSTR)LocalInfo0++; + LocalInfo0->lgrpi0_name = Ptr; + + memcpy(LocalInfo0->lgrpi0_name, + AliasInfo->Name.Buffer, + AliasInfo->Name.Length); + LocalInfo0->lgrpi0_name[AliasInfo->Name.Length / sizeof(WCHAR)] = UNICODE_NULL; + break; + + case 1: + LocalInfo1 = (PLOCALGROUP_INFO_1)Buffer; + + Ptr = (LPWSTR)((ULONG_PTR)LocalInfo1 + sizeof(LOCALGROUP_INFO_1)); + LocalInfo1->lgrpi1_name = Ptr; + + memcpy(LocalInfo1->lgrpi1_name, + AliasInfo->Name.Buffer, + AliasInfo->Name.Length); + LocalInfo1->lgrpi1_name[AliasInfo->Name.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + AliasInfo->Name.Length + sizeof(WCHAR)); + LocalInfo1->lgrpi1_comment = Ptr; + + memcpy(LocalInfo1->lgrpi1_comment, + AliasInfo->AdminComment.Buffer, + AliasInfo->AdminComment.Length); + LocalInfo1->lgrpi1_comment[AliasInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; + break; + } if (AliasInfo != NULL) { @@ -421,12 +482,19 @@ NET_API_STATUS WINAPI NetLocalGroupEnum( AliasInfo = NULL; } - EnumContext->Index++; - } + (*entriesread)++; + +// } done: + if (ApiStatus == NERR_Success && EnumContext->Index < EnumContext->Returned) + ApiStatus = ERROR_MORE_DATA; + + if (EnumContext != NULL) + *totalentries = EnumContext->Returned; + if (resumehandle == NULL || ApiStatus != ERROR_MORE_DATA) { if (EnumContext != NULL) @@ -472,6 +540,10 @@ done: if (resumehandle != NULL) *resumehandle = (DWORD_PTR)EnumContext; + *bufptr = (LPBYTE)Buffer; + + TRACE ("return %lu\n", ApiStatus); + return ApiStatus; } diff --git a/dll/win32/syssetup/install.c b/dll/win32/syssetup/install.c index 8b1450cc67d..7e671bbc24b 100644 --- a/dll/win32/syssetup/install.c +++ b/dll/win32/syssetup/install.c @@ -558,7 +558,7 @@ IsConsoleBoot(VOID) if (rc != ERROR_SUCCESS) goto cleanup; - /* Check for CMDCONS in SystemStartOptions */ + /* Check for CONSOLE switch in SystemStartOptions */ pwszCurrentOption = pwszSystemStartOptions; while (pwszCurrentOption) { diff --git a/include/psdk/ntlsa.h b/include/psdk/ntlsa.h index 188c696ae28..60c41d6459a 100644 --- a/include/psdk/ntlsa.h +++ b/include/psdk/ntlsa.h @@ -30,9 +30,20 @@ extern "C" { #define ACCOUNT_ADJUST_QUOTAS 4 #define ACCOUNT_ADJUST_SYSTEM_ACCESS 8 +#define ACCOUNT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 15) +#define ACCOUNT_READ (STANDARD_RIGHTS_READ | 1) +#define ACCOUNT_WRITE (STANDARD_RIGHTS_WRITE | 14) +#define ACCOUNT_EXECUTE (STANDARD_RIGHTS_EXECUTE) + #define SECRET_SET_VALUE 1 #define SECRET_QUERY_VALUE 2 +#define SECRET_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 3) +#define SECRET_READ (STANDARD_RIGHTS_READ | 2) +#define SECRET_WRITE (STANDARD_RIGHTS_WRITE | 1) +#define SECRET_EXECUTE (STANDARD_RIGHTS_EXECUTE) + + /* System Access Flags */ #define SECURITY_ACCESS_INTERACTIVE_LOGON 0x00000001 #define SECURITY_ACCESS_NETWORK_LOGON 0x00000002 diff --git a/include/psdk/winerror.h b/include/psdk/winerror.h index e83050d1f18..e6b397818bb 100644 --- a/include/psdk/winerror.h +++ b/include/psdk/winerror.h @@ -838,6 +838,7 @@ #define ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION 1459 #define ERROR_TIMEOUT 1460 #define ERROR_INVALID_MONITOR_HANDLE 1461 +#define ERROR_INCORRECT_SIZE 1462 #define ERROR_EVENTLOG_FILE_CORRUPT 1500 #define ERROR_EVENTLOG_CANT_START 1501 #define ERROR_LOG_FILE_FULL 1502 diff --git a/lib/sdk/crt/stdio/file.c b/lib/sdk/crt/stdio/file.c index 7c063754606..e1e045f94fb 100644 --- a/lib/sdk/crt/stdio/file.c +++ b/lib/sdk/crt/stdio/file.c @@ -7,6 +7,14 @@ * Ported to ReactOS by Aleksey Bragin (aleksey@reactos.org) */ +/********************************************* + * This file contains ReactOS changes!! + * Don't blindly sync it with Wine code! + * + * If you break Unicode output on the console again, please update this counter: + * int hours_wasted_on_this = 42; + *********************************************/ + /* * msvcrt.dll file functions * @@ -2505,13 +2513,38 @@ size_t CDECL fwrite(const void *ptr, size_t size, size_t nmemb, FILE* file) /********************************************************************* * fputwc (MSVCRT.@) + * FORKED for ReactOS, don't sync with Wine! + * References: + * - http://jira.reactos.org/browse/CORE-6495 + * - http://bugs.winehq.org/show_bug.cgi?id=8598 */ -wint_t CDECL fputwc(wint_t wc, FILE* file) +wint_t CDECL fputwc(wchar_t c, FILE* stream) { - wchar_t mwc=wc; - if (fwrite( &mwc, sizeof(mwc), 1, file) != 1) - return WEOF; - return wc; + /* If this is a real file stream (and not some temporary one for + sprintf-like functions), check whether it is opened in text mode. + In this case, we have to perform an implicit conversion to ANSI. */ + if (!(stream->_flag & _IOSTRG) && get_ioinfo(stream->_file)->wxflag & WX_TEXT) + { + /* Convert to multibyte in text mode */ + char mbc[MB_LEN_MAX]; + int mb_return; + + mb_return = wctomb(mbc, c); + + if(mb_return == -1) + return WEOF; + + /* Output all characters */ + if (fwrite(mbc, mb_return, 1, stream) != 1) + return WEOF; + } + else + { + if (fwrite(&c, sizeof(c), 1, stream) != 1) + return WEOF; + } + + return c; } /********************************************************************* diff --git a/media/vgafonts/CMakeLists.txt b/media/vgafonts/CMakeLists.txt index 9ca1ccac40c..a0987bca31c 100644 --- a/media/vgafonts/CMakeLists.txt +++ b/media/vgafonts/CMakeLists.txt @@ -16,4 +16,5 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vgafonts.cab add_custom_target(vgafonts DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/vgafonts.cab) -add_cd_file(TARGET vgafonts FILE ${CMAKE_CURRENT_BINARY_DIR}/vgafonts.cab DESTINATION reactos NO_CAB FOR all) \ No newline at end of file +add_cd_file(TARGET vgafonts FILE ${CMAKE_CURRENT_BINARY_DIR}/vgafonts.cab DESTINATION reactos NO_CAB FOR all) +add_cd_file(TARGET vgafonts FILE ${CMAKE_CURRENT_BINARY_DIR}/vgafonts.cab DESTINATION reactos FOR all) \ No newline at end of file diff --git a/ntoskrnl/config/cmsysini.c b/ntoskrnl/config/cmsysini.c index d917dfbd6b9..dc03e96fdb8 100644 --- a/ntoskrnl/config/cmsysini.c +++ b/ntoskrnl/config/cmsysini.c @@ -359,9 +359,9 @@ CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock) CmpLoadOptions.Length); if (!NT_SUCCESS(Status)) goto Quickie; - /* Setup value name for system boot device */ + /* Setup value name for system boot device in ARC format */ RtlInitUnicodeString(&KeyName, L"SystemBootDevice"); - RtlCreateUnicodeStringFromAsciiz(&ValueName, LoaderBlock->NtBootPathName); + RtlCreateUnicodeStringFromAsciiz(&ValueName, LoaderBlock->ArcBootDeviceName); Status = NtSetValueKey(KeyHandle, &KeyName, 0, diff --git a/win32ss/gdi/eng/mouse.c b/win32ss/gdi/eng/mouse.c index ecc18e2f110..0600f266fb7 100644 --- a/win32ss/gdi/eng/mouse.c +++ b/win32ss/gdi/eng/mouse.c @@ -232,29 +232,51 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest) /* Blt the pointer on the screen. */ if (pgp->psurfColor) { - IntEngBitBlt(psoDest, - &pgp->psurfMask->SurfObj, - NULL, - NULL, - NULL, - &rclSurf, - (POINTL*)&rclPointer, - NULL, - NULL, - NULL, - ROP4_FROM_INDEX(R3_OPINDEX_SRCAND)); + if(!(pgp->flags & SPS_ALPHA)) + { + IntEngBitBlt(psoDest, + &pgp->psurfMask->SurfObj, + NULL, + NULL, + NULL, + &rclSurf, + (POINTL*)&rclPointer, + NULL, + NULL, + NULL, + ROP4_SRCAND); - IntEngBitBlt(psoDest, - &pgp->psurfColor->SurfObj, - NULL, - NULL, - NULL, - &rclSurf, - (POINTL*)&rclPointer, - NULL, - NULL, - NULL, - ROP4_FROM_INDEX(R3_OPINDEX_SRCINVERT)); + IntEngBitBlt(psoDest, + &pgp->psurfColor->SurfObj, + NULL, + NULL, + NULL, + &rclSurf, + (POINTL*)&rclPointer, + NULL, + NULL, + NULL, + ROP4_SRCINVERT); + } + else + { + BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } }; + EXLATEOBJ exlo; + EXLATEOBJ_vInitialize(&exlo, + pgp->psurfColor->ppal, + ppdev->ppalSurf, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0); + IntEngAlphaBlend(psoDest, + &pgp->psurfColor->SurfObj, + NULL, + &exlo.xlo, + &rclSurf, + &rclPointer, + &blendobj); + EXLATEOBJ_vCleanup(&exlo); + } } else { @@ -352,7 +374,15 @@ EngSetPointerShape( if (psoColor) { /* Color bitmap must have the same format as the dest surface */ - if (psoColor->iBitmapFormat != pso->iBitmapFormat) goto failure; + if (psoColor->iBitmapFormat != pso->iBitmapFormat) + { + /* It's OK if we have an alpha bitmap */ + if(!(fl & SPS_ALPHA)) + { + DPRINT1("Screen surface and cursor color bitmap format don't match!.\n"); + goto failure; + } + } /* Create a bitmap to copy the color bitmap to */ hbmColor = EngCreateBitmap(psoColor->sizlBitmap, @@ -452,6 +482,7 @@ EngSetPointerShape( pgp->HotSpot.x = xHot; pgp->HotSpot.y = yHot; pgp->Size = sizel; + pgp->flags = fl; if (x != -1) { @@ -598,12 +629,12 @@ GreSetPointerShape( LONG xHot, LONG yHot, LONG x, - LONG y) + LONG y, + FLONG fl) { PDC pdc; PSURFACE psurf, psurfMask, psurfColor; EXLATEOBJ exlo; - FLONG fl = 0; ULONG ulResult = 0; pdc = DC_LockDc(hdc); @@ -629,7 +660,10 @@ GreSetPointerShape( if (hbmMask) psurfMask = SURFACE_ShareLockSurface(hbmMask); else + { + ASSERT(fl & SPS_ALPHA); psurfMask = NULL; + } /* Check for color bitmap */ if (hbmColor) @@ -645,6 +679,9 @@ GreSetPointerShape( } else psurfColor = NULL; + + /* We must have a valid surface in case of alpha bitmap */ + ASSERT(((fl & SPS_ALPHA) && psurfColor) || !(fl & SPS_ALPHA)); /* Call the driver or eng function */ ulResult = IntEngSetPointerShape(&psurf->SurfObj, diff --git a/win32ss/gdi/eng/mouse.h b/win32ss/gdi/eng/mouse.h index 414f49c24c3..719be1e77bc 100644 --- a/win32ss/gdi/eng/mouse.h +++ b/win32ss/gdi/eng/mouse.h @@ -12,7 +12,8 @@ GreSetPointerShape( LONG xHot, LONG yHot, LONG x, - LONG y); + LONG y, + FLONG fl); VOID NTAPI diff --git a/win32ss/gdi/eng/pdevobj.h b/win32ss/gdi/eng/pdevobj.h index 77f315b65ab..4f3a6496858 100644 --- a/win32ss/gdi/eng/pdevobj.h +++ b/win32ss/gdi/eng/pdevobj.h @@ -34,6 +34,7 @@ typedef struct _GDIPOINTER /* should stay private to ENG? No, part of PDEVOBJ ak SURFACE *psurfColor; SURFACE *psurfMask; SURFACE *psurfSave; + FLONG flags; /* Public pointer information */ RECTL Exclude; /* Required publicly for SPS_ACCEPT_EXCLUDE */ diff --git a/win32ss/gdi/ntgdi/dc.h b/win32ss/gdi/ntgdi/dc.h index c5f7cf54362..6817f6f0ee5 100644 --- a/win32ss/gdi/ntgdi/dc.h +++ b/win32ss/gdi/ntgdi/dc.h @@ -173,6 +173,7 @@ UINT FASTCALL IntGdiSetTextAlign(HDC hDC, UINT Mode); VOID FASTCALL DCU_SetDcUndeletable(HDC); BOOL FASTCALL IntSetDefaultRegion(PDC); ULONG TranslateCOLORREF(PDC pdc, COLORREF crColor); +int FASTCALL GreSetStretchBltMode(HDC hdc, int iStretchMode); diff --git a/win32ss/gdi/ntgdi/dcutil.c b/win32ss/gdi/ntgdi/dcutil.c index 5fe2f52491a..d7f05af8cad 100644 --- a/win32ss/gdi/ntgdi/dcutil.c +++ b/win32ss/gdi/ntgdi/dcutil.c @@ -96,6 +96,29 @@ IntGdiSetTextColor(HDC hDC, return crOldColor; } +int +FASTCALL +GreSetStretchBltMode(HDC hDC, int iStretchMode) +{ + PDC pdc; + PDC_ATTR pdcattr; + INT oSMode = 0; + + pdc = DC_LockDc(hDC); + if (pdc) + { + pdcattr = pdc->pdcattr; + oSMode = pdcattr->lStretchBltMode; + pdcattr->lStretchBltMode = iStretchMode; + + // Wine returns an error here. We set the default. + if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK; + + pdcattr->jStretchBltMode = iStretchMode; + } + return oSMode; +} + VOID FASTCALL DCU_SetDcUndeletable(HDC hDC) diff --git a/win32ss/gdi/ntgdi/dib.h b/win32ss/gdi/ntgdi/dib.h index 7eabbdf397c..2c679598750 100644 --- a/win32ss/gdi/ntgdi/dib.h +++ b/win32ss/gdi/ntgdi/dib.h @@ -7,8 +7,11 @@ int FASTCALL DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width, INT APIENTRY DIB_GetDIBImageBytes (INT width, INT height, INT depth); HPALETTE FASTCALL DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi); HPALETTE FASTCALL BuildDIBPalette (CONST BITMAPINFO *bmi); + +/* Those functions permit to tranparently work with a BITMAPCOREINFO structure */ BITMAPINFO* FASTCALL DIB_ConvertBitmapInfo(CONST BITMAPINFO* bmi, DWORD Usage); -VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig); +/* Pass Usage = -1 if you don't want to convert the BITMAPINFO back to BITMAPCOREINFO */ +VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig, DWORD Usage); INT APIENTRY diff --git a/win32ss/gdi/ntgdi/dibobj.c b/win32ss/gdi/ntgdi/dibobj.c index ed8876f75db..f1bd2489a18 100644 --- a/win32ss/gdi/ntgdi/dibobj.c +++ b/win32ss/gdi/ntgdi/dibobj.c @@ -584,7 +584,6 @@ GreGetDIBitsInternal( DWORD compr, size ; USHORT i; int bitmap_type; - RGBTRIPLE* rgbTriples; RGBQUAD* rgbQuads; VOID* colorPtr; @@ -594,7 +593,6 @@ GreGetDIBitsInternal( return 0; colorPtr = (LPBYTE)Info + Info->bmiHeader.biSize; - rgbTriples = colorPtr; rgbQuads = colorPtr; bitmap_type = DIB_GetBitmapInfo(&Info->bmiHeader, @@ -643,15 +641,6 @@ GreGetDIBitsInternal( switch(bpp) { case 0: /* Only info */ - if(pbmci) - { - pbmci->bmciHeader.bcWidth = (WORD)psurf->SurfObj.sizlBitmap.cx; - pbmci->bmciHeader.bcHeight = (WORD)((psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ? - -psurf->SurfObj.sizlBitmap.cy : - psurf->SurfObj.sizlBitmap.cy); - pbmci->bmciHeader.bcPlanes = 1; - pbmci->bmciHeader.bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat); - } Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx; Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ? -psurf->SurfObj.sizlBitmap.cy : @@ -702,31 +691,19 @@ GreGetDIBitsInternal( if(Usage == DIB_RGB_COLORS) { ULONG colors = min(psurf->ppal->NumColors, 256); - - if(pbmci) - { - for(i = 0; i < colors; i++) - { - rgbTriples[i].rgbtRed = psurf->ppal->IndexedColors[i].peRed; - rgbTriples[i].rgbtGreen = psurf->ppal->IndexedColors[i].peGreen; - rgbTriples[i].rgbtBlue = psurf->ppal->IndexedColors[i].peBlue; - } - } if(colors != 256) Info->bmiHeader.biClrUsed = colors; for(i = 0; i < colors; i++) { rgbQuads[i].rgbRed = psurf->ppal->IndexedColors[i].peRed; rgbQuads[i].rgbGreen = psurf->ppal->IndexedColors[i].peGreen; rgbQuads[i].rgbBlue = psurf->ppal->IndexedColors[i].peBlue; + rgbQuads[i].rgbReserved = 0; } } else { for(i = 0; i < 256; i++) - { - if(pbmci) ((WORD*)rgbTriples)[i] = i; ((WORD*)rgbQuads)[i] = i; - } } } else @@ -735,7 +712,6 @@ GreGetDIBitsInternal( { for(i = 0; i < 256; i++) { - if(pbmci) ((WORD*)rgbTriples)[i] = i; ((WORD*)rgbQuads)[i] = i; } } @@ -752,13 +728,6 @@ GreGetDIBitsInternal( } for (i = 0; i < pDcPal->NumColors; i++) { - if (pbmci) - { - rgbTriples[i].rgbtRed = pDcPal->IndexedColors[i].peRed; - rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen; - rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue; - } - rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed; rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen; rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue; @@ -771,55 +740,20 @@ GreGetDIBitsInternal( switch (bpp) { case 1: - if (pbmci) - { - rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen = - rgbTriples[0].rgbtBlue = 0; - rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen = - rgbTriples[1].rgbtBlue = 0xff; - } - rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = - rgbQuads[0].rgbBlue = 0; + rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = rgbQuads[0].rgbBlue = 0; rgbQuads[0].rgbReserved = 0; - rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = - rgbQuads[1].rgbBlue = 0xff; + rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = rgbQuads[1].rgbBlue = 0xff; rgbQuads[1].rgbReserved = 0; break; case 4: - if (pbmci) - RtlCopyMemory(rgbTriples, EGAColorsTriples, sizeof(EGAColorsTriples)); RtlCopyMemory(rgbQuads, EGAColorsQuads, sizeof(EGAColorsQuads)); - break; case 8: { INT r, g, b; RGBQUAD *color; - if (pbmci) - { - RGBTRIPLE *colorTriple; - - RtlCopyMemory(rgbTriples, DefLogPaletteTriples, - 10 * sizeof(RGBTRIPLE)); - RtlCopyMemory(rgbTriples + 246, DefLogPaletteTriples + 10, - 10 * sizeof(RGBTRIPLE)); - colorTriple = rgbTriples + 10; - for(r = 0; r <= 5; r++) /* FIXME */ - { - for(g = 0; g <= 5; g++) - { - for(b = 0; b <= 5; b++) - { - colorTriple->rgbtRed = (r * 0xff) / 5; - colorTriple->rgbtGreen = (g * 0xff) / 5; - colorTriple->rgbtBlue = (b * 0xff) / 5; - colorTriple++; - } - } - } - } memcpy(rgbQuads, DefLogPaletteQuads, 10 * sizeof(RGBQUAD)); memcpy(rgbQuads + 246, DefLogPaletteQuads + 10, @@ -933,11 +867,8 @@ GreGetDIBitsInternal( } psurfDest = SURFACE_ShareLockSurface(hBmpDest); - - rcDest.left = 0; - rcDest.top = 0; - rcDest.bottom = ScanLines; - rcDest.right = psurf->SurfObj.sizlBitmap.cx; + + RECTL_vSetRect(&rcDest, 0, 0, ScanLines, psurf->SurfObj.sizlBitmap.cx); srcPoint.x = 0; @@ -987,7 +918,7 @@ done: if(pDC) DC_UnlockDc(pDC); if(psurf) SURFACE_ShareUnlockSurface(psurf); - if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci); + if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci, Usage); return ScanLines; } @@ -1926,10 +1857,51 @@ DIB_ConvertBitmapInfo (CONST BITMAPINFO* pbmi, DWORD Usage) /* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */ VOID FASTCALL -DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig) +DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig, DWORD usage) { - if(converted != orig) + BITMAPCOREINFO* pbmci; + if(converted == orig) + return; + + if(usage == -1) + { + /* Caller don't want any conversion */ ExFreePoolWithTag(converted, TAG_DIB); + return; + } + + /* Perform inverse conversion */ + pbmci = (BITMAPCOREINFO*)orig; + + ASSERT(pbmci->bmciHeader.bcSize == sizeof(BITMAPCOREHEADER)); + pbmci->bmciHeader.bcBitCount = converted->bmiHeader.biBitCount; + pbmci->bmciHeader.bcWidth = converted->bmiHeader.biWidth; + pbmci->bmciHeader.bcHeight = converted->bmiHeader.biHeight; + pbmci->bmciHeader.bcPlanes = converted->bmiHeader.biPlanes; + + if(pbmci->bmciHeader.bcBitCount <= 8) + { + UINT numColors = converted->bmiHeader.biClrUsed; + if(!numColors) numColors = 1 << pbmci->bmciHeader.bcBitCount; + if(usage == DIB_PAL_COLORS) + { + RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(WORD)); + RtlCopyMemory(pbmci->bmciColors, converted->bmiColors, numColors * sizeof(WORD)); + } + else + { + UINT i; + RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(RGBTRIPLE)); + for(i=0; ibmciColors[i].rgbtRed = converted->bmiColors[i].rgbRed; + pbmci->bmciColors[i].rgbtGreen = converted->bmiColors[i].rgbGreen; + pbmci->bmciColors[i].rgbtBlue = converted->bmiColors[i].rgbBlue; + } + } + } + /* Now free it, it's not needed anymore */ + ExFreePoolWithTag(converted, TAG_DIB); } /* EOF */ diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h index 5e7bf2ca53e..93b7ee9e540 100644 --- a/win32ss/include/ntuser.h +++ b/win32ss/include/ntuser.h @@ -976,6 +976,43 @@ typedef struct tagSETCLIPBDATA BOOL fIncSerialNumber; } SETCLIPBDATA, *PSETCLIPBDATA; +// Used with NtUserSetCursorIconData, last parameter. +typedef struct tagCURSORDATA +{ + LPWSTR lpName; + LPWSTR lpModName; + USHORT rt; + USHORT dummy; + ULONG CURSORF_flags; + SHORT xHotspot; + SHORT yHotspot; + HBITMAP hbmMask; + HBITMAP hbmColor; + HBITMAP hbmAlpha; + RECT rcBounds; + HBITMAP hbmUserAlpha; // Could be in W7U, not in W2k + ULONG bpp; + ULONG cx; + ULONG cy; + INT cpcur; + INT cicur; + struct tagCURSORDATA * aspcur; + DWORD * aicur; + INT * ajifRate; + INT iicur; +} CURSORDATA, *PCURSORDATA; /* !dso CURSORDATA */ + +// CURSORF_flags: +#define CURSORF_FROMRESOURCE 0x0001 +#define CURSORF_GLOBAL 0x0002 +#define CURSORF_LRSHARED 0x0004 +#define CURSORF_ACON 0x0008 +#define CURSORF_WOWCLEANUP 0x0010 +#define CURSORF_ACONFRAME 0x0040 +#define CURSORF_SECRET 0x0080 +#define CURSORF_LINKED 0x0100 +#define CURSORF_CURRENT 0x0200 + DWORD NTAPI NtUserAssociateInputContext( @@ -2737,15 +2774,21 @@ NtUserSetCursorIconData( _In_ HCURSOR hCursor, _In_ PUNICODE_STRING pustrModule, _In_ PUNICODE_STRING puSrcName, - _In_ PICONINFO pii); + _In_ PCURSORDATA pCursorData); + +typedef struct _tagFINDEXISTINGCURICONPARAM +{ + BOOL bIcon; + LONG cx; + LONG cy; +} FINDEXISTINGCURICONPARAM; HICON NTAPI NtUserFindExistingCursorIcon( _In_ PUNICODE_STRING pustrModule, _In_ PUNICODE_STRING pustrRsrc, - _In_ LONG cxDesired, - _In_ LONG cyDesired); + _In_ FINDEXISTINGCURICONPARAM* param); #else BOOL NTAPI diff --git a/win32ss/user/consrv/console.c b/win32ss/user/consrv/console.c index e403429e53e..ee4d57c91e3 100644 --- a/win32ss/user/consrv/console.c +++ b/win32ss/user/consrv/console.c @@ -149,17 +149,33 @@ CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd) /* make console active, and insert into console list */ Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer; + /* + * If we are not in GUI-mode, start the text-mode console. If we fail, + * try to start the GUI-mode console (win32k will automatically switch + * to graphical mode, therefore no additional code is needed). + */ if (!GuiMode) { + DPRINT1("WIN32CSR: Opening text-mode console\n"); Status = TuiInitConsole(Console); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to open text-mode console, switching to gui-mode\n"); + DPRINT1("Failed to open text-mode console, switching to gui-mode, Status = 0x%08lx\n", Status); GuiMode = TRUE; } } - else /* GuiMode */ + + /* + * Try to open the GUI-mode console. Two cases are possible: + * - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case + * failed and we start GUI-mode console. + * - We are in text-mode, therefore GuiMode == FALSE, the previous test-case + * succeeded BUT we failed at starting text-mode console. Then GuiMode + * was switched to TRUE in order to try to open the console in GUI-mode. + */ + if (GuiMode) { + DPRINT1("WIN32CSR: Opening GUI-mode console\n"); Status = GuiInitConsole(Console, ShowCmd); if (!NT_SUCCESS(Status)) { @@ -167,13 +183,13 @@ CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd) RtlFreeUnicodeString(&Console->Title); DeleteCriticalSection(&Console->Lock); CloseHandle(Console->ActiveEvent); - DPRINT1("GuiInitConsole: failed\n"); + DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status); return Status; } } Status = CsrInitConsoleScreenBuffer(Console, NewBuffer); - if (! NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { ConioCleanupConsole(Console); RtlFreeUnicodeString(&Console->Title); diff --git a/win32ss/user/ntuser/clipboard.c b/win32ss/user/ntuser/clipboard.c index 72bac911b0f..64b204e8eb3 100644 --- a/win32ss/user/ntuser/clipboard.c +++ b/win32ss/user/ntuser/clipboard.c @@ -276,7 +276,7 @@ cleanup: UserReleaseDC(NULL, hdc, FALSE); if (pConvertedBmi) - DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi); + DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi, -1); } VOID static NTAPI diff --git a/win32ss/user/ntuser/cursoricon.c b/win32ss/user/ntuser/cursoricon.c index 84d8c76b4e3..f5086951d57 100644 --- a/win32ss/user/ntuser/cursoricon.c +++ b/win32ss/user/ntuser/cursoricon.c @@ -1154,6 +1154,12 @@ UserDrawIconEx( return FALSE; } + if (!psurfColor) + { + ERR("Attention HAX FIX API DrawIconEx TEST Line 37: psurfColor is NULL going with Mask!\n"); + psurfColor = SURFACE_ShareLockSurface(hbmMask); + } + psurfOffScreen = SURFACE_AllocSurface(STYPE_BITMAP, cxWidth, cyHeight, psurfColor->SurfObj.iBitmapFormat, 0, 0, NULL); diff --git a/win32ss/user/ntuser/cursoricon.h b/win32ss/user/ntuser/cursoricon.h index 842392d890f..2d001778a35 100644 --- a/win32ss/user/ntuser/cursoricon.h +++ b/win32ss/user/ntuser/cursoricon.h @@ -9,26 +9,29 @@ typedef struct tagCURICON_PROCESS } CURICON_PROCESS, *PCURICON_PROCESS; #ifdef NEW_CURSORICON -typedef struct _CURICON_FRAME -{ - HBITMAP hbmMask; - HBITMAP hbmColor; - HBITMAP hbmAlpha; -} CURICON_FRAME, *PCURICON_FRAME; - typedef struct _CURICON_OBJECT { - PROCMARKHEAD head; + PROCMARKHEAD head; + struct _tagCURSOR* pcurNext; + UNICODE_STRING strName; + USHORT atomModName; + USHORT rt; + ULONG CURSORF_flags; + SHORT xHotspot; + SHORT yHotspot; + HBITMAP hbmMask; + HBITMAP hbmColor; + HBITMAP hbmAlpha; + RECT rcBounds; + HBITMAP hbmUserAlpha; + ULONG bpp; + ULONG cx; + ULONG cy; +/* ReactOS specific, to be deleted */ LIST_ENTRY ListEntry; HANDLE Self; LIST_ENTRY ProcessList; UNICODE_STRING ustrModule; - UNICODE_STRING ustrRsrc; - SIZE Size; - BYTE Shadow; - BOOL bIcon; - POINTL ptlHotspot; - CURICON_FRAME aFrame[1]; } CURICON_OBJECT, *PCURICON_OBJECT; #else diff --git a/win32ss/user/ntuser/cursoricon_new.c b/win32ss/user/ntuser/cursoricon_new.c index e5d25ba4a05..c80df050dd8 100644 --- a/win32ss/user/ntuser/cursoricon_new.c +++ b/win32ss/user/ntuser/cursoricon_new.c @@ -27,8 +27,8 @@ #include DBG_DEFAULT_CHANNEL(UserIcon); -static PPAGED_LOOKASIDE_LIST pgProcessLookasideList; static LIST_ENTRY gCurIconList; +static PAGED_LOOKASIDE_LIST *pgProcessLookasideList; SYSTEM_CURSORINFO gSysCursorInfo; @@ -48,14 +48,14 @@ InitCursorImpl() 128); InitializeListHead(&gCurIconList); - gSysCursorInfo.Enabled = FALSE; - gSysCursorInfo.ButtonsDown = 0; - gSysCursorInfo.bClipped = FALSE; - gSysCursorInfo.LastBtnDown = 0; - gSysCursorInfo.CurrentCursorObject = NULL; - gSysCursorInfo.ShowingCursor = -1; - gSysCursorInfo.ClickLockActive = FALSE; - gSysCursorInfo.ClickLockTime = 0; + gSysCursorInfo.Enabled = FALSE; + gSysCursorInfo.ButtonsDown = 0; + gSysCursorInfo.bClipped = FALSE; + gSysCursorInfo.LastBtnDown = 0; + gSysCursorInfo.CurrentCursorObject = NULL; + gSysCursorInfo.ShowingCursor = -1; + gSysCursorInfo.ClickLockActive = FALSE; + gSysCursorInfo.ClickLockTime = 0; return TRUE; } @@ -66,6 +66,13 @@ IntGetSysCursorInfo() return &gSysCursorInfo; } +FORCEINLINE +BOOL +is_icon(PCURICON_OBJECT object) +{ + return MAKEINTRESOURCE(object->rt) == RT_ICON; +} + /* This function creates a reference for the object! */ PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon) { @@ -182,23 +189,23 @@ IntFindExistingCurIconObject( LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry) { /* See if we are looking for an icon or a cursor */ - if(CurIcon->bIcon != param->bIcon) + if(MAKEINTRESOURCE(CurIcon->rt) != (param->bIcon ? RT_ICON : RT_CURSOR)) continue; /* See if module names match */ if(RtlCompareUnicodeString(pustrModule, &CurIcon->ustrModule, TRUE) == 0) { /* They do. Now see if this is the same resource */ - if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer) && IS_INTRESOURCE(pustrRsrc->Buffer)) + if(IS_INTRESOURCE(CurIcon->strName.Buffer) && IS_INTRESOURCE(pustrRsrc->Buffer)) { - if(CurIcon->ustrRsrc.Buffer != pustrRsrc->Buffer) + if(CurIcon->strName.Buffer != pustrRsrc->Buffer) continue; } - else if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer) || IS_INTRESOURCE(pustrRsrc->Buffer)) + else if(IS_INTRESOURCE(CurIcon->strName.Buffer) || IS_INTRESOURCE(pustrRsrc->Buffer)) continue; - else if(RtlCompareUnicodeString(pustrRsrc, &CurIcon->ustrRsrc, TRUE) != 0) + else if(RtlCompareUnicodeString(pustrRsrc, &CurIcon->strName, TRUE) != 0) continue; - if ((param->cx == CurIcon->Size.cx) &&(param->cy == CurIcon->Size.cy)) + if ((param->cx == CurIcon->cx) && (param->cy == CurIcon->cy)) { if (! ReferenceCurIconByProcess(CurIcon)) { @@ -217,13 +224,12 @@ PCURICON_OBJECT IntCreateCurIconHandle(DWORD dwNumber) { PCURICON_OBJECT CurIcon; - BOOLEAN bIcon = dwNumber == 0; HANDLE hCurIcon; if(dwNumber == 0) dwNumber = 1; - CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, otCursorIcon, FIELD_OFFSET(CURICON_OBJECT, aFrame[dwNumber])); + CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT)); if (!CurIcon) { @@ -232,14 +238,13 @@ IntCreateCurIconHandle(DWORD dwNumber) } CurIcon->Self = hCurIcon; - CurIcon->bIcon = bIcon; InitializeListHead(&CurIcon->ProcessList); if (! ReferenceCurIconByProcess(CurIcon)) { ERR("Failed to add process\n"); - UserDeleteObject(hCurIcon, otCursorIcon); UserDereferenceObject(CurIcon); + UserDeleteObject(hCurIcon, otCursorIcon); return NULL; } @@ -251,11 +256,17 @@ IntCreateCurIconHandle(DWORD dwNumber) BOOLEAN FASTCALL IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi, BOOLEAN bForce) { - PSYSTEM_CURSORINFO CurInfo; HBITMAP bmpMask, bmpColor, bmpAlpha; BOOLEAN Ret, bListEmpty, bFound = FALSE; PCURICON_PROCESS Current = NULL; + /* Check if this is the current cursor */ + if(CurIcon->CURSORF_flags & CURSORF_CURRENT) + { + UserDereferenceObject(CurIcon); + return FALSE; + } + /* For handles created without any data (error handling) */ if(IsListEmpty(&CurIcon->ProcessList)) goto emptyList; @@ -308,40 +319,32 @@ emptyList: /* Remove it from the list */ RemoveEntryList(&CurIcon->ListEntry); - CurInfo = IntGetSysCursorInfo(); - - if (CurInfo->CurrentCursorObject == CurIcon) - { - /* Hide the cursor if we're destroying the current cursor */ - UserSetCursor(NULL, TRUE); - } - - bmpMask = CurIcon->aFrame[0].hbmMask; - bmpColor = CurIcon->aFrame[0].hbmColor; - bmpAlpha = CurIcon->aFrame[0].hbmAlpha; + bmpMask = CurIcon->hbmMask; + bmpColor = CurIcon->hbmColor; + bmpAlpha = CurIcon->hbmAlpha; /* Delete bitmaps */ if (bmpMask) { GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED); GreDeleteObject(bmpMask); - CurIcon->aFrame[0].hbmMask = NULL; + CurIcon->hbmMask = NULL; } if (bmpColor) { GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED); GreDeleteObject(bmpColor); - CurIcon->aFrame[0].hbmColor = NULL; + CurIcon->hbmColor = NULL; } if (bmpAlpha) { GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED); GreDeleteObject(bmpAlpha); - CurIcon->aFrame[0].hbmAlpha = NULL; + CurIcon->hbmAlpha = NULL; } - if(!IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer)) - ExFreePoolWithTag(CurIcon->ustrRsrc.Buffer, TAG_STRING); + if(!IS_INTRESOURCE(CurIcon->strName.Buffer)) + ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING); if(CurIcon->ustrModule.Buffer) ReleaseCapturedUnicodeString(&CurIcon->ustrModule, UserMode); @@ -408,27 +411,16 @@ NtUserGetIconInfo( if(IconInfo) { /* Fill data */ - ii.fIcon = CurIcon->bIcon; - ii.xHotspot = CurIcon->ptlHotspot.x; - ii.yHotspot = CurIcon->ptlHotspot.y; + ii.fIcon = is_icon(CurIcon); + ii.xHotspot = CurIcon->xHotspot; + ii.yHotspot = CurIcon->yHotspot; /* Copy bitmaps */ - ii.hbmMask = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmMask); + ii.hbmMask = BITMAP_CopyBitmap(CurIcon->hbmMask); GreSetObjectOwner(ii.hbmMask, GDI_OBJ_HMGR_POWNED); - ii.hbmColor = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmColor); + ii.hbmColor = BITMAP_CopyBitmap(CurIcon->hbmColor); GreSetObjectOwner(ii.hbmColor, GDI_OBJ_HMGR_POWNED); - - if (pbpp) - { - PSURFACE psurfBmp; - - psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor); - if (psurfBmp) - { - colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat); - SURFACE_ShareUnlockSurface(psurfBmp); - } - } + colorBpp = CurIcon->bpp; /* Copy fields */ _SEH2_TRY @@ -487,7 +479,7 @@ NtUserGetIconInfo( if(lpResName) { - if(!CurIcon->ustrRsrc.Buffer) + if(!CurIcon->strName.Buffer) { EngSetLastError(ERROR_INVALID_HANDLE); goto leave; @@ -496,15 +488,15 @@ NtUserGetIconInfo( _SEH2_TRY { ProbeForWrite(lpResName, sizeof(UNICODE_STRING), 1); - if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer)) + if(IS_INTRESOURCE(CurIcon->strName.Buffer)) { - lpResName->Buffer = CurIcon->ustrRsrc.Buffer; + lpResName->Buffer = CurIcon->strName.Buffer; lpResName->Length = 0; } else { - lpResName->Length = min(lpResName->MaximumLength, CurIcon->ustrRsrc.Length); - RtlCopyMemory(lpResName->Buffer, CurIcon->ustrRsrc.Buffer, lpResName->Length); + lpResName->Length = min(lpResName->MaximumLength, CurIcon->strName.Length); + RtlCopyMemory(lpResName->Buffer, CurIcon->strName.Buffer, lpResName->Length); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -558,9 +550,9 @@ NtUserGetIconSize( _SEH2_TRY { ProbeForWrite(plcx, sizeof(LONG), 1); - RtlCopyMemory(plcx, &CurIcon->Size.cx, sizeof(LONG)); + *plcx = CurIcon->cx; ProbeForWrite(plcy, sizeof(LONG), 1); - RtlCopyMemory(plcy, &CurIcon->Size.cy, sizeof(LONG)); + *plcy = CurIcon->cy; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -788,7 +780,7 @@ NtUserFindExistingCursorIcon( _SEH2_TRY { ProbeForRead(param, sizeof(*param), 1); - paramSafe = *param; + RtlCopyMemory(¶mSafe, param, sizeof(paramSafe)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -882,6 +874,7 @@ NtUserSetCursor( EngSetLastError(ERROR_INVALID_CURSOR_HANDLE); goto leave; } + pcurNew->CURSORF_flags |= CURSORF_CURRENT; } else { @@ -892,6 +885,7 @@ NtUserSetCursor( if (pcurOld) { hOldCursor = (HCURSOR)pcurOld->Self; + pcurOld->CURSORF_flags &= ~CURSORF_CURRENT; UserDereferenceObject(pcurOld); } @@ -902,7 +896,7 @@ leave: /* - * @implemented + * @unimplemented */ BOOL APIENTRY @@ -910,150 +904,8 @@ NtUserSetCursorContents( HANDLE hCurIcon, PICONINFO UnsafeIconInfo) { - PCURICON_OBJECT CurIcon; - ICONINFO IconInfo; - PSURFACE psurfBmp; - NTSTATUS Status; - BOOL Ret = FALSE; - DECLARE_RETURN(BOOL); - - TRACE("Enter NtUserSetCursorContents\n"); - UserEnterExclusive(); - - if (!(CurIcon = UserGetCurIconObject(hCurIcon))) - { - RETURN(FALSE); - } - - /* Copy fields */ - Status = MmCopyFromCaller(&IconInfo, UnsafeIconInfo, sizeof(ICONINFO)); - if (!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - goto done; - } - -#if 0 - /* Check if we get valid information */ - if(IconInfo.fIcon != CurInfo->bIcon) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - goto done; - } -#endif - - /* Delete old bitmaps */ - if (CurIcon->aFrame[0].hbmColor) - GreDeleteObject(CurIcon->aFrame[0].hbmColor); - if (CurIcon->aFrame[0].hbmMask) - GreDeleteObject(CurIcon->aFrame[0].hbmMask); - if(CurIcon->aFrame[0].hbmAlpha) - GreDeleteObject(CurIcon->aFrame[0].hbmAlpha); - - /* Set fields */ - CurIcon->bIcon = IconInfo.fIcon; - CurIcon->ptlHotspot.x = IconInfo.xHotspot; - CurIcon->ptlHotspot.y = IconInfo.yHotspot; - CurIcon->aFrame[0].hbmMask = IconInfo.hbmMask; - CurIcon->aFrame[0].hbmColor = IconInfo.hbmColor; - CurIcon->aFrame[0].hbmAlpha = NULL; - - if (IconInfo.hbmColor) - { - BOOLEAN bAlpha = FALSE; - psurfBmp = SURFACE_ShareLockSurface(IconInfo.hbmColor); - if (!psurfBmp) - goto done; - CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx; - CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy; - - /* 32bpp bitmap is likely to have an alpha channel */ - if(psurfBmp->SurfObj.iBitmapFormat == BMF_32BPP) - { - PFN_DIB_GetPixel fn_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel; - INT i, j; - - fn_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel; - for (i = 0; i < psurfBmp->SurfObj.sizlBitmap.cx; i++) - { - for (j = 0; j < psurfBmp->SurfObj.sizlBitmap.cy; j++) - { - bAlpha = ((BYTE)(fn_GetPixel(&psurfBmp->SurfObj, i, j) >> 24)) != 0; - if (bAlpha) - break; - } - if (bAlpha) - break; - } - } - /* We're done with this one */ - SURFACE_ShareUnlockSurface(psurfBmp); - GreSetObjectOwner(IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC); - - if(bAlpha) - { - UCHAR Alpha; - PUCHAR ptr; - INT i, j; - /* Copy the bitmap */ - CurIcon->aFrame[0].hbmAlpha = BITMAP_CopyBitmap(IconInfo.hbmColor); - if(!CurIcon->aFrame[0].hbmAlpha) - { - ERR("BITMAP_CopyBitmap failed!"); - goto done; - } - - psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmAlpha); - if(!psurfBmp) - { - ERR("SURFACE_LockSurface failed!\n"); - goto done; - } - - /* Premultiply with the alpha channel value */ - for (i = 0; i < psurfBmp->SurfObj.sizlBitmap.cy; i++) - { - ptr = (PBYTE)psurfBmp->SurfObj.pvScan0 + i*psurfBmp->SurfObj.lDelta; - for (j = 0; j < psurfBmp->SurfObj.sizlBitmap.cx; j++) - { - Alpha = ptr[3]; - ptr[0] = (ptr[0] * Alpha) / 0xff; - ptr[1] = (ptr[1] * Alpha) / 0xff; - ptr[2] = (ptr[2] * Alpha) / 0xff; - ptr += 4; - } - } - SURFACE_ShareUnlockSurface(psurfBmp); - GreSetObjectOwner(CurIcon->aFrame[0].hbmAlpha, GDI_OBJ_HMGR_PUBLIC); - } - } - else - { - psurfBmp = SURFACE_ShareLockSurface(IconInfo.hbmMask); - if (!psurfBmp) - goto done; - - CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx; - CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy / 2; - - SURFACE_ShareUnlockSurface(psurfBmp); - } - GreSetObjectOwner(IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC); - - Ret = TRUE; - -done: - - if (CurIcon) - { - UserDereferenceObject(CurIcon); - } - RETURN(Ret); - -CLEANUP: - TRACE("Leave NtUserSetCursorContents, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; + FIXME(" is UNIMPLEMENTED.\n"); + return FALSE; } @@ -1066,13 +918,11 @@ NtUserSetCursorIconData( _In_ HCURSOR Handle, _In_opt_ PUNICODE_STRING pustrModule, _In_opt_ PUNICODE_STRING pustrRsrc, - _In_ PICONINFO pIconInfo) + _In_ PCURSORDATA pCursorData) { PCURICON_OBJECT CurIcon; - PSURFACE psurfBmp; NTSTATUS Status = STATUS_SUCCESS; BOOL Ret = FALSE; - ICONINFO ii; TRACE("Enter NtUserSetCursorIconData\n"); @@ -1091,8 +941,16 @@ NtUserSetCursorIconData( _SEH2_TRY { - ProbeForRead(pIconInfo, sizeof(ICONINFO), 1); - ii = *pIconInfo; + ProbeForRead(pCursorData, sizeof(*pCursorData), 1); + CurIcon->xHotspot = pCursorData->xHotspot; + CurIcon->yHotspot = pCursorData->yHotspot; + CurIcon->cx = pCursorData->cx; + CurIcon->cy = pCursorData->cy; + CurIcon->rt = pCursorData->rt; + CurIcon->bpp = pCursorData->bpp; + CurIcon->hbmMask = pCursorData->hbmMask; + CurIcon->hbmColor = pCursorData->hbmColor; + CurIcon->hbmAlpha = pCursorData->hbmAlpha; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -1106,90 +964,44 @@ NtUserSetCursorIconData( goto done; } - /* This is probably not what windows does, but consistency checks can't hurt */ - if(CurIcon->bIcon != ii.fIcon) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - goto done; - } - CurIcon->ptlHotspot.x = ii.xHotspot; - CurIcon->ptlHotspot.y = ii.yHotspot; - - if(!ii.hbmMask) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - goto done; - } - - CurIcon->aFrame[0].hbmMask = BITMAP_CopyBitmap(ii.hbmMask); - if(!CurIcon->aFrame[0].hbmMask) - goto done; - - if(ii.hbmColor) - { - CurIcon->aFrame[0].hbmColor = BITMAP_CopyBitmap(ii.hbmColor); - if(!CurIcon->aFrame[0].hbmColor) - goto done; - } - - if (CurIcon->aFrame[0].hbmColor) - { - psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor); - if(!psurfBmp) - goto done; - - CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx; - CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy; - SURFACE_ShareUnlockSurface(psurfBmp); - GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_PUBLIC); - } - else - { - psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmMask); - if(!psurfBmp) - goto done; - - CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx; - CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy/2; - SURFACE_ShareUnlockSurface(psurfBmp); - } - GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC); - if(pustrModule) { /* We use this convenient function, because INTRESOURCEs and ATOMs are the same */ - Status = ProbeAndCaptureUnicodeStringOrAtom(&CurIcon->ustrRsrc, pustrRsrc); + Status = ProbeAndCaptureUnicodeStringOrAtom(&CurIcon->strName, pustrRsrc); if(!NT_SUCCESS(Status)) goto done; Status = ProbeAndCaptureUnicodeString(&CurIcon->ustrModule, UserMode, pustrModule); if(!NT_SUCCESS(Status)) goto done; } + + + if(!CurIcon->hbmMask) + { + ERR("NtUserSetCursorIconData was got no hbmMask.\n"); + EngSetLastError(ERROR_INVALID_PARAMETER); + goto done; + } + + GreSetObjectOwner(CurIcon->hbmMask, GDI_OBJ_HMGR_PUBLIC); + + if(CurIcon->hbmColor) + GreSetObjectOwner(CurIcon->hbmColor, GDI_OBJ_HMGR_PUBLIC); + + if(CurIcon->hbmAlpha) + GreSetObjectOwner(CurIcon->hbmAlpha, GDI_OBJ_HMGR_PUBLIC); Ret = TRUE; done: - UserDereferenceObject(CurIcon); if(!Ret) { - if (CurIcon->aFrame[0].hbmMask) - { - GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_POWNED); - GreDeleteObject(CurIcon->aFrame[0].hbmMask); - CurIcon->aFrame[0].hbmMask = NULL; - } - if (CurIcon->aFrame[0].hbmColor) - { - GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_POWNED); - GreDeleteObject(CurIcon->aFrame[0].hbmColor); - CurIcon->aFrame[0].hbmColor = NULL; - } - if(!IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer)) - ExFreePoolWithTag(CurIcon->ustrRsrc.Buffer, TAG_STRING); + if(!IS_INTRESOURCE(CurIcon->strName.Buffer)) + ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING); if(CurIcon->ustrModule.Buffer) ReleaseCapturedUnicodeString(&CurIcon->ustrModule, UserMode); } - + UserDereferenceObject(CurIcon); TRACE("Leave NtUserSetCursorIconData, ret=%i\n",Ret); UserLeave(); @@ -1232,9 +1044,9 @@ UserDrawIconEx( return FALSE; } - hbmMask = pIcon->aFrame[0].hbmMask; - hbmColor = pIcon->aFrame[0].hbmColor; - hbmAlpha = pIcon->aFrame[0].hbmAlpha; + hbmMask = pIcon->hbmMask; + hbmColor = pIcon->hbmColor; + hbmAlpha = pIcon->hbmAlpha; if (istepIfAniCur) ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n"); @@ -1254,7 +1066,7 @@ UserDrawIconEx( if(hbmColor == NULL) { /* But then the mask bitmap must have the information in it's bottom half */ - ASSERT(psurfMask->SurfObj.sizlBitmap.cy == 2*pIcon->Size.cy); + ASSERT(psurfMask->SurfObj.sizlBitmap.cy == 2*pIcon->cy); psurfColor = NULL; } else if ((psurfColor = SURFACE_ShareLockSurface(hbmColor)) == NULL) @@ -1294,26 +1106,26 @@ UserDrawIconEx( } /* Set source rect */ - RECTL_vSetRect(&rcSrc, 0, 0, pIcon->Size.cx, pIcon->Size.cy); + RECTL_vSetRect(&rcSrc, 0, 0, pIcon->cx, pIcon->cy); /* Fix width parameter, if needed */ if (!cxWidth) { if(diFlags & DI_DEFAULTSIZE) - cxWidth = pIcon->bIcon ? + cxWidth = is_icon(pIcon) ? UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR); else - cxWidth = pIcon->Size.cx; + cxWidth = pIcon->cx; } /* Fix height parameter, if needed */ if (!cyHeight) { if(diFlags & DI_DEFAULTSIZE) - cyHeight = pIcon->bIcon ? + cyHeight = is_icon(pIcon) ? UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR); else - cyHeight = pIcon->Size.cy; + cyHeight = pIcon->cy; } /* Should we render off-screen? */ @@ -1410,7 +1222,7 @@ UserDrawIconEx( } /* Now do the rendering */ - if(hbmAlpha && (diFlags & DI_IMAGE)) + if(hbmAlpha && ((diFlags & DI_NORMAL) == DI_NORMAL)) { BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } }; PSURFACE psurf = NULL; @@ -1501,7 +1313,7 @@ NoAlpha: { /* Mask bitmap holds the information in its bottom half */ DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY; - RECTL_vOffsetRect(&rcSrc, 0, pIcon->Size.cy); + RECTL_vOffsetRect(&rcSrc, 0, pIcon->cy); EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0); diff --git a/win32ss/user/ntuser/display.c b/win32ss/user/ntuser/display.c index eb3cdbc7c14..350f49717ff 100644 --- a/win32ss/user/ntuser/display.c +++ b/win32ss/user/ntuser/display.c @@ -173,7 +173,7 @@ InitVideo() if (NT_SUCCESS(Status)) { /* Check if VGA mode is requested. */ - if (wcsstr(awcBuffer, L"/BASEVIDEO") != 0) + if (wcsstr(awcBuffer, L"BASEVIDEO") != 0) { ERR("VGA mode requested.\n"); gbBaseVideo = TRUE; diff --git a/win32ss/user/ntuser/keyboard.c b/win32ss/user/ntuser/keyboard.c index d374e004254..4c906ed44a6 100644 --- a/win32ss/user/ntuser/keyboard.c +++ b/win32ss/user/ntuser/keyboard.c @@ -900,7 +900,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d /* Post a keyboard message */ TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam); - MsqPostMessage(pFocusQueue, &Msg, TRUE, QS_KEY); + MsqPostMessage(pFocusQueue, &Msg, TRUE, QS_KEY, 0); } return TRUE; @@ -1121,7 +1121,7 @@ IntTranslateKbdMessage(LPMSG lpMsg, NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR; NewMsg.wParam = HIWORD(lpMsg->lParam); NewMsg.lParam = LOWORD(lpMsg->lParam); - MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY); + MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY, 0); return TRUE; } @@ -1150,7 +1150,7 @@ IntTranslateKbdMessage(LPMSG lpMsg, { TRACE("Msg: %x '%lc' (%04x) %08x\n", NewMsg.message, wch[i], wch[i], NewMsg.lParam); NewMsg.wParam = wch[i]; - MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY); + MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY, 0); } bResult = TRUE; } diff --git a/win32ss/user/ntuser/message.c b/win32ss/user/ntuser/message.c index e39057fe177..5423442ce5d 100644 --- a/win32ss/user/ntuser/message.c +++ b/win32ss/user/ntuser/message.c @@ -1105,7 +1105,7 @@ UserPostThreadMessage( DWORD idThread, KeQueryTickCount(&LargeTickCount); Message.time = MsqCalculateMessageTime(&LargeTickCount); - MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE); + MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE, 0); ObDereferenceObject( peThread ); return TRUE; } @@ -1228,7 +1228,7 @@ UserPostMessage( HWND Wnd, } else { - MsqPostMessage(Window->head.pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE); + MsqPostMessage(Window->head.pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE, 0); } } return TRUE; diff --git a/win32ss/user/ntuser/misc/file.c b/win32ss/user/ntuser/misc/file.c index abc5a0ca651..8b4d0e26b06 100644 --- a/win32ss/user/ntuser/misc/file.c +++ b/win32ss/user/ntuser/misc/file.c @@ -233,7 +233,7 @@ UserLoadImage(PCWSTR pwszName) 0); NtGdiDeleteObjectApp(hdc); - DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi); + DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi, -1); } else { diff --git a/win32ss/user/ntuser/msgqueue.c b/win32ss/user/ntuser/msgqueue.c index 0ae86125932..b6bbfdf534d 100644 --- a/win32ss/user/ntuser/msgqueue.c +++ b/win32ss/user/ntuser/msgqueue.c @@ -147,12 +147,13 @@ UserSetCursor( /* Call GDI to set the new screen cursor */ #ifdef NEW_CURSORICON GreSetPointerShape(hdcScreen, - NewCursor->aFrame[0].hbmMask, - NewCursor->aFrame[0].hbmColor, - NewCursor->ptlHotspot.x, - NewCursor->ptlHotspot.y, + NewCursor->hbmAlpha ? NULL : NewCursor->hbmMask, + NewCursor->hbmAlpha ? NewCursor->hbmAlpha : NewCursor->hbmColor, + NewCursor->xHotspot, + NewCursor->yHotspot, gpsi->ptCursor.x, - gpsi->ptCursor.y); + gpsi->ptCursor.y, + NewCursor->hbmAlpha ? SPS_ALPHA : 0); #else GreSetPointerShape(hdcScreen, NewCursor->IconInfo.hbmMask, @@ -160,7 +161,8 @@ UserSetCursor( NewCursor->IconInfo.xHotspot, NewCursor->IconInfo.yHotspot, gpsi->ptCursor.x, - gpsi->ptCursor.y); + gpsi->ptCursor.y, + 0); #endif } else /* Note: OldCursor != NewCursor so we have to hide cursor */ @@ -582,13 +584,16 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook { /* Call GDI to set the new screen cursor */ #ifdef NEW_CURSORICON - GreSetPointerShape(hdcScreen, - MessageQueue->CursorObject->aFrame[0].hbmMask, - MessageQueue->CursorObject->aFrame[0].hbmColor, - MessageQueue->CursorObject->ptlHotspot.x, - MessageQueue->CursorObject->ptlHotspot.y, - gpsi->ptCursor.x, - gpsi->ptCursor.y); + GreSetPointerShape(hdcScreen, + MessageQueue->CursorObject->hbmAlpha ? + NULL : MessageQueue->CursorObject->hbmMask, + MessageQueue->CursorObject->hbmAlpha ? + MessageQueue->CursorObject->hbmAlpha : MessageQueue->CursorObject->hbmColor, + MessageQueue->CursorObject->xHotspot, + MessageQueue->CursorObject->yHotspot, + gpsi->ptCursor.x, + gpsi->ptCursor.y, + MessageQueue->CursorObject->hbmAlpha ? SPS_ALPHA : 0); #else GreSetPointerShape(hdcScreen, MessageQueue->CursorObject->IconInfo.hbmMask, @@ -596,7 +601,8 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook MessageQueue->CursorObject->IconInfo.xHotspot, MessageQueue->CursorObject->IconInfo.yHotspot, gpsi->ptCursor.x, - gpsi->ptCursor.y); + gpsi->ptCursor.y, + 0); #endif } else GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y); @@ -616,7 +622,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook else { TRACE("Posting mouse message to hwnd=0x%x!\n", UserHMGetHandle(pwnd)); - MsqPostMessage(MessageQueue, Msg, TRUE, QS_MOUSEBUTTON); + MsqPostMessage(MessageQueue, Msg, TRUE, QS_MOUSEBUTTON, 0); } } else if (hdcScreen) @@ -669,7 +675,7 @@ MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam) KeQueryTickCount(&LargeTickCount); Mesg.time = MsqCalculateMessageTime(&LargeTickCount); Mesg.pt = gpsi->ptCursor; - MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, Type); + MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, Type, 0); UserDereferenceObject(Window); ObDereferenceObject (Thread); @@ -1246,8 +1252,11 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, } VOID FASTCALL -MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN HardwareMessage, - DWORD MessageBits) +MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, + MSG* Msg, + BOOLEAN HardwareMessage, + DWORD MessageBits, + DWORD dwQEvent) { PUSER_MESSAGE Message; @@ -1256,7 +1265,12 @@ MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN HardwareMessa return; } - if(!HardwareMessage) + if (dwQEvent) + { + InsertHeadList(&MessageQueue->PostedMessagesListHead, + &Message->ListEntry); + } + else if (!HardwareMessage) { InsertTailList(&MessageQueue->PostedMessagesListHead, &Message->ListEntry); @@ -1267,7 +1281,9 @@ MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN HardwareMessa &Message->ListEntry); } + Message->dwQEvent = dwQEvent; Message->QS_Flags = MessageBits; + //Message->pti = pti; Fixed in ATI changes. See CORE-6551 MsqWakeQueue(MessageQueue, MessageBits, (MessageBits & QS_TIMER ? FALSE : TRUE)); } diff --git a/win32ss/user/ntuser/msgqueue.h b/win32ss/user/ntuser/msgqueue.h index e20d1028417..2708aabcaac 100644 --- a/win32ss/user/ntuser/msgqueue.h +++ b/win32ss/user/ntuser/msgqueue.h @@ -23,6 +23,9 @@ typedef struct _USER_MESSAGE LIST_ENTRY ListEntry; MSG Msg; DWORD QS_Flags; + LONG_PTR ExtraInfo; + DWORD dwQEvent; + PTHREADINFO pti; } USER_MESSAGE, *PUSER_MESSAGE; struct _USER_MESSAGE_QUEUE; @@ -156,7 +159,7 @@ NTSTATUS FASTCALL co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult); PUSER_MESSAGE FASTCALL MsqCreateMessage(LPMSG Msg); VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE Message); -VOID FASTCALL MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN HardwareMessage, DWORD MessageBits); +VOID FASTCALL MsqPostMessage(PUSER_MESSAGE_QUEUE, MSG*, BOOLEAN, DWORD, DWORD); VOID FASTCALL MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode); BOOLEAN APIENTRY MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue, diff --git a/win32ss/user/ntuser/timer.c b/win32ss/user/ntuser/timer.c index 8e679d30f4d..8b43dd3b1a3 100644 --- a/win32ss/user/ntuser/timer.c +++ b/win32ss/user/ntuser/timer.c @@ -409,7 +409,7 @@ PostTimerMessages(PWND Window) Msg.wParam = (WPARAM) pTmr->nID; Msg.lParam = (LPARAM) pTmr->pfn; - MsqPostMessage(ThreadQueue, &Msg, FALSE, QS_TIMER); + MsqPostMessage(ThreadQueue, &Msg, FALSE, QS_TIMER, 0); pTmr->flags &= ~TMRF_READY; pti->cTimersReady++; Hit = TRUE; diff --git a/win32ss/user/ntuser/windc.c b/win32ss/user/ntuser/windc.c index 8921d0c6913..756b453e29c 100644 --- a/win32ss/user/ntuser/windc.c +++ b/win32ss/user/ntuser/windc.c @@ -462,7 +462,6 @@ UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags) ((Dce->DCXFlags & DCX_CACHECOMPAREMASK) == DcxFlags)) { UpdateClipOrigin = TRUE; - //bUpdateVisRgn = FALSE; break; } } diff --git a/win32ss/user/user32/misc/misc.c b/win32ss/user/user32/misc/misc.c index d211bb15945..a473e79e1ce 100644 --- a/win32ss/user/user32/misc/misc.c +++ b/win32ss/user/user32/misc/misc.c @@ -304,6 +304,8 @@ GetUser32Handle(HANDLE handle) INT Index; USHORT generation; + if (!handle) return NULL; + Index = (((UINT_PTR)handle & 0xffff) - FIRST_USER_HANDLE) >> 1; if (Index < 0 || Index >= gHandleTable->nb_handles) @@ -457,21 +459,14 @@ PWND FASTCALL ValidateHwnd(HWND hwnd) { - PWND Wnd; PCLIENTINFO ClientInfo = GetWin32ClientInfo(); ASSERT(ClientInfo != NULL); /* See if the window is cached */ - if (hwnd == ClientInfo->CallbackWnd.hWnd) + if (hwnd && hwnd == ClientInfo->CallbackWnd.hWnd) return ClientInfo->CallbackWnd.pWnd; - Wnd = ValidateHandle((HANDLE)hwnd, otWindow); - if (Wnd != NULL) - { - return Wnd; - } - - return NULL; + return ValidateHandle((HANDLE)hwnd, otWindow); } // diff --git a/win32ss/user/user32/windows/cursoricon_new.c b/win32ss/user/user32/windows/cursoricon_new.c index 3635dbcdbe6..f79d6a1b731 100644 --- a/win32ss/user/user32/windows/cursoricon_new.c +++ b/win32ss/user/user32/windows/cursoricon_new.c @@ -1,8 +1,8 @@ /* * PROJECT: ReactOS user32.dll * COPYRIGHT: GPL - See COPYING in the top level directory - * FILE: dll/win32/user32/windows/class.c - * PURPOSE: Window classes + * FILE: dll/win32/user32/windows/cursoricon.c + * PURPOSE: cursor and icons implementation * PROGRAMMER: Jérôme Gardou (jerome.gardou@reactos.org) */ @@ -171,13 +171,144 @@ static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width, return -1; } +/*********************************************************************** + * bmi_has_alpha + */ +static BOOL bmi_has_alpha( const BITMAPINFO *info, const void *bits ) +{ + int i; + BOOL has_alpha = FALSE; + const unsigned char *ptr = bits; + + if (info->bmiHeader.biBitCount != 32) return FALSE; + for (i = 0; i < info->bmiHeader.biWidth * abs(info->bmiHeader.biHeight); i++, ptr += 4) + if ((has_alpha = (ptr[3] != 0))) break; + return has_alpha; +} + +/*********************************************************************** + * create_alpha_bitmap + * + * Create the alpha bitmap for a 32-bpp icon that has an alpha channel. + */ +static HBITMAP create_alpha_bitmap( + _In_ HBITMAP color, + _In_opt_ const BITMAPINFO *src_info, + _In_opt_ const void *color_bits ) +{ + HBITMAP alpha = NULL, hbmpOld; + BITMAPINFO *info = NULL; + HDC hdc = NULL, hdcScreen; + void *bits = NULL; + unsigned char *ptr; + int i; + LONG width, height; + BITMAP bm; + + if (!GetObjectW( color, sizeof(bm), &bm )) + return NULL; + if (bm.bmBitsPixel != 32) + return NULL; + + hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL); + if(!hdcScreen) + return NULL; + if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32) + goto done; + hdc = CreateCompatibleDC(hdcScreen); + if(!hdc) + goto done; + + if(src_info) + { + WORD bpp; + DWORD compr; + int size; + + if(!bmi_has_alpha(src_info, color_bits)) + goto done; + + if(!DIB_GetBitmapInfo(&src_info->bmiHeader, &width, &height, &bpp, &compr)) + goto done; + if(bpp != 32) + goto done; + + size = get_dib_image_size(width, height, bpp); + bits = HeapAlloc(GetProcessHeap(), 0, size); + if(!bits) + goto done; + CopyMemory(bits, color_bits, size); + } + else + { + info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256])); + if(!info) + goto done; + info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + info->bmiHeader.biWidth = bm.bmWidth; + info->bmiHeader.biHeight = -bm.bmHeight; + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = 32; + info->bmiHeader.biCompression = BI_RGB; + info->bmiHeader.biSizeImage = bm.bmWidth * bm.bmHeight * 4; + info->bmiHeader.biXPelsPerMeter = 0; + info->bmiHeader.biYPelsPerMeter = 0; + info->bmiHeader.biClrUsed = 0; + info->bmiHeader.biClrImportant = 0; + + bits = HeapAlloc(GetProcessHeap(), 0, info->bmiHeader.biSizeImage); + if(!bits) + goto done; + if(!GetDIBits( hdc, color, 0, bm.bmHeight, bits, info, DIB_RGB_COLORS )) + goto done; + if (!bmi_has_alpha( info, bits )) + goto done; + width = bm.bmWidth; + height = bm.bmHeight; + } + + /* pre-multiply by alpha */ + for (i = 0, ptr = bits; i < width * height; i++, ptr += 4) + { + unsigned int alpha = ptr[3]; + ptr[0] = ptr[0] * alpha / 255; + ptr[1] = ptr[1] * alpha / 255; + ptr[2] = ptr[2] * alpha / 255; + } + + /* Create the bitmap */ + alpha = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight); + if(!alpha) + goto done; + hbmpOld = SelectObject(hdc, alpha); + if(!hbmpOld) + goto done; + if(!StretchDIBits( hdc, 0, 0, bm.bmWidth, bm.bmHeight, + 0, 0, width, height, + bits, src_info ? src_info : info, DIB_RGB_COLORS, SRCCOPY )) + { + SelectObject(hdc, hbmpOld); + hbmpOld = NULL; + DeleteObject(alpha); + alpha = NULL; + } + SelectObject(hdc, hbmpOld); + +done: + DeleteDC(hdcScreen); + if(hdc) DeleteDC( hdc ); + if(info) HeapFree( GetProcessHeap(), 0, info ); + if(bits) HeapFree(GetProcessHeap(), 0, bits); + + TRACE("Returning 0x%08x.\n", alpha); + return alpha; +} + /************* IMPLEMENTATION CORE ****************/ -static BOOL CURSORICON_GetIconInfoFromBMI( - _Inout_ ICONINFO* pii, - _In_ const BITMAPINFO *pbmi, - _In_ int cxDesired, - _In_ int cyDesired +static BOOL CURSORICON_GetCursorDataFromBMI( + _Inout_ CURSORDATA* pdata, + _In_ const BITMAPINFO *pbmi ) { UINT ubmiSize = bitmap_info_size(pbmi, DIB_RGB_COLORS); @@ -201,13 +332,22 @@ static BOOL CURSORICON_GetIconInfoFromBMI( if(compr != BI_RGB) return FALSE; + /* If no dimensions were set, use the one from the icon */ + if(!pdata->cx) pdata->cx = width; + if(!pdata->cy) pdata->cy = height < 0 ? -height/2 : height/2; + /* Fix the hotspot coords */ - if(!pii->fIcon) + if(pdata->rt == (USHORT)((ULONG_PTR)RT_CURSOR)) { - if(cxDesired != pbmi->bmiHeader.biWidth) - pii->xHotspot = (pii->xHotspot * cxDesired) / pbmi->bmiHeader.biWidth; - if(cxDesired != (pbmi->bmiHeader.biHeight/2)) - pii->yHotspot = (pii->yHotspot * cyDesired * 2) / pbmi->bmiHeader.biHeight; + if(pdata->cx != width) + pdata->xHotspot = (pdata->xHotspot * pdata->cx) / width; + if(pdata->cy != height/2) + pdata->yHotspot = (pdata->yHotspot * pdata->cy * 2) / height; + } + else + { + pdata->xHotspot = pdata->cx/2; + pdata->yHotspot = pdata->cy/2; } hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL); @@ -230,49 +370,52 @@ static BOOL CURSORICON_GetIconInfoFromBMI( ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcHeight /= 2; else pbmiCopy->bmiHeader.biHeight /= 2; + height /= 2; pvColor = (const char*)pbmi + ubmiSize; pvMask = (const char*)pvColor + - get_dib_image_size(pbmi->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight, pbmi->bmiHeader.biBitCount ); + get_dib_image_size(width, height, bpp ); /* Set XOR bits */ if(monochrome) { /* Create the 1bpp bitmap which will contain everything */ - pii->hbmColor = NULL; - pii->hbmMask = CreateCompatibleBitmap(hdc, cxDesired, cyDesired * 2); - if(!pii->hbmMask) + pdata->hbmColor = NULL; + pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy * 2, 1, 1, NULL); + if(!pdata->hbmMask) goto done; - hbmpOld = SelectObject(hdc, pii->hbmMask); + hbmpOld = SelectObject(hdc, pdata->hbmMask); if(!hbmpOld) goto done; - if(!StretchDIBits(hdc, 0, cyDesired, cxDesired, cyDesired, - 0, 0, pbmiCopy->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight, + if(!StretchDIBits(hdc, 0, pdata->cy, pdata->cx, pdata->cy, + 0, 0, width, height, pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY)) goto done; + pdata->bpp = 1; } else { /* Create the bitmap. It has to be compatible with the screen surface */ - pii->hbmColor = CreateCompatibleBitmap(hdcScreen, cxDesired, cyDesired); - if(!pii->hbmColor) + pdata->hbmColor = CreateCompatibleBitmap(hdcScreen, pdata->cx, pdata->cy); + if(!pdata->hbmColor) goto done; /* Create the 1bpp mask bitmap */ - pii->hbmMask = CreateCompatibleBitmap(hdc, cxDesired, cyDesired); - if(!pii->hbmMask) + pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy, 1, 1, NULL); + if(!pdata->hbmMask) goto done; - hbmpOld = SelectObject(hdc, pii->hbmColor); + hbmpOld = SelectObject(hdc, pdata->hbmColor); if(!hbmpOld) goto done; - if(!StretchDIBits(hdc, 0, 0, cxDesired, cyDesired, - 0, 0, pbmiCopy->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight, + if(!StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy, + 0, 0, width, height, pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY)) goto done; + pdata->bpp = GetDeviceCaps(hdcScreen, BITSPIXEL); + if(pdata->bpp == 32) + pdata->hbmAlpha = create_alpha_bitmap(pdata->hbmColor, pbmiCopy, pvColor); /* Now convert the info to monochrome for the mask bits */ - pbmiCopy->bmiHeader.biBitCount = 1; - /* Handle the CORE/INFO difference */ if (pbmiCopy->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) { RGBQUAD *rgb = pbmiCopy->bmiColors; @@ -281,6 +424,7 @@ static BOOL CURSORICON_GetIconInfoFromBMI( rgb[0].rgbBlue = rgb[0].rgbGreen = rgb[0].rgbRed = 0x00; rgb[1].rgbBlue = rgb[1].rgbGreen = rgb[1].rgbRed = 0xff; rgb[0].rgbReserved = rgb[1].rgbReserved = 0; + pbmiCopy->bmiHeader.biBitCount = 1; } else { @@ -288,14 +432,15 @@ static BOOL CURSORICON_GetIconInfoFromBMI( rgb[0].rgbtBlue = rgb[0].rgbtGreen = rgb[0].rgbtRed = 0x00; rgb[1].rgbtBlue = rgb[1].rgbtGreen = rgb[1].rgbtRed = 0xff; + ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcBitCount = 1; } } /* Set the mask bits */ - if(!SelectObject(hdc, pii->hbmMask)) + if(!SelectObject(hdc, pdata->hbmMask)) goto done; - bResult = StretchDIBits(hdc, 0, 0, cxDesired, cyDesired, - 0, 0, pbmiCopy->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight, - pvMask, pbmiCopy, DIB_RGB_COLORS, SRCCOPY) != 0; + bResult = StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy, + 0, 0, width, height, + pvMask, pbmiCopy, DIB_RGB_COLORS, SRCCOPY) != 0; done: DeleteDC(hdcScreen); @@ -305,12 +450,65 @@ done: /* Clean up in case of failure */ if(!bResult) { - if(pii->hbmMask) DeleteObject(pii->hbmMask); - if(pii->hbmColor) DeleteObject(pii->hbmColor); + if(pdata->hbmMask) DeleteObject(pdata->hbmMask); + if(pdata->hbmColor) DeleteObject(pdata->hbmColor); + if(pdata->hbmAlpha) DeleteObject(pdata->hbmAlpha); } return bResult; } +static BOOL CURSORICON_GetCursorDataFromIconInfo( + _Out_ CURSORDATA* pCursorData, + _In_ ICONINFO* pIconInfo +) +{ + BITMAP bm; + + ZeroMemory(pCursorData, sizeof(*pCursorData)); + /* Use the CopyImage function, as it will gracefully convert our bitmap to the screen bit depth */ + if(pIconInfo->hbmColor) + { + pCursorData->hbmColor = CopyImage(pIconInfo->hbmColor, IMAGE_BITMAP, 0, 0, 0); + if(!pCursorData->hbmColor) + return FALSE; + } + pCursorData->hbmMask = CopyImage(pIconInfo->hbmMask, IMAGE_BITMAP, 0, 0, LR_MONOCHROME); + if(!pCursorData->hbmMask) + return FALSE; + + /* Now, fill some information */ + pCursorData->rt = (USHORT)((ULONG_PTR)(pIconInfo->fIcon ? RT_ICON : RT_CURSOR)); + if(pCursorData->hbmColor) + { + GetObject(pCursorData->hbmColor, sizeof(bm), &bm); + pCursorData->bpp = bm.bmBitsPixel; + pCursorData->cx = bm.bmWidth; + pCursorData->cy = bm.bmHeight; + if(pCursorData->bpp == 32) + pCursorData->hbmAlpha = create_alpha_bitmap(pCursorData->hbmColor, NULL, NULL); + } + else + { + GetObject(pCursorData->hbmMask, sizeof(bm), &bm); + pCursorData->bpp = 1; + pCursorData->cx = bm.bmWidth; + pCursorData->cy = bm.bmHeight/2; + } + + if(pIconInfo->fIcon) + { + pCursorData->xHotspot = pCursorData->cx/2; + pCursorData->yHotspot = pCursorData->cy/2; + } + else + { + pCursorData->xHotspot = pIconInfo->xHotspot; + pCursorData->yHotspot = pIconInfo->yHotspot; + } + + return TRUE; +} + static HBITMAP BITMAP_LoadImageW( @@ -324,14 +522,17 @@ BITMAP_LoadImageW( const BITMAPINFO* pbmi; BITMAPINFO* pbmiScaled = NULL; BITMAPINFO* pbmiCopy = NULL; - const VOID* pvMapping; + const VOID* pvMapping = NULL; DWORD dwOffset = 0; - HGLOBAL hgRsrc; + HGLOBAL hgRsrc = NULL; int iBMISize; PVOID pvBits; HDC hdcScreen = NULL; HDC hdc = NULL; - HBITMAP hbmpRet, hbmpOld; + HBITMAP hbmpOld, hbmpRet = NULL; + LONG width, height; + WORD bpp; + DWORD compr; /* Map the bitmap info */ if(fuLoad & LR_LOADFROMFILE) @@ -371,7 +572,18 @@ BITMAP_LoadImageW( return NULL; } - /* See if we must scale the bitmap */ + /* Fix up values */ + if(DIB_GetBitmapInfo(&pbmi->bmiHeader, &width, &height, &bpp, &compr) == -1) + goto end; + if((width > 65535) || (height > 65535)) + goto end; + if(cxDesired == 0) + cxDesired = width; + if(cyDesired == 0) + cyDesired = height; + else if(height < 0) + cyDesired = -cyDesired; + iBMISize = bitmap_info_size(pbmi, DIB_RGB_COLORS); /* Get a pointer to the image data */ @@ -492,35 +704,15 @@ create_bitmap: if(pbmiScaled->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) { BITMAPCOREHEADER* pbmch = (BITMAPCOREHEADER*)&pbmiScaled->bmiHeader; - if(cxDesired == 0) - cxDesired = pbmch->bcWidth; - if(cyDesired == 0) - cyDesired == pbmch->bcHeight; - else if(pbmch->bcHeight < 0) - cyDesired = -cyDesired; - pbmch->bcWidth = cxDesired; pbmch->bcHeight = cyDesired; } else { - if ((pbmi->bmiHeader.biHeight > 65535) || (pbmi->bmiHeader.biWidth > 65535)) { - WARN("Broken BITMAPINFO!\n"); - goto end; - } - - if(cxDesired == 0) - cxDesired = pbmi->bmiHeader.biWidth; - if(cyDesired == 0) - cyDesired = pbmi->bmiHeader.biHeight; - else if(pbmi->bmiHeader.biHeight < 0) - cyDesired = -cyDesired; - pbmiScaled->bmiHeader.biWidth = cxDesired; pbmiScaled->bmiHeader.biHeight = cyDesired; /* No compression for DIB sections */ - if(fuLoad & LR_CREATEDIBSECTION) - pbmiScaled->bmiHeader.biCompression = BI_RGB; + pbmiScaled->bmiHeader.biCompression = BI_RGB; } } @@ -574,9 +766,9 @@ end: HeapFree(GetProcessHeap(), 0, pbmiScaled); if(pbmiCopy) HeapFree(GetProcessHeap(), 0, pbmiCopy); - if (fuLoad & LR_LOADFROMFILE) + if (pvMapping) UnmapViewOfFile( pvMapping ); - else + if(hgRsrc) FreeResource(hgRsrc); return hbmpRet; @@ -621,9 +813,9 @@ CURSORICON_LoadFromFileW( CURSORICONFILEDIR *dir; DWORD filesize = 0; LPBYTE bits; - HANDLE hRet = NULL; + HANDLE hCurIcon = NULL; WORD i; - ICONINFO ii; + CURSORDATA cursorData; TRACE("loading %s\n", debugstr_w( lpszName )); @@ -696,25 +888,44 @@ CURSORICON_LoadFromFileW( /* Get our entry */ entry = &dir->idEntries[i-1]; + /* Fix dimensions */ + if(!cxDesired) cxDesired = entry->bWidth; + if(!cyDesired) cyDesired = entry->bHeight; /* A bit of preparation */ - ii.xHotspot = entry->xHotspot; - ii.yHotspot = entry->yHotspot; - ii.fIcon = bIcon; + ZeroMemory(&cursorData, sizeof(cursorData)); + if(!bIcon) + { + cursorData.xHotspot = entry->xHotspot; + cursorData.yHotspot = entry->yHotspot; + } + cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR)); /* Do the dance */ - if(!CURSORICON_GetIconInfoFromBMI(&ii, (BITMAPINFO*)&bits[entry->dwDIBOffset], cxDesired, cyDesired)) + if(!CURSORICON_GetCursorDataFromBMI(&cursorData, (BITMAPINFO*)&bits[entry->dwDIBOffset])) goto end; - /* Create the icon. NOTE: there's no LR_SHARED icons if they are created from file */ - hRet = CreateIconIndirect(&ii); + hCurIcon = NtUserxCreateEmptyCurObject(bIcon ? 0 : 1); + if(!hCurIcon) + goto end_error; - /* Clean up */ - DeleteObject(ii.hbmMask); - DeleteObject(ii.hbmColor); + /* Tell win32k */ + if(!NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData)) + { + NtUserDestroyCursor(hCurIcon, TRUE); + goto end_error; + } end: UnmapViewOfFile(bits); - return hRet; + return hCurIcon; + + /* Clean up */ +end_error: + DeleteObject(cursorData.hbmMask); + if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); + if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha); + + return NULL; } static @@ -733,7 +944,7 @@ CURSORICON_LoadImageW( CURSORICONDIR* dir; WORD wResId; LPBYTE bits; - ICONINFO ii; + CURSORDATA cursorData; BOOL bStatus; UNICODE_STRING ustrRsrc; UNICODE_STRING ustrModule = {0, 0, NULL}; @@ -775,7 +986,7 @@ CURSORICON_LoadImageW( /* Get it */ do { - DWORD ret = GetModuleFileName(hinst, ustrModule.Buffer, size); + DWORD ret = GetModuleFileNameW(hinst, ustrModule.Buffer, size); if(ret == 0) { HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); @@ -783,8 +994,8 @@ CURSORICON_LoadImageW( } if(ret < size) { - ustrModule.Length = ret; - ustrModule.MaximumLength = size; + ustrModule.Length = ret*sizeof(WCHAR); + ustrModule.MaximumLength = size*sizeof(WCHAR); break; } size *= 2; @@ -845,70 +1056,77 @@ CURSORICON_LoadImageW( goto done; } - /* Get the hotspot */ - if(bIcon) - { - ii.xHotspot = cxDesired/2; - ii.yHotspot = cyDesired/2; - } - if(!bIcon) + ZeroMemory(&cursorData, sizeof(cursorData)); + + if(dir->idType == 2) { + /* idType == 2 for cursor resources */ SHORT* ptr = (SHORT*)bits; - ii.xHotspot = ptr[0]; - ii.yHotspot = ptr[1]; + cursorData.xHotspot = ptr[0]; + cursorData.yHotspot = ptr[1]; bits += 2*sizeof(SHORT); } - ii.fIcon = bIcon; + cursorData.cx = cxDesired; + cursorData.cy = cyDesired; + cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR)); /* Get the bitmaps */ - bStatus = CURSORICON_GetIconInfoFromBMI( - &ii, - (BITMAPINFO*)bits, - cxDesired, - cyDesired); + bStatus = CURSORICON_GetCursorDataFromBMI( + &cursorData, + (BITMAPINFO*)bits); FreeResource( handle ); if(!bStatus) goto done; + /* This is from resource */ + cursorData.CURSORF_flags = CURSORF_FROMRESOURCE; + /* Create the handle */ hCurIcon = NtUserxCreateEmptyCurObject(bIcon ? 0 : 1); if(!hCurIcon) { - DeleteObject(ii.hbmMask); - if(ii.hbmColor) DeleteObject(ii.hbmColor); - goto done; + goto end_error; } /* Tell win32k */ if(fuLoad & LR_SHARED) - bStatus = NtUserSetCursorIconData(hCurIcon, &ustrModule, &ustrRsrc, &ii); + { + cursorData.CURSORF_flags |= CURSORF_LRSHARED; + bStatus = NtUserSetCursorIconData(hCurIcon, &ustrModule, &ustrRsrc, &cursorData); + } else - bStatus = NtUserSetCursorIconData(hCurIcon, NULL, NULL, &ii); + bStatus = NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData); if(!bStatus) { NtUserDestroyCursor(hCurIcon, TRUE); - hCurIcon = NULL; + goto end_error; } - - DeleteObject(ii.hbmMask); - if(ii.hbmColor) DeleteObject(ii.hbmColor); done: if(ustrModule.Buffer) HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); return hCurIcon; + +end_error: + if(ustrModule.Buffer) + HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); + DeleteObject(cursorData.hbmMask); + if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); + if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha); + + return NULL; } static HBITMAP BITMAP_CopyImage( - _In_ HBITMAP hbmp, - _In_ int cxDesired, - _In_ int cyDesired, - _In_ UINT fuFlags + _In_ HBITMAP hnd, + _In_ int desiredx, + _In_ int desiredy, + _In_ UINT flags ) { HBITMAP res = NULL; @@ -916,22 +1134,22 @@ BITMAP_CopyImage( int objSize; BITMAPINFO * bi; - objSize = GetObjectW( hbmp, sizeof(ds), &ds ); + objSize = GetObjectW( hnd, sizeof(ds), &ds ); if (!objSize) return 0; - if ((cxDesired < 0) || (cyDesired < 0)) return 0; + if ((desiredx < 0) || (desiredy < 0)) return 0; - if (fuFlags & LR_COPYFROMRESOURCE) + if (flags & LR_COPYFROMRESOURCE) { FIXME("The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n"); } - if (fuFlags & LR_COPYRETURNORG) + if (flags & LR_COPYRETURNORG) { FIXME("The flag LR_COPYRETURNORG is not implemented for bitmaps\n"); } - if (cxDesired == 0) cxDesired = ds.dsBm.bmWidth; - if (cyDesired == 0) cyDesired = ds.dsBm.bmHeight; + if (desiredx == 0) desiredx = ds.dsBm.bmWidth; + if (desiredy == 0) desiredy = ds.dsBm.bmHeight; /* Allocate memory for a BITMAPINFOHEADER structure and a color table. The maximum number of colors in a color table @@ -945,7 +1163,7 @@ BITMAP_CopyImage( bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel; bi->bmiHeader.biCompression = BI_RGB; - if (fuFlags & LR_CREATEDIBSECTION) + if (flags & LR_CREATEDIBSECTION) { /* Create a DIB section. LR_MONOCHROME is ignored */ void * bits; @@ -958,12 +1176,11 @@ BITMAP_CopyImage( memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER)); } - /* Get the color table or the color masks */ - GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS); + bi->bmiHeader.biWidth = desiredx; + bi->bmiHeader.biHeight = desiredy; - bi->bmiHeader.biWidth = cxDesired; - bi->bmiHeader.biHeight = cyDesired; - bi->bmiHeader.biSizeImage = 0; + /* Get the color table or the color masks */ + GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS); res = CreateDIBSection(dc, bi, DIB_RGB_COLORS, &bits, NULL, 0); DeleteDC(dc); @@ -972,16 +1189,16 @@ BITMAP_CopyImage( { /* Create a device-dependent bitmap */ - BOOL monochrome = (fuFlags & LR_MONOCHROME); + BOOL monochrome = (flags & LR_MONOCHROME); if (objSize == sizeof(DIBSECTION)) { /* The source bitmap is a DIB section. Get its attributes */ HDC dc = CreateCompatibleDC(NULL); - bi->bmiHeader.biSize = sizeof(bi->bmiHeader); - bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel; - GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS); + bi->bmiHeader.biWidth = ds.dsBm.bmWidth; + bi->bmiHeader.biHeight = ds.dsBm.bmHeight; + GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS); DeleteDC(dc); if (!monochrome && ds.dsBm.bmBitsPixel == 1) @@ -1015,12 +1232,12 @@ BITMAP_CopyImage( if (monochrome) { - res = CreateBitmap(cxDesired, cyDesired, 1, 1, NULL); + res = CreateBitmap(desiredx, desiredy, 1, 1, NULL); } else { HDC screenDC = GetDC(NULL); - res = CreateCompatibleBitmap(screenDC, cxDesired, cyDesired); + res = CreateCompatibleBitmap(screenDC, desiredx, desiredy); ReleaseDC(NULL, screenDC); } } @@ -1061,7 +1278,7 @@ BITMAP_CopyImage( bi->bmiHeader.biClrImportant = 0; /* Fill in biSizeImage */ - GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS); + GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS); bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bi->bmiHeader.biSizeImage); if (bits) @@ -1069,11 +1286,11 @@ BITMAP_CopyImage( HBITMAP oldBmp; /* Get the image bits of the source bitmap */ - GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS); + GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS); /* Copy it to the destination bitmap */ oldBmp = SelectObject(dc, res); - StretchDIBits(dc, 0, 0, cxDesired, cyDesired, + StretchDIBits(dc, 0, 0, desiredx, desiredy, 0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS, SRCCOPY); SelectObject(dc, oldBmp); @@ -1084,9 +1301,9 @@ BITMAP_CopyImage( DeleteDC(dc); } - if (fuFlags & LR_COPYDELETEORG) + if (flags & LR_COPYDELETEORG) { - DeleteObject(hbmp); + DeleteObject(hnd); } } HeapFree(GetProcessHeap(), 0, bi); @@ -1114,17 +1331,17 @@ CURSORICON_CopyImage( PVOID pvBuf; HMODULE hModule; - ustrModule.MaximumLength = MAX_PATH; + ustrModule.MaximumLength = MAX_PATH * sizeof(WCHAR); ustrRsrc.MaximumLength = 256; - ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength * sizeof(WCHAR)); + ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength); if(!ustrModule.Buffer) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; } /* Keep track of the buffer for the resource, NtUserGetIconInfo might overwrite it */ - pvBuf = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(WCHAR)); + pvBuf = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength); if(!pvBuf) { HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); @@ -1153,7 +1370,7 @@ CURSORICON_CopyImage( { PWSTR newBuffer; ustrModule.MaximumLength *= 2; - newBuffer = HeapReAlloc(GetProcessHeap(), 0, ustrModule.Buffer, ustrModule.MaximumLength * sizeof(WCHAR)); + newBuffer = HeapReAlloc(GetProcessHeap(), 0, ustrModule.Buffer, ustrModule.MaximumLength); if(!ustrModule.Buffer) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -1165,7 +1382,7 @@ CURSORICON_CopyImage( if(ustrRsrc.Length == ustrRsrc.MaximumLength) { ustrRsrc.MaximumLength *= 2; - pvBuf = HeapReAlloc(GetProcessHeap(), 0, ustrRsrc.Buffer, ustrRsrc.MaximumLength * sizeof(WCHAR)); + pvBuf = HeapReAlloc(GetProcessHeap(), 0, ustrRsrc.Buffer, ustrRsrc.MaximumLength); if(!pvBuf) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -1176,14 +1393,15 @@ CURSORICON_CopyImage( } while(TRUE); /* NULL-terminate our strings */ - ustrModule.Buffer[ustrModule.Length] = 0; + ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = 0; if(!IS_INTRESOURCE(ustrRsrc.Buffer)) - ustrRsrc.Buffer[ustrRsrc.Length] = 0; + ustrRsrc.Buffer[ustrRsrc.Length/sizeof(WCHAR)] = 0; /* Get the module handle */ if(!GetModuleHandleExW(0, ustrModule.Buffer, &hModule)) { /* This hould never happen */ + ERR("Invalid handle?.\n"); SetLastError(ERROR_INVALID_PARAMETER); goto leave; } @@ -1198,6 +1416,8 @@ CURSORICON_CopyImage( HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); HeapFree(GetProcessHeap(), 0, pvBuf); + TRACE("Returning 0x%08x.\n", ret); + return ret; } @@ -1499,21 +1719,6 @@ int WINAPI LookupIconIdFromDirectoryEx( return 0; } - /* idType == 2 is for cursors, 1 for icons */ - /*if(fIcon) - { - if(dir->idType == 2) - { - WARN("An icon was asked for a cursor resource.\n"); - return 0; - } - } - else if(dir->idType == 1) - { - WARN("A cursor was asked for an icon resource.\n"); - return 0; - }*/ - if(Flags & LR_MONOCHROME) bppDesired = 1; else @@ -1526,6 +1731,11 @@ int WINAPI LookupIconIdFromDirectoryEx( bppDesired = GetDeviceCaps(icScreen, BITSPIXEL); DeleteDC(icScreen); } + + if(!cxDesired) + cxDesired = GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR); + if(!cyDesired) + cyDesired = GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR); /* Find the best match for the desired size */ cxyDiff = 0xFFFFFFFF; @@ -1658,7 +1868,7 @@ HICON WINAPI CreateIconFromResource( _In_ DWORD dwVer ) { - return CreateIconFromResourceEx( presbits, dwResSize, fIcon, dwVer, 0,0,0); + return CreateIconFromResourceEx( presbits, dwResSize, fIcon, dwVer, 0, 0, LR_DEFAULTSIZE | LR_SHARED); } HICON WINAPI CreateIconFromResourceEx( @@ -1671,36 +1881,65 @@ HICON WINAPI CreateIconFromResourceEx( _In_ UINT uFlags ) { - ICONINFO ii; + CURSORDATA cursorData; HICON hIcon; - if(uFlags) - FIXME("uFlags 0x%08x ignored.\n", uFlags); + TRACE("%p, %lu, %lu, %lu, %i, %i, %lu.\n", pbIconBits, cbIconBits, fIcon, dwVersion, cxDesired, cyDesired, uFlags); - if(fIcon) + if(uFlags & ~LR_DEFAULTSIZE) + FIXME("uFlags 0x%08x ignored.\n", uFlags & ~LR_DEFAULTSIZE); + + if(uFlags & LR_DEFAULTSIZE) { - ii.xHotspot = cxDesired/2; - ii.yHotspot = cyDesired/2; + if(!cxDesired) cxDesired = GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR); + if(!cyDesired) cyDesired = GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR); } - else + + /* Check if this is an animated cursor */ + if(!memcmp(pbIconBits, "RIFF", 4)) + { + UNIMPLEMENTED; + return NULL; + } + + ZeroMemory(&cursorData, sizeof(cursorData)); + cursorData.cx = cxDesired; + cursorData.cy = cyDesired; + cursorData.rt = (USHORT)((ULONG_PTR)(fIcon ? RT_ICON : RT_CURSOR)); + if(!fIcon) { WORD* pt = (WORD*)pbIconBits; - ii.xHotspot = *pt++; - ii.yHotspot = *pt++; + cursorData.xHotspot = *pt++; + cursorData.yHotspot = *pt++; pbIconBits = (PBYTE)pt; } - ii.fIcon = fIcon; - if(!CURSORICON_GetIconInfoFromBMI(&ii, (BITMAPINFO*)pbIconBits, cxDesired, cyDesired)) + if(!CURSORICON_GetCursorDataFromBMI(&cursorData, (BITMAPINFO*)pbIconBits)) + { + ERR("Couldn't fill the CURSORDATA structure.\n"); return NULL; + } - hIcon = CreateIconIndirect(&ii); + hIcon = NtUserxCreateEmptyCurObject(fIcon ? 0 : 1); + if(!hIcon) + goto end_error; - /* Clean up */ - DeleteObject(ii.hbmMask); - if(ii.hbmColor) DeleteObject(ii.hbmColor); + if(!NtUserSetCursorIconData(hIcon, NULL, NULL, &cursorData)) + { + ERR("NtUserSetCursorIconData failed.\n"); + NtUserDestroyCursor(hIcon, TRUE); + goto end_error; + } return hIcon; + + /* Clean up */ +end_error: + DeleteObject(cursorData.hbmMask); + if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); + if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha); + + return NULL; } HICON WINAPI CreateIconIndirect( @@ -1709,22 +1948,34 @@ HICON WINAPI CreateIconIndirect( { /* As simple as creating a handle, and let win32k deal with the bitmaps */ HICON hiconRet; + CURSORDATA cursorData; TRACE("%p.\n", piconinfo); - hiconRet = NtUserxCreateEmptyCurObject(piconinfo->fIcon ? 0 : 1); - if(!hiconRet) + if(!CURSORICON_GetCursorDataFromIconInfo(&cursorData, piconinfo)) return NULL; - if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, piconinfo)) + hiconRet = NtUserxCreateEmptyCurObject(piconinfo->fIcon ? 0 : 1); + if(!hiconRet) + goto end_error; + + if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, &cursorData)) { NtUserDestroyCursor(hiconRet, FALSE); - hiconRet = NULL; + goto end_error; } TRACE("Returning 0x%08x.\n", hiconRet); return hiconRet; + +end_error: + /* Clean up */ + DeleteObject(cursorData.hbmMask); + if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); + if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha); + + return NULL; } HCURSOR WINAPI CreateCursor( @@ -1768,8 +2019,7 @@ BOOL WINAPI SetCursorPos( _In_ int Y ) { - UNIMPLEMENTED; - return FALSE; + return NtUserxSetCursorPos(X,Y); } BOOL WINAPI GetCursorPos( @@ -1783,14 +2033,12 @@ int WINAPI ShowCursor( _In_ BOOL bShow ) { - UNIMPLEMENTED; - return -1; + return NtUserxShowCursor(bShow); } HCURSOR WINAPI GetCursor(void) { - UNIMPLEMENTED; - return NULL; + return (HCURSOR)NtUserGetThreadState(THREADSTATE_GETCURSOR); } BOOL WINAPI DestroyCursor( diff --git a/win32ss/w32ksvc.h b/win32ss/w32ksvc.h index dd80587c696..daf987312c7 100644 --- a/win32ss/w32ksvc.h +++ b/win32ss/w32ksvc.h @@ -380,8 +380,11 @@ SVC_(UserEnumDisplaySettings, 4) SVC_(UserEvent, 1) SVC_(UserExcludeUpdateRgn, 2) SVC_(UserFillWindow, 4) -// SVC_(UserFindExistingCursorIcon, 3, Wrong, number, of, param, ?) +#ifdef NEW_CURSORICON +SVC_(UserFindExistingCursorIcon, 3) +#else SVC_(UserFindExistingCursorIcon, 4) +#endif SVC_(UserFindWindowEx, 5) SVC_(UserFlashWindowEx, 1) SVC_(UserGetAltTabInfo, 6)