mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 04:37:15 +00:00
Synchronize with trunk's revision r57599.
svn path=/branches/ros-csrss/; revision=57600
This commit is contained in:
commit
aab393ca70
36 changed files with 1985 additions and 571 deletions
|
@ -1221,6 +1221,7 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olecli32",0x0
|
|||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olesvr32",0x00000000,"olesvr32.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olethk32",0x00000000,"olethk32.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","rpcrt4",0x00000000,"rpcrt4.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","setupapi",0x00000000,"setupapi.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","shell32",0x00000000,"shell32.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","url",0x00000000,"url.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","urlmon",0x00000000,"urlmon.dll"
|
||||
|
|
|
@ -776,6 +776,7 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olecli32",0x0
|
|||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olesvr32",0x00000000,"olesvr32.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olethk32",0x00000000,"olethk32.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","rpcrt4",0x00000000,"rpcrt4.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","setupapi",0x00000000,"setupapi.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","shell32",0x00000000,"shell32.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","url",0x00000000,"url.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","urlmon",0x00000000,"urlmon.dll"
|
||||
|
|
|
@ -1221,6 +1221,7 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olecli32",0x0
|
|||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olesvr32",0x00000000,"olesvr32.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olethk32",0x00000000,"olethk32.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","rpcrt4",0x00000000,"rpcrt4.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","setupapi",0x00000000,"setupapi.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","shell32",0x00000000,"shell32.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","url",0x00000000,"url.dll"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","urlmon",0x00000000,"urlmon.dll"
|
||||
|
|
|
@ -13,11 +13,11 @@ spec2def(lsasrv.dll lsasrv.spec ADD_IMPORTLIB)
|
|||
list(APPEND SOURCE
|
||||
authport.c
|
||||
database.c
|
||||
lookup.c
|
||||
lsarpc.c
|
||||
lsasrv.c
|
||||
policy.c
|
||||
privileges.c
|
||||
sids.c
|
||||
lsasrv.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lsasrv_stubs.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lsasrv.def
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: Local Security Authority (LSA) Server
|
||||
* FILE: reactos/dll/win32/lsasrv/sids.c
|
||||
* FILE: reactos/dll/win32/lsasrv/lookup.c
|
||||
* PURPOSE: Sid / Name lookup functions
|
||||
*
|
||||
* PROGRAMMERS: Eric Kohl
|
||||
|
@ -72,8 +72,8 @@ typedef struct _WELL_KNOWN_SID
|
|||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
PSID Sid;
|
||||
UNICODE_STRING Name;
|
||||
UNICODE_STRING Domain;
|
||||
UNICODE_STRING AccountName;
|
||||
UNICODE_STRING DomainName;
|
||||
SID_NAME_USE Use;
|
||||
} WELL_KNOWN_SID, *PWELL_KNOWN_SID;
|
||||
|
||||
|
@ -202,8 +202,8 @@ BOOLEAN
|
|||
LsapCreateSid(PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
|
||||
UCHAR SubAuthorityCount,
|
||||
PULONG SubAuthorities,
|
||||
PWSTR Name,
|
||||
PWSTR Domain,
|
||||
PWSTR AccountName,
|
||||
PWSTR DomainName,
|
||||
SID_NAME_USE Use)
|
||||
{
|
||||
PWELL_KNOWN_SID SidEntry;
|
||||
|
@ -235,11 +235,11 @@ LsapCreateSid(PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
|
|||
*p = SubAuthorities[i];
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&SidEntry->Name,
|
||||
Name);
|
||||
RtlInitUnicodeString(&SidEntry->AccountName,
|
||||
AccountName);
|
||||
|
||||
RtlInitUnicodeString(&SidEntry->Domain,
|
||||
Domain);
|
||||
RtlInitUnicodeString(&SidEntry->DomainName,
|
||||
DomainName);
|
||||
|
||||
SidEntry->Use = Use;
|
||||
|
||||
|
@ -472,6 +472,13 @@ LsapInitSids(VOID)
|
|||
L"NT AUTHORITY",
|
||||
SidTypeWellKnownGroup);
|
||||
|
||||
LsapCreateSid(&NtAuthority,
|
||||
1,
|
||||
SubAuthorities,
|
||||
L"LOCALSERVICE",
|
||||
L"NT AUTHORITY",
|
||||
SidTypeWellKnownGroup);
|
||||
|
||||
/* Network Service Sid */
|
||||
SubAuthorities[0] = SECURITY_NETWORK_SERVICE_RID;
|
||||
LsapCreateSid(&NtAuthority,
|
||||
|
@ -481,6 +488,13 @@ LsapInitSids(VOID)
|
|||
L"NT AUTHORITY",
|
||||
SidTypeWellKnownGroup);
|
||||
|
||||
LsapCreateSid(&NtAuthority,
|
||||
1,
|
||||
SubAuthorities,
|
||||
L"NETWORKSERVICE",
|
||||
L"NT AUTHORITY",
|
||||
SidTypeWellKnownGroup);
|
||||
|
||||
/* Builtin Domain Sid */
|
||||
SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
|
||||
LsapCreateSid(&NtAuthority,
|
||||
|
@ -653,7 +667,7 @@ LsapLookupWellKnownSid(PSID Sid)
|
|||
|
||||
|
||||
PWELL_KNOWN_SID
|
||||
LsapLookupWellKnownName(PUNICODE_STRING Name)
|
||||
LsapLookupIsolatedWellKnownName(PUNICODE_STRING AccountName)
|
||||
{
|
||||
PLIST_ENTRY ListEntry;
|
||||
PWELL_KNOWN_SID Ptr;
|
||||
|
@ -664,7 +678,33 @@ LsapLookupWellKnownName(PUNICODE_STRING Name)
|
|||
Ptr = CONTAINING_RECORD(ListEntry,
|
||||
WELL_KNOWN_SID,
|
||||
ListEntry);
|
||||
if (RtlEqualUnicodeString(Name, &Ptr->Name, TRUE))
|
||||
if (RtlEqualUnicodeString(AccountName, &Ptr->AccountName, TRUE))
|
||||
{
|
||||
return Ptr;
|
||||
}
|
||||
|
||||
ListEntry = ListEntry->Flink;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
PWELL_KNOWN_SID
|
||||
LsapLookupFullyQualifiedWellKnownName(PUNICODE_STRING AccountName,
|
||||
PUNICODE_STRING DomainName)
|
||||
{
|
||||
PLIST_ENTRY ListEntry;
|
||||
PWELL_KNOWN_SID Ptr;
|
||||
|
||||
ListEntry = WellKnownSidListHead.Flink;
|
||||
while (ListEntry != &WellKnownSidListHead)
|
||||
{
|
||||
Ptr = CONTAINING_RECORD(ListEntry,
|
||||
WELL_KNOWN_SID,
|
||||
ListEntry);
|
||||
if (RtlEqualUnicodeString(AccountName, &Ptr->AccountName, TRUE) &&
|
||||
RtlEqualUnicodeString(DomainName, &Ptr->DomainName, TRUE))
|
||||
{
|
||||
return Ptr;
|
||||
}
|
||||
|
@ -975,6 +1015,37 @@ CreateDomainSidFromAccountSid(PSID AccountSid)
|
|||
}
|
||||
|
||||
|
||||
static PSID
|
||||
LsapCopySid(PSID SrcSid)
|
||||
{
|
||||
UCHAR RidCount;
|
||||
PSID DstSid;
|
||||
ULONG i;
|
||||
ULONG DstSidSize;
|
||||
PULONG p, q;
|
||||
|
||||
RidCount = *RtlSubAuthorityCountSid(SrcSid);
|
||||
DstSidSize = RtlLengthRequiredSid(RidCount);
|
||||
|
||||
DstSid = MIDL_user_allocate(DstSidSize);
|
||||
if (DstSid == NULL)
|
||||
return NULL;
|
||||
|
||||
RtlInitializeSid(DstSid,
|
||||
RtlIdentifierAuthoritySid(SrcSid),
|
||||
RidCount);
|
||||
|
||||
for (i = 0; i < (ULONG)RidCount; i++)
|
||||
{
|
||||
p = RtlSubAuthoritySid(SrcSid, i);
|
||||
q = RtlSubAuthoritySid(DstSid, i);
|
||||
*q = *p;
|
||||
}
|
||||
|
||||
return DstSid;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
LsapLookupIsolatedNames(DWORD Count,
|
||||
|
@ -1004,18 +1075,24 @@ LsapLookupIsolatedNames(DWORD Count,
|
|||
TRACE("Mapping name: %wZ\n", &AccountNames[i]);
|
||||
|
||||
/* Look-up all well-known names */
|
||||
ptr = LsapLookupWellKnownName((PUNICODE_STRING)&AccountNames[i]);
|
||||
ptr = LsapLookupIsolatedWellKnownName((PUNICODE_STRING)&AccountNames[i]);
|
||||
if (ptr != NULL)
|
||||
{
|
||||
SidsBuffer[i].Use = ptr->Use;
|
||||
SidsBuffer[i].Sid = ptr->Sid;
|
||||
SidsBuffer[i].Sid = LsapCopySid(ptr->Sid);
|
||||
if (SidsBuffer[i].Sid == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
SidsBuffer[i].DomainIndex = -1;
|
||||
SidsBuffer[i].Flags = 0;
|
||||
|
||||
if (ptr->Use == SidTypeDomain)
|
||||
{
|
||||
Status = LsapAddDomainToDomainsList(DomainsBuffer,
|
||||
&ptr->Name,
|
||||
&ptr->AccountName,
|
||||
ptr->Sid,
|
||||
&DomainIndex);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -1025,11 +1102,11 @@ LsapLookupIsolatedNames(DWORD Count,
|
|||
}
|
||||
else
|
||||
{
|
||||
ptr2= LsapLookupWellKnownName(&ptr->Domain);
|
||||
ptr2= LsapLookupIsolatedWellKnownName(&ptr->DomainName);
|
||||
if (ptr2 != NULL)
|
||||
{
|
||||
Status = LsapAddDomainToDomainsList(DomainsBuffer,
|
||||
&ptr2->Name,
|
||||
&ptr2->AccountName,
|
||||
ptr2->Sid,
|
||||
&DomainIndex);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -1072,7 +1149,13 @@ LsapLookupIsolatedNames(DWORD Count,
|
|||
if (RtlEqualUnicodeString((PUNICODE_STRING)&AccountNames[i], &BuiltinDomainName, TRUE))
|
||||
{
|
||||
SidsBuffer[i].Use = SidTypeDomain;
|
||||
SidsBuffer[i].Sid = BuiltinDomainSid;
|
||||
SidsBuffer[i].Sid = LsapCopySid(BuiltinDomainSid);
|
||||
if (SidsBuffer[i].Sid == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
SidsBuffer[i].DomainIndex = -1;
|
||||
SidsBuffer[i].Flags = 0;
|
||||
|
||||
|
@ -1093,7 +1176,12 @@ LsapLookupIsolatedNames(DWORD Count,
|
|||
if (RtlEqualUnicodeString((PUNICODE_STRING)&AccountNames[i], &AccountDomainName, TRUE))
|
||||
{
|
||||
SidsBuffer[i].Use = SidTypeDomain;
|
||||
SidsBuffer[i].Sid = AccountDomainSid;
|
||||
SidsBuffer[i].Sid = LsapCopySid(AccountDomainSid);
|
||||
if (SidsBuffer[i].Sid == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
SidsBuffer[i].DomainIndex = -1;
|
||||
SidsBuffer[i].Flags = 0;
|
||||
|
||||
|
@ -1183,7 +1271,10 @@ LsapLookupIsolatedBuiltinNames(DWORD Count,
|
|||
SidsBuffer[i].Sid = CreateSidFromSidAndRid(BuiltinDomainSid,
|
||||
RelativeIds.Element[0]);
|
||||
if (SidsBuffer[i].Sid == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
SidsBuffer[i].DomainIndex = -1;
|
||||
SidsBuffer[i].Flags = 0;
|
||||
|
@ -1278,7 +1369,10 @@ LsapLookupIsolatedAccountNames(DWORD Count,
|
|||
SidsBuffer[i].Sid = CreateSidFromSidAndRid(AccountDomainSid,
|
||||
RelativeIds.Element[0]);
|
||||
if (SidsBuffer[i].Sid == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
SidsBuffer[i].DomainIndex = -1;
|
||||
SidsBuffer[i].Flags = 0;
|
||||
|
@ -1310,6 +1404,114 @@ done:
|
|||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
LsapLookupFullyQualifiedWellKnownNames(DWORD Count,
|
||||
PRPC_UNICODE_STRING DomainNames,
|
||||
PRPC_UNICODE_STRING AccountNames,
|
||||
PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
|
||||
PLSAPR_TRANSLATED_SID_EX2 SidsBuffer,
|
||||
PULONG Mapped)
|
||||
{
|
||||
UNICODE_STRING EmptyDomainName = RTL_CONSTANT_STRING(L"");
|
||||
PWELL_KNOWN_SID ptr, ptr2;
|
||||
PSID DomainSid;
|
||||
ULONG DomainIndex;
|
||||
ULONG i;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
/* Ignore names which were already mapped */
|
||||
if (SidsBuffer[i].Use != SidTypeUnknown)
|
||||
continue;
|
||||
|
||||
/* Ignore isolated account names */
|
||||
if (DomainNames[i].Length == 0)
|
||||
continue;
|
||||
|
||||
TRACE("Mapping name: %wZ\\%wZ\n", &DomainNames[i], &AccountNames[i]);
|
||||
|
||||
/* Look-up all well-known names */
|
||||
ptr = LsapLookupFullyQualifiedWellKnownName((PUNICODE_STRING)&AccountNames[i],
|
||||
(PUNICODE_STRING)&DomainNames[i]);
|
||||
if (ptr != NULL)
|
||||
{
|
||||
TRACE("Found it! (%wZ\\%wZ)\n", &ptr->DomainName, &ptr->AccountName);
|
||||
|
||||
SidsBuffer[i].Use = ptr->Use;
|
||||
SidsBuffer[i].Sid = LsapCopySid(ptr->Sid);
|
||||
if (SidsBuffer[i].Sid == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
SidsBuffer[i].DomainIndex = -1;
|
||||
SidsBuffer[i].Flags = 0;
|
||||
|
||||
if (ptr->Use == SidTypeDomain)
|
||||
{
|
||||
Status = LsapAddDomainToDomainsList(DomainsBuffer,
|
||||
&ptr->AccountName,
|
||||
ptr->Sid,
|
||||
&DomainIndex);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
SidsBuffer[i].DomainIndex = DomainIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr2= LsapLookupIsolatedWellKnownName(&ptr->DomainName);
|
||||
if (ptr2 != NULL)
|
||||
{
|
||||
Status = LsapAddDomainToDomainsList(DomainsBuffer,
|
||||
&ptr2->AccountName,
|
||||
ptr2->Sid,
|
||||
&DomainIndex);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
SidsBuffer[i].DomainIndex = DomainIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
DomainSid = CreateDomainSidFromAccountSid(ptr->Sid);
|
||||
if (DomainSid == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
Status = LsapAddDomainToDomainsList(DomainsBuffer,
|
||||
&EmptyDomainName,
|
||||
DomainSid,
|
||||
&DomainIndex);
|
||||
|
||||
if (DomainSid != NULL)
|
||||
{
|
||||
MIDL_user_free(DomainSid);
|
||||
DomainSid = NULL;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
SidsBuffer[i].DomainIndex = DomainIndex;
|
||||
}
|
||||
}
|
||||
|
||||
(*Mapped)++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
LsapLookupBuiltinNames(DWORD Count,
|
||||
|
@ -1359,6 +1561,8 @@ LsapLookupBuiltinNames(DWORD Count,
|
|||
if (!RtlEqualUnicodeString((PUNICODE_STRING)&DomainNames[i], &BuiltinDomainName, TRUE))
|
||||
continue;
|
||||
|
||||
TRACE("Mapping name: %wZ\\%wZ\n", &DomainNames[i], &AccountNames[i]);
|
||||
|
||||
Status = SamrLookupNamesInDomain(DomainHandle,
|
||||
1,
|
||||
&AccountNames[i],
|
||||
|
@ -1370,7 +1574,10 @@ LsapLookupBuiltinNames(DWORD Count,
|
|||
SidsBuffer[i].Sid = CreateSidFromSidAndRid(BuiltinDomainSid,
|
||||
RelativeIds.Element[0]);
|
||||
if (SidsBuffer[i].Sid == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
SidsBuffer[i].DomainIndex = -1;
|
||||
SidsBuffer[i].Flags = 0;
|
||||
|
@ -1451,6 +1658,8 @@ LsapLookupAccountNames(DWORD Count,
|
|||
if (!RtlEqualUnicodeString((PUNICODE_STRING)&DomainNames[i], &AccountDomainName, TRUE))
|
||||
continue;
|
||||
|
||||
TRACE("Mapping name: %wZ\\%wZ\n", &DomainNames[i], &AccountNames[i]);
|
||||
|
||||
Status = SamrLookupNamesInDomain(DomainHandle,
|
||||
1,
|
||||
&AccountNames[i],
|
||||
|
@ -1462,7 +1671,10 @@ LsapLookupAccountNames(DWORD Count,
|
|||
SidsBuffer[i].Sid = CreateSidFromSidAndRid(AccountDomainSid,
|
||||
RelativeIds.Element[0]);
|
||||
if (SidsBuffer[i].Sid == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
SidsBuffer[i].DomainIndex = -1;
|
||||
SidsBuffer[i].Flags = 0;
|
||||
|
@ -1509,13 +1721,10 @@ LsapLookupNames(DWORD Count,
|
|||
PRPC_UNICODE_STRING DomainNames = NULL;
|
||||
PRPC_UNICODE_STRING AccountNames = NULL;
|
||||
ULONG SidsBufferLength;
|
||||
// ULONG DomainIndex;
|
||||
ULONG i;
|
||||
ULONG Mapped = 0;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
// PWELL_KNOWN_SID ptr, ptr2;
|
||||
|
||||
//TRACE("()\n");
|
||||
|
||||
TranslatedSids->Entries = 0;
|
||||
|
@ -1621,7 +1830,22 @@ LsapLookupNames(DWORD Count,
|
|||
if (Mapped == Count)
|
||||
goto done;
|
||||
|
||||
Status = LsapLookupFullyQualifiedWellKnownNames(Count,
|
||||
DomainNames,
|
||||
AccountNames,
|
||||
DomainsBuffer,
|
||||
SidsBuffer,
|
||||
&Mapped);
|
||||
if (!NT_SUCCESS(Status) &&
|
||||
Status != STATUS_NONE_MAPPED &&
|
||||
Status != STATUS_SOME_NOT_MAPPED)
|
||||
{
|
||||
TRACE("LsapLookupFullyQualifiedWellKnownNames failed! (Status %lx)\n", Status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (Mapped == Count)
|
||||
goto done;
|
||||
|
||||
Status = LsapLookupBuiltinNames(Count,
|
||||
DomainNames,
|
||||
|
@ -1755,16 +1979,22 @@ LsapLookupWellKnownSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
|||
NamesBuffer[i].Use = ptr->Use;
|
||||
NamesBuffer[i].Flags = 0;
|
||||
|
||||
NamesBuffer[i].Name.Buffer = MIDL_user_allocate(ptr->Name.MaximumLength);
|
||||
NamesBuffer[i].Name.Length = ptr->Name.Length;
|
||||
NamesBuffer[i].Name.MaximumLength = ptr->Name.MaximumLength;
|
||||
RtlCopyMemory(NamesBuffer[i].Name.Buffer, ptr->Name.Buffer, ptr->Name.MaximumLength);
|
||||
NamesBuffer[i].Name.Length = ptr->AccountName.Length;
|
||||
NamesBuffer[i].Name.MaximumLength = ptr->AccountName.MaximumLength;
|
||||
NamesBuffer[i].Name.Buffer = MIDL_user_allocate(ptr->AccountName.MaximumLength);
|
||||
if (NamesBuffer[i].Name.Buffer == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ptr2= LsapLookupWellKnownName(&ptr->Domain);
|
||||
RtlCopyMemory(NamesBuffer[i].Name.Buffer, ptr->AccountName.Buffer, ptr->AccountName.MaximumLength);
|
||||
|
||||
ptr2= LsapLookupIsolatedWellKnownName(&ptr->DomainName);
|
||||
if (ptr2 != NULL)
|
||||
{
|
||||
Status = LsapAddDomainToDomainsList(DomainsBuffer,
|
||||
&ptr2->Name,
|
||||
&ptr2->AccountName,
|
||||
ptr2->Sid,
|
||||
&DomainIndex);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -2062,82 +2292,6 @@ done:
|
|||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
LsapLookupUnknownSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||
PLSAPR_TRANSLATED_NAME_EX NamesBuffer,
|
||||
PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer,
|
||||
PULONG Mapped)
|
||||
{
|
||||
SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY};
|
||||
static const UNICODE_STRING DomainName = RTL_CONSTANT_STRING(L"UNKNOWN");
|
||||
static const UNICODE_STRING AdminName = RTL_CONSTANT_STRING(L"Test");
|
||||
PSID AdminsSid = NULL;
|
||||
LPWSTR SidString = NULL;
|
||||
ULONG SidLength;
|
||||
ULONG DomainIndex;
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = RtlAllocateAndInitializeSid(&IdentifierAuthority,
|
||||
2,
|
||||
SECURITY_BUILTIN_DOMAIN_RID,
|
||||
DOMAIN_ALIAS_RID_ADMINS,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
&AdminsSid);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
SidLength = RtlLengthSid(AdminsSid);
|
||||
|
||||
for (i = 0; i < SidEnumBuffer->Entries; i++)
|
||||
{
|
||||
/* Ignore SIDs which are already mapped */
|
||||
if (NamesBuffer[i].Use != SidTypeUnknown)
|
||||
continue;
|
||||
|
||||
|
||||
ConvertSidToStringSidW(SidEnumBuffer->SidInfo[i].Sid, &SidString);
|
||||
TRACE("Mapping SID: %S\n", SidString);
|
||||
LocalFree(SidString);
|
||||
SidString = NULL;
|
||||
|
||||
|
||||
/* Hack: Map the SID to the Admin Account if it is not a well-known SID */
|
||||
NamesBuffer[i].Use = SidTypeUser;
|
||||
NamesBuffer[i].Flags = 0;
|
||||
NamesBuffer[i].Name.Length = AdminName.Length;
|
||||
NamesBuffer[i].Name.MaximumLength = AdminName.MaximumLength;
|
||||
NamesBuffer[i].Name.Buffer = MIDL_user_allocate(AdminName.MaximumLength);
|
||||
if (NamesBuffer[i].Name.Buffer == NULL)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
RtlCopyMemory(NamesBuffer[i].Name.Buffer, AdminName.Buffer, AdminName.MaximumLength);
|
||||
|
||||
Status = LsapAddDomainToDomainsList(DomainsBuffer,
|
||||
(PUNICODE_STRING)&DomainName,
|
||||
AdminsSid,
|
||||
&DomainIndex);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
NamesBuffer[i].DomainIndex = DomainIndex;
|
||||
|
||||
TRACE("Mapped to: %wZ\n", &NamesBuffer[i].Name);
|
||||
|
||||
(*Mapped)++;
|
||||
}
|
||||
|
||||
done:
|
||||
if (AdminsSid != NULL)
|
||||
RtlFreeSid(AdminsSid);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||
PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
|
||||
|
@ -2229,16 +2383,6 @@ LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
|||
if (Mapped == SidEnumBuffer->Entries)
|
||||
goto done;
|
||||
|
||||
/* Map unknown SIDs */
|
||||
Status = LsapLookupUnknownSids(SidEnumBuffer,
|
||||
NamesBuffer,
|
||||
DomainsBuffer,
|
||||
&Mapped);
|
||||
if (!NT_SUCCESS(Status) &&
|
||||
Status != STATUS_NONE_MAPPED &&
|
||||
Status != STATUS_SOME_NOT_MAPPED)
|
||||
goto done;
|
||||
|
||||
done:
|
||||
TRACE("done Status: %lx Mapped: %lu\n", Status, Mapped);
|
||||
|
|
@ -118,6 +118,32 @@ LsapSetObjectAttribute(PLSA_DB_OBJECT DbObject,
|
|||
LPVOID AttributeData,
|
||||
ULONG AttributeSize);
|
||||
|
||||
/* lookup.c */
|
||||
NTSTATUS
|
||||
LsapInitSids(VOID);
|
||||
|
||||
ULONG
|
||||
LsapGetRelativeIdFromSid(PSID Sid);
|
||||
|
||||
NTSTATUS
|
||||
LsapLookupNames(DWORD Count,
|
||||
PRPC_UNICODE_STRING Names,
|
||||
PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
|
||||
PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
|
||||
LSAP_LOOKUP_LEVEL LookupLevel,
|
||||
DWORD *MappedCount,
|
||||
DWORD LookupOptions,
|
||||
DWORD ClientRevision);
|
||||
|
||||
NTSTATUS
|
||||
LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||
PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
|
||||
PLSAPR_TRANSLATED_NAMES_EX TranslatedNames,
|
||||
LSAP_LOOKUP_LEVEL LookupLevel,
|
||||
DWORD *MappedCount,
|
||||
DWORD LookupOptions,
|
||||
DWORD ClientRevision);
|
||||
|
||||
/* lsarpc.c */
|
||||
VOID
|
||||
LsarStartRpcServer(VOID);
|
||||
|
@ -201,30 +227,4 @@ LsarpEnumeratePrivileges(DWORD *EnumerationContext,
|
|||
PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer,
|
||||
DWORD PreferedMaximumLength);
|
||||
|
||||
/* sids.h */
|
||||
NTSTATUS
|
||||
LsapInitSids(VOID);
|
||||
|
||||
ULONG
|
||||
LsapGetRelativeIdFromSid(PSID Sid);
|
||||
|
||||
NTSTATUS
|
||||
LsapLookupNames(DWORD Count,
|
||||
PRPC_UNICODE_STRING Names,
|
||||
PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
|
||||
PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
|
||||
LSAP_LOOKUP_LEVEL LookupLevel,
|
||||
DWORD *MappedCount,
|
||||
DWORD LookupOptions,
|
||||
DWORD ClientRevision);
|
||||
|
||||
NTSTATUS
|
||||
LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
|
||||
PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
|
||||
PLSAPR_TRANSLATED_NAMES_EX TranslatedNames,
|
||||
LSAP_LOOKUP_LEVEL LookupLevel,
|
||||
DWORD *MappedCount,
|
||||
DWORD LookupOptions,
|
||||
DWORD ClientRevision);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -128,6 +128,66 @@ SamAddMemberToAlias(IN SAM_HANDLE AliasHandle,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamAddMemberToGroup(IN SAM_HANDLE GroupHandle,
|
||||
IN ULONG MemberId,
|
||||
IN ULONG Attributes)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamAddMemberToGroup(%p %lu %lx)",
|
||||
GroupHandle, MemberId, Attributes);
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrAddMemberToGroup((SAMPR_HANDLE)GroupHandle,
|
||||
MemberId,
|
||||
Attributes);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamAddMultipleMembersToAlias(IN SAM_HANDLE AliasHandle,
|
||||
IN PSID *MemberIds,
|
||||
IN ULONG MemberCount)
|
||||
{
|
||||
SAMPR_PSID_ARRAY Buffer;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamAddMultipleMembersToAlias(%p %p %lu)\n",
|
||||
AliasHandle, MemberIds, MemberCount);
|
||||
|
||||
if (MemberIds == NULL)
|
||||
return STATUS_INVALID_PARAMETER_2;
|
||||
|
||||
Buffer.Count = MemberCount;
|
||||
Buffer.Sids = (PSAMPR_SID_INFORMATION)MemberIds;
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrAddMultipleMembersToAlias((SAMPR_HANDLE)AliasHandle,
|
||||
&Buffer);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamCloseHandle(IN SAM_HANDLE SamHandle)
|
||||
|
@ -320,6 +380,90 @@ SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamDeleteAlias(IN SAM_HANDLE AliasHandle)
|
||||
{
|
||||
SAMPR_HANDLE LocalAliasHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamDeleteAlias(%p)\n", AliasHandle);
|
||||
|
||||
LocalAliasHandle = (SAMPR_HANDLE)AliasHandle;
|
||||
|
||||
if (LocalAliasHandle == NULL)
|
||||
return STATUS_INVALID_HANDLE;
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrDeleteAlias(&LocalAliasHandle);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamDeleteGroup(IN SAM_HANDLE GroupHandle)
|
||||
{
|
||||
SAMPR_HANDLE LocalGroupHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamDeleteGroup(%p)\n", GroupHandle);
|
||||
|
||||
LocalGroupHandle = (SAMPR_HANDLE)GroupHandle;
|
||||
|
||||
if (LocalGroupHandle == NULL)
|
||||
return STATUS_INVALID_HANDLE;
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrDeleteGroup(&LocalGroupHandle);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamDeleteUser(IN SAM_HANDLE UserHandle)
|
||||
{
|
||||
SAMPR_HANDLE LocalUserHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamDeleteUser(%p)\n", UserHandle);
|
||||
|
||||
LocalUserHandle = (SAMPR_HANDLE)UserHandle;
|
||||
|
||||
if (LocalUserHandle == NULL)
|
||||
return STATUS_INVALID_HANDLE;
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrDeleteUser(&LocalUserHandle);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamEnumerateAliasesInDomain(IN SAM_HANDLE DomainHandle,
|
||||
|
@ -577,6 +721,50 @@ SamGetAliasMembership(IN SAM_HANDLE DomainHandle,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamGetGroupsForUser(IN SAM_HANDLE UserHandle,
|
||||
OUT PGROUP_MEMBERSHIP *Groups,
|
||||
OUT PULONG MembershipCount)
|
||||
{
|
||||
PSAMPR_GET_GROUPS_BUFFER GroupsBuffer = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamGetGroupsForUser(%p %p %p)\n",
|
||||
UserHandle, Groups, MembershipCount);
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrGetGroupsForUser((SAMPR_HANDLE)UserHandle,
|
||||
&GroupsBuffer);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
*Groups = GroupsBuffer->Groups;
|
||||
*MembershipCount = GroupsBuffer->MembershipCount;
|
||||
|
||||
MIDL_user_free(GroupsBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GroupsBuffer != NULL)
|
||||
{
|
||||
if (GroupsBuffer->Groups != NULL)
|
||||
MIDL_user_free(GroupsBuffer->Groups);
|
||||
|
||||
MIDL_user_free(GroupsBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamGetMembersInAlias(IN SAM_HANDLE AliasHandle,
|
||||
|
@ -619,6 +807,55 @@ SamGetMembersInAlias(IN SAM_HANDLE AliasHandle,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamGetMembersInGroup(IN SAM_HANDLE GroupHandle,
|
||||
OUT PULONG *MemberIds,
|
||||
OUT PULONG *Attributes,
|
||||
OUT PULONG MemberCount)
|
||||
{
|
||||
PSAMPR_GET_MEMBERS_BUFFER MembersBuffer = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamGetMembersInGroup(%p %p %p %p)\n",
|
||||
GroupHandle, MemberIds, Attributes, MemberCount);
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrGetMembersInGroup((SAMPR_HANDLE)GroupHandle,
|
||||
&MembersBuffer);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
*MemberIds = MembersBuffer->Members;
|
||||
*Attributes = MembersBuffer->Attributes;
|
||||
*MemberCount = MembersBuffer->MemberCount;
|
||||
|
||||
MIDL_user_free(MembersBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MembersBuffer != NULL)
|
||||
{
|
||||
if (MembersBuffer->Members != NULL)
|
||||
MIDL_user_free(MembersBuffer->Members);
|
||||
|
||||
if (MembersBuffer->Attributes != NULL)
|
||||
MIDL_user_free(MembersBuffer->Attributes);
|
||||
|
||||
MIDL_user_free(MembersBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle,
|
||||
|
@ -1057,6 +1294,161 @@ SamQueryInformationUser(IN SAM_HANDLE UserHandle,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamQuerySecurityObject(IN SAM_HANDLE ObjectHandle,
|
||||
IN SECURITY_INFORMATION SecurityInformation,
|
||||
OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
|
||||
{
|
||||
SAMPR_SR_SECURITY_DESCRIPTOR LocalSecurityDescriptor;
|
||||
PSAMPR_SR_SECURITY_DESCRIPTOR pLocalSecurityDescriptor;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamQuerySecurityObject(%p %lu %p)\n",
|
||||
ObjectHandle, SecurityInformation, SecurityDescriptor);
|
||||
|
||||
LocalSecurityDescriptor.Length = 0;
|
||||
LocalSecurityDescriptor.SecurityDescriptor = NULL;
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
pLocalSecurityDescriptor = &LocalSecurityDescriptor;
|
||||
|
||||
Status = SamrQuerySecurityObject((SAMPR_HANDLE)ObjectHandle,
|
||||
SecurityInformation,
|
||||
&pLocalSecurityDescriptor);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
*SecurityDescriptor = LocalSecurityDescriptor.SecurityDescriptor;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamRemoveMemberFromAlias(IN SAM_HANDLE AliasHandle,
|
||||
IN PSID MemberId)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamRemoveMemberFromAlias(%p %ul)\n",
|
||||
AliasHandle, MemberId);
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrRemoveMemberFromAlias((SAMPR_HANDLE)AliasHandle,
|
||||
MemberId);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamRemoveMemberFromForeignDomain(IN SAM_HANDLE DomainHandle,
|
||||
IN PSID MemberId)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamRemoveMemberFromForeignDomain(%p %ul)\n",
|
||||
DomainHandle, MemberId);
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrRemoveMemberFromForeignDomain((SAMPR_HANDLE)DomainHandle,
|
||||
MemberId);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamRemoveMemberFromGroup(IN SAM_HANDLE GroupHandle,
|
||||
IN ULONG MemberId)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamRemoveMemberFromGroup(%p %ul)\n",
|
||||
GroupHandle, MemberId);
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrRemoveMemberFromGroup((SAMPR_HANDLE)GroupHandle,
|
||||
MemberId);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamRemoveMultipleMembersFromAlias(IN SAM_HANDLE AliasHandle,
|
||||
IN PSID *MemberIds,
|
||||
IN ULONG MemberCount)
|
||||
{
|
||||
SAMPR_PSID_ARRAY Buffer;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamRemoveMultipleMembersFromAlias(%p %p %lu)\n",
|
||||
AliasHandle, MemberIds, MemberCount);
|
||||
|
||||
if (MemberIds == NULL)
|
||||
return STATUS_INVALID_PARAMETER_2;
|
||||
|
||||
Buffer.Count = MemberCount;
|
||||
Buffer.Sids = (PSAMPR_SID_INFORMATION)MemberIds;
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrRemoveMultipleMembersFromAlias((SAMPR_HANDLE)AliasHandle,
|
||||
&Buffer);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamRidToSid(IN SAM_HANDLE ObjectHandle,
|
||||
IN ULONG Rid,
|
||||
OUT PSID *Sid)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamSetInformationAlias(IN SAM_HANDLE AliasHandle,
|
||||
|
@ -1165,6 +1557,88 @@ SamSetInformationUser(IN SAM_HANDLE UserHandle,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamSetMemberAttributesOfGroup(IN SAM_HANDLE GroupHandle,
|
||||
IN ULONG MemberId,
|
||||
IN ULONG Attributes)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamSetMemberAttributesOfGroup(%p %lu 0x%lx)\n",
|
||||
GroupHandle, MemberId, Attributes);
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrSetMemberAttributesOfGroup((SAMPR_HANDLE)GroupHandle,
|
||||
MemberId,
|
||||
Attributes);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamSetSecurityObject(IN SAM_HANDLE ObjectHandle,
|
||||
IN SECURITY_INFORMATION SecurityInformation,
|
||||
IN PSECURITY_DESCRIPTOR SecurityDescriptor)
|
||||
{
|
||||
SAMPR_SR_SECURITY_DESCRIPTOR DescriptorToPass;
|
||||
ULONG Length;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE("SamSetSecurityObject(%p %lu %p)\n",
|
||||
ObjectHandle, SecurityInformation, SecurityDescriptor);
|
||||
|
||||
/* Retrieve the length of the relative security descriptor */
|
||||
Length = 0;
|
||||
Status = RtlMakeSelfRelativeSD(SecurityDescriptor,
|
||||
NULL,
|
||||
&Length);
|
||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
|
||||
/* Allocate a buffer for the security descriptor */
|
||||
DescriptorToPass.Length = Length;
|
||||
DescriptorToPass.SecurityDescriptor = MIDL_user_allocate(Length);
|
||||
if (DescriptorToPass.SecurityDescriptor == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Convert the given security descriptor to a relative security descriptor */
|
||||
Status = RtlMakeSelfRelativeSD(SecurityDescriptor,
|
||||
(PSECURITY_DESCRIPTOR)DescriptorToPass.SecurityDescriptor,
|
||||
&Length);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto done;
|
||||
|
||||
RpcTryExcept
|
||||
{
|
||||
Status = SamrSetSecurityObject((SAMPR_HANDLE)ObjectHandle,
|
||||
SecurityInformation,
|
||||
&DescriptorToPass);
|
||||
}
|
||||
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = I_RpcMapWin32Status(RpcExceptionCode());
|
||||
}
|
||||
RpcEndExcept;
|
||||
|
||||
done:
|
||||
if (DescriptorToPass.SecurityDescriptor != NULL)
|
||||
MIDL_user_free(DescriptorToPass.SecurityDescriptor);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamShutdownSamServer(IN SAM_HANDLE ServerHandle)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@ stdcall SamAddMemberToAlias(ptr ptr)
|
||||
@ stub SamAddMemberToGroup
|
||||
@ stub SamAddMultipleMembersToAlias
|
||||
@ stdcall SamAddMemberToGroup(ptr long long)
|
||||
@ stdcall SamAddMultipleMembersToAlias(ptr ptr long)
|
||||
@ stub SamChangePasswordUser2
|
||||
@ stub SamChangePasswordUser3
|
||||
@ stub SamChangePasswordUser
|
||||
|
@ -11,9 +11,9 @@
|
|||
@ stdcall SamCreateGroupInDomain(ptr ptr long ptr ptr)
|
||||
@ stdcall SamCreateUser2InDomain(ptr ptr long long ptr ptr ptr)
|
||||
@ stdcall SamCreateUserInDomain(ptr ptr long ptr ptr)
|
||||
@ stub SamDeleteAlias
|
||||
@ stub SamDeleteGroup
|
||||
@ stub SamDeleteUser
|
||||
@ stdcall SamDeleteAlias(ptr)
|
||||
@ stdcall SamDeleteGroup(ptr)
|
||||
@ stdcall SamDeleteUser(ptr)
|
||||
@ stdcall SamEnumerateAliasesInDomain(ptr ptr ptr long ptr)
|
||||
@ stdcall SamEnumerateDomainsInSamServer(ptr ptr ptr long ptr)
|
||||
@ stdcall SamEnumerateGroupsInDomain(ptr ptr ptr long ptr)
|
||||
|
@ -22,9 +22,9 @@
|
|||
@ stdcall SamGetAliasMembership(ptr long ptr ptr ptr)
|
||||
@ stub SamGetCompatibilityMode
|
||||
@ stub SamGetDisplayEnumerationIndex
|
||||
@ stub SamGetGroupsForUser
|
||||
@ stdcall SamGetGroupsForUser(ptr ptr ptr)
|
||||
@ stdcall SamGetMembersInAlias(ptr ptr ptr)
|
||||
@ stub SamGetMembersInGroup
|
||||
@ stdcall SamGetMembersInGroup(ptr ptr ptr ptr)
|
||||
@ stdcall SamLookupDomainInSamServer(ptr ptr ptr)
|
||||
@ stdcall SamLookupIdsInDomain(ptr long ptr ptr ptr)
|
||||
@ stdcall SamLookupNamesInDomain(ptr long ptr ptr ptr)
|
||||
|
@ -37,18 +37,18 @@
|
|||
@ stdcall SamQueryInformationDomain(ptr long ptr)
|
||||
@ stdcall SamQueryInformationGroup(ptr long ptr)
|
||||
@ stdcall SamQueryInformationUser(ptr long ptr)
|
||||
@ stub SamQuerySecurityObject
|
||||
@ stub SamRemoveMemberFromAlias
|
||||
@ stub SamRemoveMemberFromForeignDomain
|
||||
@ stub SamRemoveMemberFromGroup
|
||||
@ stub SamRemoveMultipleMembersFromAlias
|
||||
@ stub SamRidToSid
|
||||
@ stdcall SamQuerySecurityObject(ptr long ptr)
|
||||
@ stdcall SamRemoveMemberFromAlias(ptr long)
|
||||
@ stdcall SamRemoveMemberFromForeignDomain(ptr long)
|
||||
@ stdcall SamRemoveMemberFromGroup(ptr long)
|
||||
@ stdcall SamRemoveMultipleMembersFromAlias(ptr ptr long)
|
||||
@ stdcall SamRidToSid(ptr long ptr)
|
||||
@ stdcall SamSetInformationAlias(ptr long ptr)
|
||||
@ stdcall SamSetInformationDomain(ptr long ptr)
|
||||
@ stdcall SamSetInformationGroup(ptr long ptr)
|
||||
@ stdcall SamSetInformationUser(ptr long ptr)
|
||||
@ stub SamSetMemberAttributesOfGroup
|
||||
@ stub SamSetSecurityObject
|
||||
@ stdcall SamSetMemberAttributesOfGroup(ptr long long)
|
||||
@ stdcall SamSetSecurityObject(ptr long ptr)
|
||||
@ stdcall SamShutdownSamServer(ptr)
|
||||
@ stub SamTestPrivateFunctionsDomain
|
||||
@ stub SamTestPrivateFunctionsUser
|
||||
|
|
|
@ -83,26 +83,38 @@ static int SIC_LoadOverlayIcon(int icon_idx);
|
|||
* NOTES
|
||||
* Creates a new icon as a copy of the passed-in icon, overlayed with a
|
||||
* shortcut image.
|
||||
* FIXME: This should go to the ImageList implementation!
|
||||
*/
|
||||
static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
|
||||
{ ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo;
|
||||
HICON ShortcutIcon, TargetIcon;
|
||||
BITMAP SourceBitmapInfo, ShortcutBitmapInfo;
|
||||
HDC SourceDC = NULL,
|
||||
ShortcutDC = NULL,
|
||||
TargetDC = NULL,
|
||||
ScreenDC = NULL;
|
||||
HBITMAP OldSourceBitmap = NULL,
|
||||
OldShortcutBitmap = NULL,
|
||||
{
|
||||
ICONINFO ShortcutIconInfo, TargetIconInfo;
|
||||
HICON ShortcutIcon = NULL, TargetIcon;
|
||||
BITMAP TargetBitmapInfo, ShortcutBitmapInfo;
|
||||
HDC ShortcutDC = NULL,
|
||||
TargetDC = NULL;
|
||||
HBITMAP OldShortcutBitmap = NULL,
|
||||
OldTargetBitmap = NULL;
|
||||
|
||||
static int s_imgListIdx = -1;
|
||||
ZeroMemory(&ShortcutIconInfo, sizeof(ShortcutIconInfo));
|
||||
ZeroMemory(&TargetIconInfo, sizeof(TargetIconInfo));
|
||||
|
||||
/* Get information about the source icon and shortcut overlay */
|
||||
if (! GetIconInfo(SourceIcon, &SourceIconInfo)
|
||||
|| 0 == GetObjectW(SourceIconInfo.hbmColor, sizeof(BITMAP), &SourceBitmapInfo))
|
||||
{
|
||||
/* Get information about the source icon and shortcut overlay.
|
||||
* We will write over the source bitmaps to get the final ones */
|
||||
if (! GetIconInfo(SourceIcon, &TargetIconInfo))
|
||||
return NULL;
|
||||
|
||||
/* Is it possible with the ImageList implementation? */
|
||||
if(!TargetIconInfo.hbmColor)
|
||||
{
|
||||
/* Maybe we'll support this at some point */
|
||||
FIXME("1bpp icon wants its overlay!\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(!GetObjectW(TargetIconInfo.hbmColor, sizeof(BITMAP), &TargetBitmapInfo))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* search for the shortcut icon only once */
|
||||
|
@ -121,23 +133,25 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
|
|||
} else
|
||||
ShortcutIcon = NULL;
|
||||
|
||||
if (NULL == ShortcutIcon
|
||||
|| ! GetIconInfo(ShortcutIcon, &ShortcutIconInfo)
|
||||
|| 0 == GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo))
|
||||
if (!ShortcutIcon || !GetIconInfo(ShortcutIcon, &ShortcutIconInfo))
|
||||
{
|
||||
return NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
TargetIconInfo = SourceIconInfo;
|
||||
TargetIconInfo.hbmMask = NULL;
|
||||
TargetIconInfo.hbmColor = NULL;
|
||||
/* Is it possible with the ImageLists ? */
|
||||
if(!ShortcutIconInfo.hbmColor)
|
||||
{
|
||||
/* Maybe we'll support this at some point */
|
||||
FIXME("Should draw 1bpp overlay!\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Setup the source, shortcut and target masks */
|
||||
SourceDC = CreateCompatibleDC(NULL);
|
||||
if (NULL == SourceDC) goto fail;
|
||||
OldSourceBitmap = (HBITMAP)SelectObject(SourceDC, SourceIconInfo.hbmMask);
|
||||
if (NULL == OldSourceBitmap) goto fail;
|
||||
if(!GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Setup the masks */
|
||||
ShortcutDC = CreateCompatibleDC(NULL);
|
||||
if (NULL == ShortcutDC) goto fail;
|
||||
OldShortcutBitmap = (HBITMAP)SelectObject(ShortcutDC, ShortcutIconInfo.hbmMask);
|
||||
|
@ -145,44 +159,120 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
|
|||
|
||||
TargetDC = CreateCompatibleDC(NULL);
|
||||
if (NULL == TargetDC) goto fail;
|
||||
TargetIconInfo.hbmMask = CreateCompatibleBitmap(TargetDC, SourceBitmapInfo.bmWidth,
|
||||
SourceBitmapInfo.bmHeight);
|
||||
if (NULL == TargetIconInfo.hbmMask) goto fail;
|
||||
ScreenDC = GetDC(NULL);
|
||||
if (NULL == ScreenDC) goto fail;
|
||||
TargetIconInfo.hbmColor = CreateCompatibleBitmap(ScreenDC, SourceBitmapInfo.bmWidth,
|
||||
SourceBitmapInfo.bmHeight);
|
||||
ReleaseDC(NULL, ScreenDC);
|
||||
if (NULL == TargetIconInfo.hbmColor) goto fail;
|
||||
OldTargetBitmap = (HBITMAP)SelectObject(TargetDC, TargetIconInfo.hbmMask);
|
||||
if (NULL == OldTargetBitmap) goto fail;
|
||||
|
||||
/* Create the target mask by ANDing the source and shortcut masks */
|
||||
if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight,
|
||||
SourceDC, 0, 0, SRCCOPY) ||
|
||||
! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
|
||||
ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
|
||||
/* Create the complete mask by ANDing the source and shortcut masks.
|
||||
* NOTE: in an ImageList, all icons have the same dimensions */
|
||||
if (!BitBlt(TargetDC, 0, 0, ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
|
||||
ShortcutDC, 0, 0, SRCAND))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Setup the source and target xor bitmap */
|
||||
if (NULL == SelectObject(SourceDC, SourceIconInfo.hbmColor) ||
|
||||
NULL == SelectObject(TargetDC, TargetIconInfo.hbmColor))
|
||||
/*
|
||||
* We must remove or add the alpha component to the shortcut overlay:
|
||||
* If we don't, SRCCOPY will copy it to our resulting icon, resulting in a
|
||||
* partially transparent icons where it shouldn't be, and to an invisible icon
|
||||
* if the underlying icon don't have any alpha channel information. (16bpp only icon for instance).
|
||||
* But if the underlying icon has alpha channel information, then we must mark the overlay information
|
||||
* as opaque.
|
||||
* NOTE: This code sucks(tm) and should belong to the ImageList implementation.
|
||||
* NOTE2: there are better ways to do this.
|
||||
*/
|
||||
if(ShortcutBitmapInfo.bmBitsPixel == 32)
|
||||
{
|
||||
BOOL add_alpha;
|
||||
BYTE buffer[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
|
||||
BITMAPINFO* lpbmi = (BITMAPINFO*)buffer;
|
||||
PVOID bits;
|
||||
PULONG pixel;
|
||||
INT i, j;
|
||||
|
||||
/* Find if the source bitmap has an alpha channel */
|
||||
if(TargetBitmapInfo.bmBitsPixel != 32) add_alpha = FALSE;
|
||||
else
|
||||
{
|
||||
ZeroMemory(buffer, sizeof(buffer));
|
||||
lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
lpbmi->bmiHeader.biWidth = TargetBitmapInfo.bmWidth;
|
||||
lpbmi->bmiHeader.biHeight = TargetBitmapInfo.bmHeight;
|
||||
lpbmi->bmiHeader.biPlanes = 1;
|
||||
lpbmi->bmiHeader.biBitCount = 32;
|
||||
|
||||
bits = HeapAlloc(GetProcessHeap(), 0, TargetBitmapInfo.bmHeight * TargetBitmapInfo.bmWidthBytes);
|
||||
|
||||
if(!bits) goto fail;
|
||||
|
||||
if(!GetDIBits(TargetDC, TargetIconInfo.hbmColor, 0, TargetBitmapInfo.bmHeight, bits, lpbmi, DIB_RGB_COLORS))
|
||||
{
|
||||
ERR("GetBIBits failed!\n");
|
||||
HeapFree(GetProcessHeap(), 0, bits);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Copy the source color bitmap to the target */
|
||||
if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight,
|
||||
SourceDC, 0, 0, SRCCOPY)) goto fail;
|
||||
i = j = 0;
|
||||
pixel = (PULONG)bits;
|
||||
|
||||
/* Copy the source xor bitmap to the target and clear out part of it by using
|
||||
the shortcut mask */
|
||||
if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor)) goto fail;
|
||||
if (!MaskBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
|
||||
ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
|
||||
for(i=0; i<TargetBitmapInfo.bmHeight; i++)
|
||||
{
|
||||
for(j=0; j<TargetBitmapInfo.bmWidth; j++)
|
||||
{
|
||||
add_alpha = (*pixel++ & 0xFF000000) != 0;
|
||||
if(add_alpha) break;
|
||||
}
|
||||
if(add_alpha) break;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, bits);
|
||||
}
|
||||
|
||||
/* Allocate the bits */
|
||||
bits = HeapAlloc(GetProcessHeap(), 0, ShortcutBitmapInfo.bmHeight*ShortcutBitmapInfo.bmWidthBytes);
|
||||
if(!bits) goto fail;
|
||||
|
||||
ZeroMemory(buffer, sizeof(buffer));
|
||||
lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
lpbmi->bmiHeader.biWidth = ShortcutBitmapInfo.bmWidth;
|
||||
lpbmi->bmiHeader.biHeight = ShortcutBitmapInfo.bmHeight;
|
||||
lpbmi->bmiHeader.biPlanes = 1;
|
||||
lpbmi->bmiHeader.biBitCount = 32;
|
||||
|
||||
if(!GetDIBits(TargetDC, ShortcutIconInfo.hbmColor, 0, ShortcutBitmapInfo.bmHeight, bits, lpbmi, DIB_RGB_COLORS))
|
||||
{
|
||||
ERR("GetBIBits failed!\n");
|
||||
HeapFree(GetProcessHeap(), 0, bits);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pixel = (PULONG)bits;
|
||||
/* Remove alpha channel component or make it totally opaque */
|
||||
for(i=0; i<ShortcutBitmapInfo.bmHeight; i++)
|
||||
{
|
||||
for(j=0; j<ShortcutBitmapInfo.bmWidth; j++)
|
||||
{
|
||||
if(add_alpha) *pixel++ |= 0xFF000000;
|
||||
else *pixel++ &= 0x00FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
/* GetDIBits return BI_BITFIELDS with masks set to 0, and SetDIBits fails when masks are 0. The irony... */
|
||||
lpbmi->bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
/* Set the bits again */
|
||||
if(!SetDIBits(TargetDC, ShortcutIconInfo.hbmColor, 0, ShortcutBitmapInfo.bmHeight, bits, lpbmi, DIB_RGB_COLORS))
|
||||
{
|
||||
ERR("SetBIBits failed!, %lu\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, bits);
|
||||
goto fail;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, bits);
|
||||
}
|
||||
|
||||
/* Now do the copy. We overwrite the original icon data */
|
||||
if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor) ||
|
||||
NULL == SelectObject(TargetDC, TargetIconInfo.hbmColor))
|
||||
goto fail;
|
||||
if (!MaskBlt(TargetDC, 0, 0, ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
|
||||
ShortcutDC, 0, 0, ShortcutIconInfo.hbmMask, 0, 0,
|
||||
MAKEROP4(0xAA0000, SRCCOPY)))
|
||||
{
|
||||
|
@ -192,11 +282,9 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
|
|||
/* Clean up, we're not goto'ing to 'fail' after this so we can be lazy and not set
|
||||
handles to NULL */
|
||||
SelectObject(TargetDC, OldTargetBitmap);
|
||||
DeleteObject(TargetDC);
|
||||
DeleteDC(TargetDC);
|
||||
SelectObject(ShortcutDC, OldShortcutBitmap);
|
||||
DeleteObject(ShortcutDC);
|
||||
SelectObject(SourceDC, OldSourceBitmap);
|
||||
DeleteObject(SourceDC);
|
||||
DeleteDC(ShortcutDC);
|
||||
|
||||
/* Create the icon using the bitmaps prepared earlier */
|
||||
TargetIcon = CreateIconIndirect(&TargetIconInfo);
|
||||
|
@ -204,19 +292,24 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
|
|||
/* CreateIconIndirect copies the bitmaps, so we can release our bitmaps now */
|
||||
DeleteObject(TargetIconInfo.hbmColor);
|
||||
DeleteObject(TargetIconInfo.hbmMask);
|
||||
/* Delete what GetIconInfo gave us */
|
||||
DeleteObject(ShortcutIconInfo.hbmColor);
|
||||
DeleteObject(ShortcutIconInfo.hbmMask);
|
||||
DestroyIcon(ShortcutIcon);
|
||||
|
||||
return TargetIcon;
|
||||
|
||||
fail:
|
||||
/* Clean up scratch resources we created */
|
||||
if (NULL != OldTargetBitmap) SelectObject(TargetDC, OldTargetBitmap);
|
||||
if (NULL != TargetDC) DeleteDC(TargetDC);
|
||||
if (NULL != OldShortcutBitmap) SelectObject(ShortcutDC, OldShortcutBitmap);
|
||||
if (NULL != ShortcutDC) DeleteDC(ShortcutDC);
|
||||
if (NULL != TargetIconInfo.hbmColor) DeleteObject(TargetIconInfo.hbmColor);
|
||||
if (NULL != TargetIconInfo.hbmMask) DeleteObject(TargetIconInfo.hbmMask);
|
||||
if (NULL != TargetDC) DeleteObject(TargetDC);
|
||||
if (NULL != OldShortcutBitmap) SelectObject(ShortcutDC, OldShortcutBitmap);
|
||||
if (NULL != ShortcutDC) DeleteObject(ShortcutDC);
|
||||
if (NULL != OldSourceBitmap) SelectObject(SourceDC, OldSourceBitmap);
|
||||
if (NULL != SourceDC) DeleteObject(SourceDC);
|
||||
if (NULL != ShortcutIconInfo.hbmColor) DeleteObject(ShortcutIconInfo.hbmColor);
|
||||
if (NULL != ShortcutIconInfo.hbmMask) DeleteObject(ShortcutIconInfo.hbmColor);
|
||||
if (NULL != ShortcutIcon) DestroyIcon(ShortcutIcon);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -228,7 +321,8 @@ fail:
|
|||
* appends an icon pair to the end of the cache
|
||||
*/
|
||||
static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags)
|
||||
{ LPSIC_ENTRY lpsice;
|
||||
{
|
||||
LPSIC_ENTRY lpsice;
|
||||
INT ret, index, index1;
|
||||
WCHAR path[MAX_PATH];
|
||||
TRACE("%s %i %p %p\n", debugstr_w(sSourceFile), dwSourceIndex, hSmallIcon ,hBigIcon);
|
||||
|
@ -247,23 +341,38 @@ static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallI
|
|||
index = DPA_InsertPtr(sic_hdpa, 0x7fff, lpsice);
|
||||
if ( INVALID_INDEX == index )
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, lpsice->sSourceFile);
|
||||
SHFree(lpsice);
|
||||
ret = INVALID_INDEX;
|
||||
goto leave;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
index = ImageList_AddIcon (ShellSmallIconList, hSmallIcon);
|
||||
index1= ImageList_AddIcon (ShellBigIconList, hBigIcon);
|
||||
|
||||
/* Something went wrong when allocating a new image in the list. Abort. */
|
||||
if((index == -1) || (index1 == -1))
|
||||
{
|
||||
WARN("Something went wrong when adding the icon to the list: small - 0x%x, big - 0x%x.\n",
|
||||
index, index1);
|
||||
if(index != -1) ImageList_Remove(ShellSmallIconList, index);
|
||||
if(index1 != -1) ImageList_Remove(ShellBigIconList, index1);
|
||||
ret = INVALID_INDEX;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (index!=index1)
|
||||
{
|
||||
FIXME("iconlists out of sync 0x%x 0x%x\n", index, index1);
|
||||
/* What to do ???? */
|
||||
}
|
||||
lpsice->dwListIndex = index;
|
||||
ret = lpsice->dwListIndex;
|
||||
}
|
||||
|
||||
leave:
|
||||
if(ret == INVALID_INDEX)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, lpsice->sSourceFile);
|
||||
SHFree(lpsice);
|
||||
}
|
||||
LeaveCriticalSection(&SHELL32_SicCS);
|
||||
return ret;
|
||||
}
|
||||
|
@ -274,23 +383,23 @@ static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallI
|
|||
* gets small/big icon by number from a file
|
||||
*/
|
||||
static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
|
||||
{ HICON hiconLarge=0;
|
||||
{
|
||||
HICON hiconLarge=0;
|
||||
HICON hiconSmall=0;
|
||||
HICON hiconLargeShortcut;
|
||||
HICON hiconSmallShortcut;
|
||||
|
||||
#if defined(__CYGWIN__) || defined (__MINGW32__) || defined(_MSC_VER)
|
||||
UINT ret;
|
||||
static UINT (WINAPI*PrivateExtractIconExW)(LPCWSTR,int,HICON*,HICON*,UINT) = NULL;
|
||||
|
||||
if (!PrivateExtractIconExW) {
|
||||
if (!PrivateExtractIconExW)
|
||||
{
|
||||
HMODULE hUser32 = GetModuleHandleA("user32");
|
||||
PrivateExtractIconExW = (UINT(WINAPI*)(LPCWSTR,int,HICON*,HICON*,UINT)) GetProcAddress(hUser32, "PrivateExtractIconExW");
|
||||
}
|
||||
|
||||
if (PrivateExtractIconExW)
|
||||
{
|
||||
PrivateExtractIconExW(sSourceFile, dwSourceIndex, &hiconLarge, &hiconSmall, 1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
PrivateExtractIconsW(sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, NULL, 1, 0);
|
||||
PrivateExtractIconsW(sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, NULL, 1, 0);
|
||||
|
@ -299,15 +408,19 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
|
|||
if ( !hiconLarge || !hiconSmall)
|
||||
{
|
||||
WARN("failure loading icon %i from %s (%p %p)\n", dwSourceIndex, debugstr_w(sSourceFile), hiconLarge, hiconSmall);
|
||||
return -1;
|
||||
if(hiconLarge) DestroyIcon(hiconLarge);
|
||||
if(hiconSmall) DestroyIcon(hiconSmall);
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
|
||||
if (0 != (dwFlags & GIL_FORSHORTCUT))
|
||||
{
|
||||
hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE);
|
||||
hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE);
|
||||
HICON hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE);
|
||||
HICON hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE);
|
||||
if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut)
|
||||
{
|
||||
DestroyIcon(hiconLarge);
|
||||
DestroyIcon(hiconSmall);
|
||||
hiconLarge = hiconLargeShortcut;
|
||||
hiconSmall = hiconSmallShortcut;
|
||||
}
|
||||
|
@ -320,7 +433,10 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
|
|||
}
|
||||
}
|
||||
|
||||
return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags);
|
||||
ret = SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags);
|
||||
DestroyIcon(hiconLarge);
|
||||
DestroyIcon(hiconSmall);
|
||||
return ret;
|
||||
}
|
||||
/*****************************************************************************
|
||||
* SIC_GetIconIndex [internal]
|
||||
|
@ -367,6 +483,7 @@ INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
|
|||
LeaveCriticalSection(&SHELL32_SicCS);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* SIC_Initialize [internal]
|
||||
*/
|
||||
|
@ -378,6 +495,7 @@ BOOL SIC_Initialize(void)
|
|||
HDC hDC;
|
||||
INT bpp;
|
||||
DWORD ilMask;
|
||||
BOOL result = FALSE;
|
||||
|
||||
TRACE("Entered SIC_Initialize\n");
|
||||
|
||||
|
@ -397,11 +515,11 @@ BOOL SIC_Initialize(void)
|
|||
if (!hDC)
|
||||
{
|
||||
ERR("Failed to create information context (error %d)\n", GetLastError());
|
||||
return FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
bpp = GetDeviceCaps(hDC, BITSPIXEL);
|
||||
ReleaseDC(NULL, hDC);
|
||||
DeleteDC(hDC);
|
||||
|
||||
if (bpp <= 4)
|
||||
ilMask = ILC_COLOR4;
|
||||
|
@ -428,14 +546,23 @@ BOOL SIC_Initialize(void)
|
|||
ilMask,
|
||||
100,
|
||||
100);
|
||||
if (!ShellSmallIconList)
|
||||
{
|
||||
ERR("Failed to create the small icon list.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ShellBigIconList = ImageList_Create(cx_large,
|
||||
cy_large,
|
||||
ilMask,
|
||||
100,
|
||||
100);
|
||||
if (ShellSmallIconList)
|
||||
if (!ShellBigIconList)
|
||||
{
|
||||
ERR("Failed to create the big icon list.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Load the document icon, which is used as the default if an icon isn't found. */
|
||||
hSm = (HICON)LoadImageW(shell32_hInstance,
|
||||
MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
|
||||
|
@ -445,18 +572,10 @@ BOOL SIC_Initialize(void)
|
|||
LR_SHARED | LR_DEFAULTCOLOR);
|
||||
if (!hSm)
|
||||
{
|
||||
ERR("Failed to load IDI_SHELL_DOCUMENT icon1!\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Failed to load ShellSmallIconList\n");
|
||||
return FALSE;
|
||||
ERR("Failed to load small IDI_SHELL_DOCUMENT icon!\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ShellBigIconList)
|
||||
{
|
||||
hLg = (HICON)LoadImageW(shell32_hInstance,
|
||||
MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
|
||||
IMAGE_ICON,
|
||||
|
@ -465,24 +584,45 @@ BOOL SIC_Initialize(void)
|
|||
LR_SHARED | LR_DEFAULTCOLOR);
|
||||
if (!hLg)
|
||||
{
|
||||
ERR("Failed to load IDI_SHELL_DOCUMENT icon2!\n");
|
||||
DestroyIcon(hSm);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Failed to load ShellBigIconList\n");
|
||||
return FALSE;
|
||||
ERR("Failed to load large IDI_SHELL_DOCUMENT icon!\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
SIC_IconAppend(swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0);
|
||||
SIC_IconAppend(swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0);
|
||||
if(SIC_IconAppend(swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0) == INVALID_INDEX)
|
||||
{
|
||||
ERR("Failed to add IDI_SHELL_DOCUMENT icon to cache.\n");
|
||||
goto end;
|
||||
}
|
||||
if(SIC_IconAppend(swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0) == INVALID_INDEX)
|
||||
{
|
||||
ERR("Failed to add IDI_SHELL_DOCUMENT icon to cache.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Everything went fine */
|
||||
result = TRUE;
|
||||
|
||||
end:
|
||||
/* The image list keeps a copy of the icons, we must destroy them */
|
||||
if(hSm) DestroyIcon(hSm);
|
||||
if(hLg) DestroyIcon(hLg);
|
||||
|
||||
/* Clean everything if something went wrong */
|
||||
if(!result)
|
||||
{
|
||||
if(sic_hdpa) DPA_Destroy(sic_hdpa);
|
||||
if(ShellSmallIconList) ImageList_Destroy(ShellSmallIconList);
|
||||
if(ShellBigIconList) ImageList_Destroy(ShellSmallIconList);
|
||||
sic_hdpa = NULL;
|
||||
ShellSmallIconList = NULL;
|
||||
ShellBigIconList = NULL;
|
||||
}
|
||||
|
||||
TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
|
||||
|
||||
return TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SIC_Destroy
|
||||
*
|
||||
|
|
|
@ -306,6 +306,38 @@ HidP_GetScaledUsageValue(
|
|||
return HidParser_GetScaledUsageValue(&Parser, PreparsedData, ReportType, UsagePage, LinkCollection, Usage, UsageValue, Report, ReportLength);
|
||||
}
|
||||
|
||||
HIDAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HidP_GetUsageValue(
|
||||
IN HIDP_REPORT_TYPE ReportType,
|
||||
IN USAGE UsagePage,
|
||||
IN USHORT LinkCollection,
|
||||
IN USAGE Usage,
|
||||
OUT PULONG UsageValue,
|
||||
IN PHIDP_PREPARSED_DATA PreparsedData,
|
||||
IN PCHAR Report,
|
||||
IN ULONG ReportLength)
|
||||
{
|
||||
HID_PARSER Parser;
|
||||
|
||||
//
|
||||
// sanity check
|
||||
//
|
||||
ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature);
|
||||
|
||||
//
|
||||
// init parser
|
||||
//
|
||||
HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser);
|
||||
|
||||
//
|
||||
// get scaled usage value
|
||||
//
|
||||
return HidParser_GetUsageValue(&Parser, PreparsedData, ReportType, UsagePage, LinkCollection, Usage, UsageValue, Report, ReportLength);
|
||||
}
|
||||
|
||||
|
||||
HIDAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
@ -405,24 +437,6 @@ HidP_GetLinkCollectionNodes(
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
HIDAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HidP_GetUsageValue(
|
||||
IN HIDP_REPORT_TYPE ReportType,
|
||||
IN USAGE UsagePage,
|
||||
IN USHORT LinkCollection,
|
||||
IN USAGE Usage,
|
||||
OUT PULONG UsageValue,
|
||||
IN PHIDP_PREPARSED_DATA PreparsedData,
|
||||
IN PCHAR Report,
|
||||
IN ULONG ReportLength)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HidP_SysPowerEvent (
|
||||
|
|
|
@ -37,6 +37,7 @@ MouHid_GetButtonMove(
|
|||
OUT PLONG LastY)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG ValueX, ValueY;
|
||||
|
||||
/* init result */
|
||||
*LastX = 0;
|
||||
|
@ -44,17 +45,50 @@ MouHid_GetButtonMove(
|
|||
|
||||
/* get scaled usage value x */
|
||||
Status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_X, (PLONG)LastX, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||
if (Status != HIDP_STATUS_SUCCESS)
|
||||
{
|
||||
/* FIXME: handle more errors */
|
||||
if (Status == HIDP_STATUS_BAD_LOG_PHY_VALUES)
|
||||
{
|
||||
/* FIXME: assume it operates in absolute mode */
|
||||
DeviceExtension->MouseAbsolute = TRUE;
|
||||
|
||||
/* get unscaled value */
|
||||
Status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_X, (PULONG)&ValueX, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||
|
||||
/* FIXME handle error */
|
||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
||||
|
||||
/* absolute pointing devices values need be in range 0 - 0xffff */
|
||||
ASSERT(DeviceExtension->ValueCapsX.LogicalMax > 0);
|
||||
|
||||
*LastX = (ValueX * 0xFFFF) / DeviceExtension->ValueCapsX.LogicalMax;
|
||||
}
|
||||
}
|
||||
|
||||
/* get scaled usage value y */
|
||||
Status = HidP_GetScaledUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Y, (PLONG)LastY, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||
if (Status != HIDP_STATUS_SUCCESS)
|
||||
{
|
||||
// FIXME: handle more errors
|
||||
if (Status == HIDP_STATUS_BAD_LOG_PHY_VALUES)
|
||||
{
|
||||
// assume it operates in absolute mode
|
||||
DeviceExtension->MouseAbsolute = TRUE;
|
||||
|
||||
// get unscaled value
|
||||
Status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Y, (PULONG)&ValueY, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||
|
||||
/* FIXME handle error */
|
||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
||||
|
||||
/* absolute pointing devices values need be in range 0 - 0xffff */
|
||||
ASSERT(DeviceExtension->ValueCapsY.LogicalMax);
|
||||
*LastY = (ValueY * 0xFFFF) / DeviceExtension->ValueCapsY.LogicalMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
MouHid_GetButtonFlags(
|
||||
IN PMOUHID_DEVICE_EXTENSION DeviceExtension,
|
||||
|
@ -132,6 +166,12 @@ MouHid_GetButtonFlags(
|
|||
TempList = DeviceExtension->CurrentUsageList;
|
||||
DeviceExtension->CurrentUsageList = DeviceExtension->PreviousUsageList;
|
||||
DeviceExtension->PreviousUsageList = TempList;
|
||||
|
||||
if (DeviceExtension->MouseAbsolute)
|
||||
{
|
||||
// mouse operates absolute
|
||||
*ButtonFlags |= MOUSE_MOVE_ABSOLUTE;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -195,12 +235,12 @@ MouHid_ReadCompletion(
|
|||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
/* get mouse change flags */
|
||||
MouHid_GetButtonFlags(DeviceExtension, &ButtonFlags);
|
||||
|
||||
/* get mouse change */
|
||||
MouHid_GetButtonMove(DeviceExtension, &LastX, &LastY);
|
||||
|
||||
/* get mouse change flags */
|
||||
MouHid_GetButtonFlags(DeviceExtension, &ButtonFlags);
|
||||
|
||||
/* init input data */
|
||||
RtlZeroMemory(&MouseInputData, sizeof(MOUSE_INPUT_DATA));
|
||||
|
||||
|
@ -227,6 +267,12 @@ MouHid_ReadCompletion(
|
|||
}
|
||||
}
|
||||
|
||||
DPRINT("[MOUHID] ReportData %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
DeviceExtension->Report[0] & 0xFF,
|
||||
DeviceExtension->Report[1] & 0xFF, DeviceExtension->Report[2] & 0xFF,
|
||||
DeviceExtension->Report[3] & 0xFF, DeviceExtension->Report[4] & 0xFF,
|
||||
DeviceExtension->Report[5] & 0xFF, DeviceExtension->Report[6] & 0xFF);
|
||||
|
||||
DPRINT("[MOUHID] LastX %ld LastY %ld Flags %x ButtonData %x\n", MouseInputData.LastX, MouseInputData.LastY, MouseInputData.ButtonFlags, MouseInputData.ButtonData);
|
||||
|
||||
/* dispatch mouse action */
|
||||
|
@ -700,10 +746,10 @@ MouHid_StartDevice(
|
|||
DeviceExtension->PreparsedData = PreparsedData;
|
||||
|
||||
ValueCapsLength = 1;
|
||||
HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_X, &ValueCaps, &ValueCapsLength, PreparsedData);
|
||||
HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_X, &DeviceExtension->ValueCapsX, &ValueCapsLength, PreparsedData);
|
||||
|
||||
ValueCapsLength = 1;
|
||||
HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Y, &ValueCaps, &ValueCapsLength, PreparsedData);
|
||||
HidP_GetSpecificValueCaps(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Y, &DeviceExtension->ValueCapsY, &ValueCapsLength, PreparsedData);
|
||||
|
||||
/* now check for wheel mouse support */
|
||||
ValueCapsLength = 1;
|
||||
|
|
|
@ -109,6 +109,22 @@ typedef struct
|
|||
//
|
||||
UCHAR StopReadReport;
|
||||
|
||||
//
|
||||
// mouse absolute
|
||||
//
|
||||
UCHAR MouseAbsolute;
|
||||
|
||||
//
|
||||
// value caps x
|
||||
//
|
||||
HIDP_VALUE_CAPS ValueCapsX;
|
||||
|
||||
//
|
||||
// value caps y button
|
||||
//
|
||||
HIDP_VALUE_CAPS ValueCapsY;
|
||||
|
||||
|
||||
}MOUHID_DEVICE_EXTENSION, *PMOUHID_DEVICE_EXTENSION;
|
||||
|
||||
#define WHEEL_DELTA 120
|
||||
|
|
|
@ -474,8 +474,11 @@ USBD_ParseDescriptors(
|
|||
return CommonDescriptor;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(CommonDescriptor->bLength);
|
||||
if (CommonDescriptor->bLength == 0)
|
||||
{
|
||||
/* invalid usb descriptor */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* move to next descriptor */
|
||||
CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
|
||||
|
|
|
@ -819,6 +819,7 @@ CreateDeviceIds(
|
|||
LPWSTR DeviceString;
|
||||
WCHAR Buffer[200];
|
||||
PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
|
||||
PHUB_DEVICE_EXTENSION HubDeviceExtension;
|
||||
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;
|
||||
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
|
||||
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
|
||||
|
@ -828,6 +829,9 @@ CreateDeviceIds(
|
|||
//
|
||||
UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)UsbChildDeviceObject->DeviceExtension;
|
||||
|
||||
// get hub device extension
|
||||
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) UsbChildExtension->ParentDeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// get device descriptor
|
||||
//
|
||||
|
@ -1011,10 +1015,12 @@ CreateDeviceIds(
|
|||
//
|
||||
if (UsbChildExtension->DeviceDesc.iSerialNumber)
|
||||
{
|
||||
LPWSTR SerialBuffer = NULL;
|
||||
|
||||
Status = GetUsbStringDescriptor(UsbChildDeviceObject,
|
||||
UsbChildExtension->DeviceDesc.iSerialNumber,
|
||||
0,
|
||||
(PVOID*)&UsbChildExtension->usInstanceId.Buffer,
|
||||
(PVOID*)&SerialBuffer,
|
||||
&UsbChildExtension->usInstanceId.Length);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -1022,15 +1028,31 @@ CreateDeviceIds(
|
|||
return Status;
|
||||
}
|
||||
|
||||
UsbChildExtension->usInstanceId.MaximumLength = UsbChildExtension->usInstanceId.Length;
|
||||
DPRINT("Usb InstanceId %wZ\n", &UsbChildExtension->usInstanceId);
|
||||
// construct instance id buffer
|
||||
Index = swprintf(Buffer, L"%04d&%s", HubDeviceExtension->InstanceCount, SerialBuffer) + 1;
|
||||
UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR));
|
||||
if (UsbChildExtension->usInstanceId.Buffer == NULL)
|
||||
{
|
||||
DPRINT1("Error: failed to allocate %lu bytes\n", Index * sizeof(WCHAR));
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// copy instance id
|
||||
//
|
||||
RtlCopyMemory(UsbChildExtension->usInstanceId.Buffer, Buffer, Index * sizeof(WCHAR));
|
||||
UsbChildExtension->usInstanceId.Length = UsbChildExtension->usInstanceId.MaximumLength = Index * sizeof(WCHAR);
|
||||
ExFreePool(SerialBuffer);
|
||||
|
||||
DPRINT("Usb InstanceId %wZ InstanceCount %x\n", &UsbChildExtension->usInstanceId, HubDeviceExtension->InstanceCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// the device did not provide a serial number, lets create a pseudo instance id
|
||||
//
|
||||
Index = swprintf(Buffer, L"0&%04d", UsbChildExtension->PortNumber) + 1;
|
||||
Index = swprintf(Buffer, L"%04d&%04d", HubDeviceExtension->InstanceCount, UsbChildExtension->PortNumber) + 1;
|
||||
UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR));
|
||||
if (UsbChildExtension->usInstanceId.Buffer == NULL)
|
||||
{
|
||||
|
@ -1304,6 +1326,7 @@ CreateUsbChildDeviceObject(
|
|||
}
|
||||
|
||||
HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] = NewChildDeviceObject;
|
||||
HubDeviceExtension->InstanceCount++;
|
||||
|
||||
IoInvalidateDeviceRelations(RootHubDeviceObject, BusRelations);
|
||||
return STATUS_SUCCESS;
|
||||
|
|
|
@ -558,6 +558,7 @@ USBHUB_PdoHandlePnp(
|
|||
ULONG Index;
|
||||
ULONG bFound;
|
||||
PDEVICE_RELATIONS DeviceRelation;
|
||||
PDEVICE_OBJECT ParentDevice;
|
||||
|
||||
UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
@ -645,6 +646,7 @@ USBHUB_PdoHandlePnp(
|
|||
{
|
||||
PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension;
|
||||
PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface;
|
||||
ParentDevice = UsbChildExtension->ParentDeviceObject;
|
||||
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
|
||||
|
||||
|
@ -671,10 +673,13 @@ USBHUB_PdoHandlePnp(
|
|||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
/* delete device */
|
||||
IoDeleteDevice(DeviceObject);
|
||||
|
||||
if (bFound)
|
||||
{
|
||||
/* Delete the device object */
|
||||
IoDeleteDevice(DeviceObject);
|
||||
/* invalidate device relations */
|
||||
IoInvalidateDeviceRelations(ParentDevice, BusRelations);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -731,6 +736,12 @@ USBHUB_PdoHandlePnp(
|
|||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp);
|
||||
}
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
{
|
||||
DPRINT("[USBHUB] HandlePnp IRP_MN_SURPRISE_REMOVAL\n");
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
|
||||
|
|
|
@ -103,8 +103,9 @@ typedef struct _HUB_DEVICE_EXTENSION
|
|||
PVOID RootHubHandle;
|
||||
USB_BUS_INTERFACE_USBDI_V2 DeviceInterface;
|
||||
|
||||
|
||||
UNICODE_STRING SymbolicLinkName;
|
||||
ULONG InstanceCount;
|
||||
|
||||
} HUB_DEVICE_EXTENSION, *PHUB_DEVICE_EXTENSION;
|
||||
|
||||
// createclose.c
|
||||
|
|
|
@ -125,10 +125,19 @@ USBSTOR_FdoHandleRemoveDevice(
|
|||
IN OUT PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG Index;
|
||||
|
||||
DPRINT("Handling FDO removal\n");
|
||||
DPRINT("Handling FDO removal %p\n", DeviceObject);
|
||||
|
||||
/* We don't need to request removal of our children here */
|
||||
/* FIXME: wait for devices finished processing */
|
||||
for(Index = 0; Index < 16; Index++)
|
||||
{
|
||||
if (DeviceExtension->ChildPDO[Index] != NULL)
|
||||
{
|
||||
DPRINT("Deleting PDO %p RefCount %x AttachedDevice %p \n", DeviceExtension->ChildPDO[Index], DeviceExtension->ChildPDO[Index]->ReferenceCount, DeviceExtension->ChildPDO[Index]->AttachedDevice);
|
||||
IoDeleteDevice(DeviceExtension->ChildPDO[Index]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Send the IRP down the stack */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
|
@ -264,7 +273,7 @@ USBSTOR_FdoHandleStartDevice(
|
|||
//
|
||||
// create pdo
|
||||
//
|
||||
Status = USBSTOR_CreatePDO(DeviceObject, Index, &DeviceExtension->ChildPDO[Index]);
|
||||
Status = USBSTOR_CreatePDO(DeviceObject, Index);
|
||||
|
||||
//
|
||||
// check for failure
|
||||
|
@ -282,6 +291,7 @@ USBSTOR_FdoHandleStartDevice(
|
|||
// increment pdo index
|
||||
//
|
||||
Index++;
|
||||
DeviceExtension->InstanceCount++;
|
||||
|
||||
}while(Index < DeviceExtension->MaxLUN);
|
||||
|
||||
|
@ -340,8 +350,20 @@ USBSTOR_FdoHandlePnp(
|
|||
|
||||
switch(IoStack->MinorFunction)
|
||||
{
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
{
|
||||
DPRINT("IRP_MN_SURPRISE_REMOVAL %p\n", DeviceObject);
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
|
||||
//
|
||||
// forward irp to next device object
|
||||
//
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
|
||||
}
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
{
|
||||
DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS %p\n", DeviceObject);
|
||||
Status = USBSTOR_FdoHandleDeviceRelations(DeviceExtension, Irp);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -676,9 +676,9 @@ USBSTOR_PdoHandleQueryInstanceId(
|
|||
else
|
||||
{
|
||||
//
|
||||
// FIXME: should use some random value
|
||||
// use instance count and LUN
|
||||
//
|
||||
swprintf(Buffer, L"%s&%d", L"00000000", PDODeviceExtension->LUN);
|
||||
swprintf(Buffer, L"%04d&%d", FDODeviceExtension->InstanceCount, PDODeviceExtension->LUN);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -897,7 +897,7 @@ USBSTOR_PdoHandlePnp(
|
|||
// check if no unique id
|
||||
//
|
||||
Caps = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
|
||||
Caps->UniqueID = TRUE; //FIXME
|
||||
Caps->UniqueID = FALSE; // no unique id is supported
|
||||
Caps->Removable = TRUE; //FIXME
|
||||
}
|
||||
break;
|
||||
|
@ -929,6 +929,11 @@ USBSTOR_PdoHandlePnp(
|
|||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//
|
||||
|
@ -1256,13 +1261,19 @@ USBSTOR_SendFormatCapacityIrp(
|
|||
NTSTATUS
|
||||
USBSTOR_CreatePDO(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN UCHAR LUN,
|
||||
OUT PDEVICE_OBJECT *ChildDeviceObject)
|
||||
IN UCHAR LUN)
|
||||
{
|
||||
PDEVICE_OBJECT PDO;
|
||||
NTSTATUS Status;
|
||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
PUFI_INQUIRY_RESPONSE Response;
|
||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
|
||||
//
|
||||
// create child device object
|
||||
|
@ -1292,7 +1303,7 @@ USBSTOR_CreatePDO(
|
|||
RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
|
||||
PDODeviceExtension->Common.IsFDO = FALSE;
|
||||
PDODeviceExtension->LowerDeviceObject = DeviceObject;
|
||||
PDODeviceExtension->PDODeviceObject = ChildDeviceObject;
|
||||
PDODeviceExtension->PDODeviceObject = &FDODeviceExtension->ChildPDO[LUN];
|
||||
PDODeviceExtension->Self = PDO;
|
||||
PDODeviceExtension->LUN = LUN;
|
||||
|
||||
|
@ -1309,7 +1320,7 @@ USBSTOR_CreatePDO(
|
|||
//
|
||||
// output device object
|
||||
//
|
||||
*ChildDeviceObject = PDO;
|
||||
FDODeviceExtension->ChildPDO[LUN] = PDO;
|
||||
|
||||
//
|
||||
// send inquiry command by irp
|
||||
|
|
|
@ -71,6 +71,7 @@ typedef struct
|
|||
PSCSI_REQUEST_BLOCK LastTimerActiveSrb; // last timer tick active srb
|
||||
ULONG SrbErrorHandlingActive; // error handling of srb is activated
|
||||
ULONG TimerWorkQueueEnabled; // timer work queue enabled
|
||||
ULONG InstanceCount; // pdo instance count
|
||||
}FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
||||
|
||||
typedef struct
|
||||
|
@ -364,8 +365,7 @@ USBSTOR_PdoHandlePnp(
|
|||
NTSTATUS
|
||||
USBSTOR_CreatePDO(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN UCHAR LUN,
|
||||
OUT PDEVICE_OBJECT *ChildDeviceObject);
|
||||
IN UCHAR LUN);
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
|
|
|
@ -271,6 +271,12 @@ typedef enum _GROUP_INFORMATION_CLASS
|
|||
GroupReplicationInformation
|
||||
} GROUP_INFORMATION_CLASS;
|
||||
|
||||
typedef struct _GROUP_MEMBERSHIP
|
||||
{
|
||||
ULONG RelativeId;
|
||||
ULONG Attributes;
|
||||
} GROUP_MEMBERSHIP, *PGROUP_MEMBERSHIP;
|
||||
|
||||
typedef enum _USER_INFORMATION_CLASS
|
||||
{
|
||||
UserGeneralInformation = 1,
|
||||
|
@ -322,6 +328,12 @@ SamAddMemberToGroup(IN SAM_HANDLE GroupHandle,
|
|||
IN ULONG MemberId,
|
||||
IN ULONG Attributes);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamAddMultipleMembersToAlias(IN SAM_HANDLE AliasHandle,
|
||||
IN PSID *MemberIds,
|
||||
IN ULONG MemberCount);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamCloseHandle(IN SAM_HANDLE SamHandle);
|
||||
|
@ -367,6 +379,18 @@ SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
|
|||
OUT PSAM_HANDLE UserHandle,
|
||||
OUT PULONG RelativeId);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamDeleteAlias(IN SAM_HANDLE AliasHandle);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamDeleteGroup(IN SAM_HANDLE GroupHandle);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamDeleteUser(IN SAM_HANDLE UserHandle);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamEnumerateAliasesInDomain(IN SAM_HANDLE DomainHandle,
|
||||
|
@ -412,12 +436,25 @@ SamGetAliasMembership(IN SAM_HANDLE DomainHandle,
|
|||
OUT PULONG MembershipCount,
|
||||
OUT PULONG *Aliases);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamGetGroupsForUser(IN SAM_HANDLE UserHandle,
|
||||
OUT PGROUP_MEMBERSHIP *Groups,
|
||||
OUT PULONG MembershipCount);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamGetMembersInAlias(IN SAM_HANDLE AliasHandle,
|
||||
OUT PSID **MemberIds,
|
||||
OUT PULONG MemberCount);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamGetMembersInGroup(IN SAM_HANDLE GroupHandle,
|
||||
OUT PULONG *MemberIds,
|
||||
OUT PULONG *Attributes,
|
||||
OUT PULONG MemberCount);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle,
|
||||
|
@ -492,11 +529,39 @@ SamQueryInformationUser(IN SAM_HANDLE UserHandle,
|
|||
IN USER_INFORMATION_CLASS UserInformationClass,
|
||||
OUT PVOID *Buffer);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamQuerySecurityObject(IN SAM_HANDLE ObjectHandle,
|
||||
IN SECURITY_INFORMATION SecurityInformation,
|
||||
OUT PSECURITY_DESCRIPTOR *SecurityDescriptor);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamRemoveMemberFromAlias(IN SAM_HANDLE AliasHandle,
|
||||
IN PSID MemberId);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamRemoveMemberFromForeignDomain(IN SAM_HANDLE DomainHandle,
|
||||
IN PSID MemberId);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamRemoveMemberFromGroup(IN SAM_HANDLE GroupHandle,
|
||||
IN ULONG MemberId);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamRemoveMultipleMembersFromAlias(IN SAM_HANDLE AliasHandle,
|
||||
IN PSID *MemberIds,
|
||||
IN ULONG MemberCount);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamRidToSid(IN SAM_HANDLE ObjectHandle,
|
||||
IN ULONG Rid,
|
||||
OUT PSID *Sid);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamSetInformationAlias(IN SAM_HANDLE AliasHandle,
|
||||
|
@ -521,6 +586,18 @@ SamSetInformationUser(IN SAM_HANDLE UserHandle,
|
|||
IN USER_INFORMATION_CLASS UserInformationClass,
|
||||
IN PVOID Buffer);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamSetMemberAttributesOfGroup(IN SAM_HANDLE GroupHandle,
|
||||
IN ULONG MemberId,
|
||||
IN ULONG Attributes);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamSetSecurityObject(IN SAM_HANDLE ObjectHandle,
|
||||
IN SECURITY_INFORMATION SecurityInformation,
|
||||
IN PSECURITY_DESCRIPTOR SecurityDescriptor);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SamShutdownSamServer(IN SAM_HANDLE ServerHandle);
|
||||
|
|
|
@ -99,11 +99,13 @@ typedef struct _SAMPR_SR_SECURITY_DESCRIPTOR
|
|||
[size_is(Length)] unsigned char* SecurityDescriptor;
|
||||
} SAMPR_SR_SECURITY_DESCRIPTOR, *PSAMPR_SR_SECURITY_DESCRIPTOR;
|
||||
|
||||
cpp_quote("#ifndef _NTSAM_")
|
||||
typedef struct _GROUP_MEMBERSHIP
|
||||
{
|
||||
unsigned long RelativeId;
|
||||
unsigned long Attributes;
|
||||
} GROUP_MEMBERSHIP, *PGROUP_MEMBERSHIP;
|
||||
cpp_quote("#endif")
|
||||
|
||||
typedef struct _SAMPR_GET_GROUPS_BUFFER
|
||||
{
|
||||
|
|
|
@ -24,23 +24,23 @@
|
|||
#define WINE_UNICODE_INLINE static inline
|
||||
#endif
|
||||
|
||||
#define memicmpW(s1,s2,n) _wcsnicmp((const wchar_t *)(s1),(const wchar_t *)(s2),(n))
|
||||
#define strlenW(s) wcslen((const wchar_t *)(s))
|
||||
#define strcpyW(d,s) wcscpy((wchar_t *)(d),(const wchar_t *)(s))
|
||||
#define strcatW(d,s) wcscat((wchar_t *)(d),(const wchar_t *)(s))
|
||||
#define strcspnW(d,s) wcscspn((wchar_t *)(d),(const wchar_t *)(s))
|
||||
#define strstrW(d,s) wcsstr((const wchar_t *)(d),(const wchar_t *)(s))
|
||||
#define strtolW(s,e,b) wcstol((const wchar_t *)(s),(wchar_t **)(e),(b))
|
||||
#define strchrW(s,c) wcschr((const wchar_t *)(s),(wchar_t)(c))
|
||||
#define strrchrW(s,c) wcsrchr((const wchar_t *)(s),(wchar_t)(c))
|
||||
#define strncmpW(s1,s2,n) wcsncmp((const wchar_t *)(s1),(const wchar_t *)(s2),(n))
|
||||
#define strncpyW(s1,s2,n) wcsncpy((wchar_t *)(s1),(const wchar_t *)(s2),(n))
|
||||
#define strcmpW(s1,s2) wcscmp((const wchar_t *)(s1),(const wchar_t *)(s2))
|
||||
#define strcmpiW(s1,s2) _wcsicmp((const wchar_t *)(s1),(const wchar_t *)(s2))
|
||||
#define strncmpiW(s1,s2,n) _wcsnicmp((const wchar_t *)(s1),(const wchar_t *)(s2),(n))
|
||||
#define strtoulW(s1,s2,b) wcstoul((const wchar_t *)(s1),(wchar_t **)(s2),(b))
|
||||
#define strspnW(str, accept) wcsspn((const wchar_t *)(str), (const wchar_t *)(accept))
|
||||
#define strpbrkW(str, accept) wcspbrk((const wchar_t *)(str), (const wchar_t *)(accept))
|
||||
#define memicmpW(s1,s2,n) _wcsnicmp((s1),(s2),(n))
|
||||
#define strlenW(s) wcslen((s))
|
||||
#define strcpyW(d,s) wcscpy((d),(s))
|
||||
#define strcatW(d,s) wcscat((d),(s))
|
||||
#define strcspnW(d,s) wcscspn((d),(s))
|
||||
#define strstrW(d,s) wcsstr((d),(s))
|
||||
#define strtolW(s,e,b) wcstol((s),(e),(b))
|
||||
#define strchrW(s,c) wcschr((s),(c))
|
||||
#define strrchrW(s,c) wcsrchr((s),(c))
|
||||
#define strncmpW(s1,s2,n) wcsncmp((s1),(s2),(n))
|
||||
#define strncpyW(s1,s2,n) wcsncpy((s1),(s2),(n))
|
||||
#define strcmpW(s1,s2) wcscmp((s1),(s2))
|
||||
#define strcmpiW(s1,s2) _wcsicmp((s1),(s2))
|
||||
#define strncmpiW(s1,s2,n) _wcsnicmp((s1),(s2),(n))
|
||||
#define strtoulW(s1,s2,b) wcstoul((s1),(s2),(b))
|
||||
#define strspnW(str, accept) wcsspn((str),(accept))
|
||||
#define strpbrkW(str, accept) wcspbrk((str),(accept))
|
||||
#define tolowerW(n) towlower((n))
|
||||
#define toupperW(n) towupper((n))
|
||||
#define islowerW(n) iswlower((n))
|
||||
|
@ -51,10 +51,10 @@
|
|||
#define isxdigitW(n) iswxdigit((n))
|
||||
#define isspaceW(n) iswspace((n))
|
||||
#define iscntrlW(n) iswcntrl((n))
|
||||
#define atoiW(s) _wtoi((const wchar_t *)(s))
|
||||
#define atolW(s) _wtol((const wchar_t *)(s))
|
||||
#define strlwrW(s) _wcslwr((wchar_t *)(s))
|
||||
#define struprW(s) _wcsupr((wchar_t *)(s))
|
||||
#define atoiW(s) _wtoi((s))
|
||||
#define atolW(s) _wtol((s))
|
||||
#define strlwrW(s) _wcslwr((s))
|
||||
#define struprW(s) _wcsupr((s))
|
||||
#define sprintfW swprintf
|
||||
#define vsprintfW vswprintf
|
||||
#define snprintfW _snwprintf
|
||||
|
|
|
@ -563,6 +563,103 @@ HidParser_UsesReportId(
|
|||
|
||||
}
|
||||
|
||||
HIDPARSER_STATUS
|
||||
HidParser_GetUsageValueWithReport(
|
||||
IN PHID_PARSER Parser,
|
||||
IN PVOID CollectionContext,
|
||||
IN UCHAR ReportType,
|
||||
IN USAGE UsagePage,
|
||||
IN USAGE Usage,
|
||||
OUT PULONG UsageValue,
|
||||
IN PCHAR ReportDescriptor,
|
||||
IN ULONG ReportDescriptorLength)
|
||||
{
|
||||
ULONG Index;
|
||||
PHID_REPORT Report;
|
||||
USHORT CurrentUsagePage;
|
||||
PHID_REPORT_ITEM ReportItem;
|
||||
ULONG Data;
|
||||
|
||||
//
|
||||
// get report
|
||||
//
|
||||
Report = HidParser_GetReportInCollection(CollectionContext, ReportType);
|
||||
if (!Report)
|
||||
{
|
||||
//
|
||||
// no such report
|
||||
//
|
||||
return HIDPARSER_STATUS_REPORT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (Report->ReportSize / 8 != (ReportDescriptorLength - 1))
|
||||
{
|
||||
//
|
||||
// invalid report descriptor length
|
||||
//
|
||||
return HIDPARSER_STATUS_INVALID_REPORT_LENGTH;
|
||||
}
|
||||
|
||||
for(Index = 0; Index < Report->ItemCount; Index++)
|
||||
{
|
||||
//
|
||||
// get report item
|
||||
//
|
||||
ReportItem = &Report->Items[Index];
|
||||
|
||||
//
|
||||
// check usage page
|
||||
//
|
||||
CurrentUsagePage = (ReportItem->UsageMinimum >> 16);
|
||||
|
||||
//
|
||||
// does usage page match
|
||||
//
|
||||
if (UsagePage != CurrentUsagePage)
|
||||
continue;
|
||||
|
||||
//
|
||||
// does the usage match
|
||||
//
|
||||
if (Usage != (ReportItem->UsageMinimum & 0xFFFF))
|
||||
continue;
|
||||
|
||||
//
|
||||
// check if the specified usage is activated
|
||||
//
|
||||
ASSERT(ReportItem->ByteOffset < ReportDescriptorLength);
|
||||
|
||||
//
|
||||
// one extra shift for skipping the prepended report id
|
||||
//
|
||||
Data = 0;
|
||||
Parser->Copy(&Data, &ReportDescriptor[ReportItem->ByteOffset +1], min(sizeof(ULONG), ReportDescriptorLength - (ReportItem->ByteOffset + 1)));
|
||||
//Data = ReportDescriptor[ReportItem->ByteOffset + 1];
|
||||
|
||||
//
|
||||
// shift data
|
||||
//
|
||||
Data >>= ReportItem->Shift;
|
||||
|
||||
//
|
||||
// clear unwanted bits
|
||||
//
|
||||
Data &= ReportItem->Mask;
|
||||
|
||||
//
|
||||
// store result
|
||||
//
|
||||
*UsageValue = Data;
|
||||
return HIDPARSER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// usage not found
|
||||
//
|
||||
return HIDPARSER_STATUS_USAGE_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
|
||||
HIDPARSER_STATUS
|
||||
HidParser_GetScaledUsageValueWithReport(
|
||||
|
@ -652,11 +749,18 @@ HidParser_GetScaledUsageValueWithReport(
|
|||
//
|
||||
// logical boundaries are signed values
|
||||
//
|
||||
|
||||
// FIXME: scale with physical min/max
|
||||
if ((Data & ~(ReportItem->Mask >> 1)) != 0)
|
||||
{
|
||||
Data |= ~ReportItem->Mask;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// HACK: logical boundaries are absolute values
|
||||
return HIDPARSER_STATUS_BAD_LOG_PHY_VALUES;
|
||||
}
|
||||
|
||||
//
|
||||
// store result
|
||||
|
|
|
@ -34,6 +34,8 @@ TranslateHidParserStatus(
|
|||
return HIDP_STATUS_I8042_TRANS_UNKNOWN;
|
||||
case HIDPARSER_STATUS_COLLECTION_NOT_FOUND:
|
||||
return HIDP_STATUS_NOT_IMPLEMENTED; //FIXME
|
||||
case HIDPARSER_STATUS_BAD_LOG_PHY_VALUES:
|
||||
return HIDP_STATUS_BAD_LOG_PHY_VALUES;
|
||||
}
|
||||
DPRINT1("TranslateHidParserStatus Status %ld not implemented\n", Status);
|
||||
return HIDP_STATUS_NOT_IMPLEMENTED;
|
||||
|
@ -952,9 +954,54 @@ HidParser_GetUsageValue(
|
|||
IN PCHAR Report,
|
||||
IN ULONG ReportLength)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
HIDPARSER_STATUS ParserStatus;
|
||||
|
||||
//
|
||||
// FIXME: implement searching in specific collection
|
||||
//
|
||||
ASSERT(LinkCollection == HIDP_LINK_COLLECTION_UNSPECIFIED);
|
||||
|
||||
if (ReportType == HidP_Input)
|
||||
{
|
||||
//
|
||||
// input report
|
||||
//
|
||||
ParserStatus = HidParser_GetUsageValueWithReport(Parser, CollectionContext, HID_REPORT_TYPE_INPUT, UsagePage, Usage, UsageValue, Report, ReportLength);
|
||||
}
|
||||
else if (ReportType == HidP_Output)
|
||||
{
|
||||
//
|
||||
// input report
|
||||
//
|
||||
ParserStatus = HidParser_GetUsageValueWithReport(Parser, CollectionContext, HID_REPORT_TYPE_OUTPUT, UsagePage, Usage, UsageValue, Report, ReportLength);
|
||||
}
|
||||
else if (ReportType == HidP_Feature)
|
||||
{
|
||||
//
|
||||
// input report
|
||||
//
|
||||
ParserStatus = HidParser_GetUsageValueWithReport(Parser, CollectionContext, HID_REPORT_TYPE_FEATURE, UsagePage, Usage, UsageValue, Report, ReportLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// invalid report type
|
||||
//
|
||||
return HIDP_STATUS_INVALID_REPORT_TYPE;
|
||||
}
|
||||
|
||||
if (ParserStatus == HIDPARSER_STATUS_SUCCESS)
|
||||
{
|
||||
//
|
||||
// success
|
||||
//
|
||||
return HIDP_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// translate error
|
||||
//
|
||||
return TranslateHidParserStatus(ParserStatus);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -48,7 +48,8 @@ typedef enum
|
|||
HIDPARSER_STATUS_INVALID_REPORT_TYPE = -6,
|
||||
HIDPARSER_STATUS_BUFFER_TOO_SMALL = -7,
|
||||
HIDPARSER_STATUS_USAGE_NOT_FOUND = -8,
|
||||
HIDPARSER_STATUS_I8042_TRANS_UNKNOWN = -9
|
||||
HIDPARSER_STATUS_I8042_TRANS_UNKNOWN = -9,
|
||||
HIDPARSER_STATUS_BAD_LOG_PHY_VALUES = -10
|
||||
}HIDPARSER_STATUS_CODES;
|
||||
|
||||
typedef struct
|
||||
|
@ -200,6 +201,7 @@ HidParser_GetLinkCollectionNodes(
|
|||
OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
|
||||
IN OUT PULONG LinkCollectionNodesLength);
|
||||
|
||||
|
||||
HIDAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
|
|
@ -327,6 +327,17 @@ HidParser_GetScaledUsageValueWithReport(
|
|||
IN PCHAR ReportDescriptor,
|
||||
IN ULONG ReportDescriptorLength);
|
||||
|
||||
HIDPARSER_STATUS
|
||||
HidParser_GetUsageValueWithReport(
|
||||
IN PHID_PARSER Parser,
|
||||
IN PVOID CollectionContext,
|
||||
IN UCHAR ReportType,
|
||||
IN USAGE UsagePage,
|
||||
IN USAGE Usage,
|
||||
OUT PULONG UsageValue,
|
||||
IN PCHAR ReportDescriptor,
|
||||
IN ULONG ReportDescriptorLength);
|
||||
|
||||
/* parser.c */
|
||||
|
||||
HIDPARSER_STATUS
|
||||
|
|
|
@ -285,6 +285,11 @@ PoVolumeDevice(
|
|||
IN PDEVICE_OBJECT DeviceObject
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PoRemoveVolumeDevice(
|
||||
IN PDEVICE_OBJECT DeviceObject);
|
||||
|
||||
//
|
||||
// Power State routines
|
||||
//
|
||||
|
|
|
@ -1035,6 +1035,9 @@ IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
|
|||
/* Set the pending delete flag */
|
||||
IoGetDevObjExtension(DeviceObject)->ExtensionFlags |= DOE_DELETE_PENDING;
|
||||
|
||||
/* Unlink with the power manager */
|
||||
if (DeviceObject->Vpb) PoRemoveVolumeDevice(DeviceObject);
|
||||
|
||||
/* Check if the device object can be unloaded */
|
||||
if (!DeviceObject->ReferenceCount) IopUnloadDevice(DeviceObject);
|
||||
}
|
||||
|
|
|
@ -98,6 +98,51 @@ PoVolumeDevice(IN PDEVICE_OBJECT DeviceObject)
|
|||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PoRemoveVolumeDevice(IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PDEVICE_OBJECT_POWER_EXTENSION Dope;
|
||||
PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
|
||||
KIRQL OldIrql;
|
||||
PAGED_CODE();
|
||||
|
||||
/* If the device already has the dope, return it */
|
||||
DeviceExtension = IoGetDevObjExtension(DeviceObject);
|
||||
if (!DeviceExtension->Dope)
|
||||
{
|
||||
/* no dope */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make sure we can flush safely */
|
||||
KeAcquireGuardedMutex(&PopVolumeLock);
|
||||
|
||||
/* Get dope from device */
|
||||
Dope = (PDEVICE_OBJECT_POWER_EXTENSION)DeviceExtension->Dope;
|
||||
|
||||
if (Dope->Volume.Flink)
|
||||
{
|
||||
/* Remove from volume from list */
|
||||
RemoveEntryList(&Dope->Volume);
|
||||
}
|
||||
|
||||
/* Allow flushes to go through */
|
||||
KeReleaseGuardedMutex(&PopVolumeLock);
|
||||
|
||||
/* Now remove dope from device object */
|
||||
KeAcquireSpinLock(&PopDopeGlobalLock, &OldIrql);
|
||||
|
||||
/* remove from dev obj */
|
||||
DeviceExtension->Dope = NULL;
|
||||
|
||||
/* Release lock */
|
||||
KeReleaseSpinLock(&PopDopeGlobalLock, OldIrql);
|
||||
|
||||
/* Free dope */
|
||||
ExFreePoolWithTag(Dope, 'Dope');
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PopFlushVolumeWorker(IN PVOID Context)
|
||||
|
|
|
@ -50,11 +50,15 @@ InitBrushImpl(VOID)
|
|||
|
||||
VOID
|
||||
NTAPI
|
||||
EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
|
||||
EBRUSHOBJ_vInit(EBRUSHOBJ *pebo,
|
||||
PBRUSH pbrush,
|
||||
PSURFACE psurf,
|
||||
COLORREF crBackgroundClr,
|
||||
COLORREF crForegroundClr,
|
||||
PPALETTE ppalDC)
|
||||
{
|
||||
ASSERT(pebo);
|
||||
ASSERT(pbrush);
|
||||
ASSERT(pdc);
|
||||
|
||||
pebo->BrushObject.flColorType = 0;
|
||||
pebo->BrushObject.pvRbrush = NULL;
|
||||
|
@ -63,20 +67,24 @@ EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
|
|||
pebo->flattrs = pbrush->flAttrs;
|
||||
|
||||
/* Initialize 1 bpp fore and back colors */
|
||||
pebo->crCurrentBack = pdc->pdcattr->crBackgroundClr;
|
||||
pebo->crCurrentText = pdc->pdcattr->crForegroundClr;
|
||||
pebo->crCurrentBack = crBackgroundClr;
|
||||
pebo->crCurrentText = crForegroundClr;
|
||||
|
||||
pebo->psurfTrg = pdc->dclevel.pSurface;
|
||||
pebo->psurfTrg = psurf;
|
||||
/* We are initializing for a new memory DC */
|
||||
if(!pebo->psurfTrg)
|
||||
pebo->psurfTrg = psurfDefaultBitmap;
|
||||
ASSERT(pebo->psurfTrg);
|
||||
ASSERT(pebo->psurfTrg->ppal);
|
||||
|
||||
/* Initialize palettes */
|
||||
pebo->ppalSurf = pebo->psurfTrg->ppal;
|
||||
GDIOBJ_vReferenceObjectByPointer(&pebo->ppalSurf->BaseObject);
|
||||
pebo->ppalDC = pdc->dclevel.ppal;
|
||||
pebo->ppalDC = ppalDC;
|
||||
if(!pebo->ppalDC)
|
||||
pebo->ppalDC = gppalDefault;
|
||||
GDIOBJ_vReferenceObjectByPointer(&pebo->ppalDC->BaseObject);
|
||||
pebo->ppalDIB = NULL;
|
||||
|
||||
if (pbrush->flAttrs & BR_IS_NULL)
|
||||
{
|
||||
|
@ -99,6 +107,16 @@ EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
|
|||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
EBRUSHOBJ_vInitFromDC(EBRUSHOBJ *pebo,
|
||||
PBRUSH pbrush, PDC pdc)
|
||||
{
|
||||
EBRUSHOBJ_vInit(pebo, pbrush, pdc->dclevel.pSurface,
|
||||
pdc->pdcattr->crBackgroundClr, pdc->pdcattr->crForegroundClr,
|
||||
pdc->dclevel.ppal);
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
EBRUSHOBJ_vSetSolidRGBColor(EBRUSHOBJ *pebo, COLORREF crColor)
|
||||
|
@ -157,13 +175,15 @@ EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo)
|
|||
|
||||
VOID
|
||||
NTAPI
|
||||
EBRUSHOBJ_vUpdate(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
|
||||
EBRUSHOBJ_vUpdateFromDC(EBRUSHOBJ *pebo,
|
||||
PBRUSH pbrush,
|
||||
PDC pdc)
|
||||
{
|
||||
/* Cleanup the brush */
|
||||
EBRUSHOBJ_vCleanup(pebo);
|
||||
|
||||
/* Reinitialize */
|
||||
EBRUSHOBJ_vInit(pebo, pbrush, pdc);
|
||||
EBRUSHOBJ_vInitFromDC(pebo, pbrush, pdc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -600,6 +600,21 @@ EXLATEOBJ_vInitXlateFromDCs(
|
|||
pexlo->ppalDstDc = pdcDst->dclevel.ppal;
|
||||
}
|
||||
|
||||
VOID NTAPI EXLATEOBJ_vInitSrcMonoXlate(
|
||||
PEXLATEOBJ pexlo,
|
||||
PPALETTE ppalDst,
|
||||
COLORREF crBackgroundClr,
|
||||
COLORREF crForegroundClr)
|
||||
{
|
||||
/* Normal initialisation, with mono palette as source */
|
||||
EXLATEOBJ_vInitialize(pexlo,
|
||||
gppalMono,
|
||||
ppalDst,
|
||||
0,
|
||||
crBackgroundClr,
|
||||
crForegroundClr);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
EXLATEOBJ_vCleanup(PEXLATEOBJ pexlo)
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
*/
|
||||
|
||||
#include <win32k.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
DBG_DEFAULT_CHANNEL(GdiBlt);
|
||||
|
||||
#define ROP_USES_SOURCE(Rop) (((((Rop) & 0xCC0000) >> 2) != ((Rop) & 0x330000)) || ((((Rop) & 0xCC000000) >> 2) != ((Rop) & 0x33000000)))
|
||||
#define ROP_USES_MASK(Rop) (((Rop) & 0xFF000000) != (((Rop) & 0xff0000) << 8))
|
||||
|
@ -49,12 +47,12 @@ NtGdiAlphaBlend(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
DPRINT("Locking DCs\n");
|
||||
TRACE("Locking DCs\n");
|
||||
ahDC[0] = hDCDest;
|
||||
ahDC[1] = hDCSrc ;
|
||||
if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ*)ahDC, apObj, GDIObjType_DC_TYPE))
|
||||
{
|
||||
DPRINT1("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hDCDest, hDCSrc);
|
||||
WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hDCDest, hDCSrc);
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -102,7 +100,7 @@ NtGdiAlphaBlend(
|
|||
}
|
||||
|
||||
/* Prepare DCs for blit */
|
||||
DPRINT("Preparing DCs for blit\n");
|
||||
TRACE("Preparing DCs for blit\n");
|
||||
DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
|
||||
|
||||
/* Determine surfaces to be used in the bitblt */
|
||||
|
@ -124,7 +122,7 @@ NtGdiAlphaBlend(
|
|||
EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
|
||||
|
||||
/* Perform the alpha blend operation */
|
||||
DPRINT("Performing the alpha blend\n");
|
||||
TRACE("Performing the alpha blend\n");
|
||||
bResult = IntEngAlphaBlend(&BitmapDest->SurfObj,
|
||||
&BitmapSrc->SurfObj,
|
||||
DCDest->rosdc.CombinedClip,
|
||||
|
@ -135,7 +133,7 @@ NtGdiAlphaBlend(
|
|||
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
leave :
|
||||
DPRINT("Finishing blit\n");
|
||||
TRACE("Finishing blit\n");
|
||||
DC_vFinishBlit(DCDest, DCSrc);
|
||||
GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
|
||||
GDIOBJ_vUnlockObject(&DCDest->BaseObject);
|
||||
|
@ -197,12 +195,12 @@ NtGdiTransparentBlt(
|
|||
BOOL Ret = FALSE;
|
||||
EXLATEOBJ exlo;
|
||||
|
||||
DPRINT("Locking DCs\n");
|
||||
TRACE("Locking DCs\n");
|
||||
ahDC[0] = hdcDst;
|
||||
ahDC[1] = hdcSrc ;
|
||||
if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ*)ahDC, apObj, GDIObjType_DC_TYPE))
|
||||
{
|
||||
DPRINT1("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hdcDst, hdcSrc);
|
||||
WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hdcDst, hdcSrc);
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -343,7 +341,7 @@ NtGdiMaskBlt(
|
|||
}
|
||||
else if(psurfMask)
|
||||
{
|
||||
DPRINT1("Getting Mask bitmap without needing it?\n");
|
||||
WARN("Getting Mask bitmap without needing it?\n");
|
||||
SURFACE_ShareUnlockSurface(psurfMask);
|
||||
psurfMask = NULL;
|
||||
}
|
||||
|
@ -351,12 +349,12 @@ NtGdiMaskBlt(
|
|||
MaskPoint.y = yMask;
|
||||
|
||||
/* Take care of source and destination bitmap */
|
||||
DPRINT("Locking DCs\n");
|
||||
TRACE("Locking DCs\n");
|
||||
ahDC[0] = hdcDest;
|
||||
ahDC[1] = UsesSource ? hdcSrc : NULL;
|
||||
if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ*)ahDC, apObj, GDIObjType_DC_TYPE))
|
||||
{
|
||||
DPRINT1("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hdcDest, hdcSrc);
|
||||
WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hdcDest, hdcSrc);
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -367,7 +365,7 @@ NtGdiMaskBlt(
|
|||
if (NULL == DCDest)
|
||||
{
|
||||
if(DCSrc) DC_UnlockDc(DCSrc);
|
||||
DPRINT("Invalid destination dc handle (0x%p) passed to NtGdiBitBlt\n", hdcDest);
|
||||
WARN("Invalid destination dc handle (0x%p) passed to NtGdiBitBlt\n", hdcDest);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -497,7 +495,7 @@ NtGdiPlgBlt(
|
|||
IN INT yMask,
|
||||
IN DWORD crBackColor)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
FIXME("NtGdiPlgBlt: unimplemented.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -558,7 +556,7 @@ GreStretchBltMask(
|
|||
ahDC[2] = UsesMask ? hDCMask : NULL;
|
||||
if (!GDIOBJ_bLockMultipleObjects(3, (HGDIOBJ*)ahDC, apObj, GDIObjType_DC_TYPE))
|
||||
{
|
||||
DPRINT1("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hDCDest, hDCSrc);
|
||||
WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to GreStretchBltMask\n", hDCDest, hDCSrc);
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -651,7 +649,7 @@ GreStretchBltMask(
|
|||
(BitmapMask->SurfObj.sizlBitmap.cx < WidthSrc ||
|
||||
BitmapMask->SurfObj.sizlBitmap.cy < HeightSrc))
|
||||
{
|
||||
DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n",
|
||||
WARN("%dx%d mask is smaller than %dx%d bitmap\n",
|
||||
BitmapMask->SurfObj.sizlBitmap.cx, BitmapMask->SurfObj.sizlBitmap.cy,
|
||||
WidthSrc, HeightSrc);
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
|
@ -853,7 +851,7 @@ IntGdiPolyPatBlt(
|
|||
if (pbrush != NULL)
|
||||
{
|
||||
/* Initialize a brush object */
|
||||
EBRUSHOBJ_vInit(&eboFill, pbrush, pdc);
|
||||
EBRUSHOBJ_vInitFromDC(&eboFill, pbrush, pdc);
|
||||
|
||||
IntPatBlt(
|
||||
pdc,
|
||||
|
|
|
@ -98,6 +98,8 @@ BOOL NTAPI BRUSH_Cleanup(PVOID ObjectBody);
|
|||
|
||||
extern HSURF gahsurfHatch[HS_DDI_MAX];
|
||||
|
||||
struct _SURFACE;
|
||||
struct _PALETTE;
|
||||
struct _DC;
|
||||
|
||||
INIT_FUNCTION
|
||||
|
@ -107,7 +109,11 @@ InitBrushImpl(VOID);
|
|||
|
||||
VOID
|
||||
NTAPI
|
||||
EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, struct _DC *);
|
||||
EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, struct _SURFACE *, COLORREF, COLORREF, struct _PALETTE *);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
EBRUSHOBJ_vInitFromDC(EBRUSHOBJ *pebo, PBRUSH pbrush, struct _DC *);
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
|
@ -115,7 +121,7 @@ EBRUSHOBJ_vSetSolidRGBColor(EBRUSHOBJ *pebo, COLORREF crColor);
|
|||
|
||||
VOID
|
||||
NTAPI
|
||||
EBRUSHOBJ_vUpdate(EBRUSHOBJ *pebo, PBRUSH pbrush, struct _DC *pdc);
|
||||
EBRUSHOBJ_vUpdateFromDC(EBRUSHOBJ *pebo, PBRUSH pbrush, struct _DC *);
|
||||
|
||||
BOOL
|
||||
NTAPI
|
||||
|
|
|
@ -270,10 +270,10 @@ DC_vInitDc(
|
|||
pdc->dcattr.ptlBrushOrigin = pdc->dclevel.ptlBrushOrigin;
|
||||
|
||||
/* Initialize EBRUSHOBJs */
|
||||
EBRUSHOBJ_vInit(&pdc->eboFill, pdc->dclevel.pbrFill, pdc);
|
||||
EBRUSHOBJ_vInit(&pdc->eboLine, pdc->dclevel.pbrLine, pdc);
|
||||
EBRUSHOBJ_vInit(&pdc->eboText, pbrDefaultBrush, pdc);
|
||||
EBRUSHOBJ_vInit(&pdc->eboBackground, pbrDefaultBrush, pdc);
|
||||
EBRUSHOBJ_vInitFromDC(&pdc->eboFill, pdc->dclevel.pbrFill, pdc);
|
||||
EBRUSHOBJ_vInitFromDC(&pdc->eboLine, pdc->dclevel.pbrLine, pdc);
|
||||
EBRUSHOBJ_vInitFromDC(&pdc->eboText, pbrDefaultBrush, pdc);
|
||||
EBRUSHOBJ_vInitFromDC(&pdc->eboBackground, pbrDefaultBrush, pdc);
|
||||
|
||||
/* Setup fill data */
|
||||
pdc->dcattr.jROP2 = R2_COPYPEN;
|
||||
|
|
|
@ -43,7 +43,7 @@ DC_vUpdateFillBrush(PDC pdc)
|
|||
if (pdcattr->ulDirty_ & DIRTY_FILL)
|
||||
{
|
||||
/* Update eboFill */
|
||||
EBRUSHOBJ_vUpdate(&pdc->eboFill, pdc->dclevel.pbrFill, pdc);
|
||||
EBRUSHOBJ_vUpdateFromDC(&pdc->eboFill, pdc->dclevel.pbrFill, pdc);
|
||||
}
|
||||
|
||||
/* Check for DC brush */
|
||||
|
@ -90,7 +90,7 @@ DC_vUpdateLineBrush(PDC pdc)
|
|||
if (pdcattr->ulDirty_ & DIRTY_LINE)
|
||||
{
|
||||
/* Update eboLine */
|
||||
EBRUSHOBJ_vUpdate(&pdc->eboLine, pdc->dclevel.pbrLine, pdc);
|
||||
EBRUSHOBJ_vUpdateFromDC(&pdc->eboLine, pdc->dclevel.pbrLine, pdc);
|
||||
}
|
||||
|
||||
/* Check for DC pen */
|
||||
|
@ -113,7 +113,7 @@ DC_vUpdateTextBrush(PDC pdc)
|
|||
/* Timo : The text brush should never be changed.
|
||||
* Jérôme : Yeah, but its palette must be updated anyway! */
|
||||
if(pdcattr->ulDirty_ & DIRTY_TEXT)
|
||||
EBRUSHOBJ_vUpdate(&pdc->eboText, pbrDefaultBrush, pdc);
|
||||
EBRUSHOBJ_vUpdateFromDC(&pdc->eboText, pbrDefaultBrush, pdc);
|
||||
|
||||
/* Update the eboText's solid color */
|
||||
EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboText, pdcattr->crForegroundClr);
|
||||
|
@ -129,7 +129,7 @@ DC_vUpdateBackgroundBrush(PDC pdc)
|
|||
PDC_ATTR pdcattr = pdc->pdcattr;
|
||||
|
||||
if(pdcattr->ulDirty_ & DIRTY_BACKGROUND)
|
||||
EBRUSHOBJ_vUpdate(&pdc->eboBackground, pbrDefaultBrush, pdc);
|
||||
EBRUSHOBJ_vUpdateFromDC(&pdc->eboBackground, pbrDefaultBrush, pdc);
|
||||
|
||||
/* Update the eboBackground's solid color */
|
||||
EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboBackground, pdcattr->crBackgroundClr);
|
||||
|
|
|
@ -1042,7 +1042,14 @@ CLEANUP:
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Mostly inspired from wine code */
|
||||
/* Mostly inspired from wine code.
|
||||
* We use low level functions because:
|
||||
* - at this point, the icon bitmap could have a different bit depth than the DC,
|
||||
* making it thus impossible to use NtCreateCompatibleDC and selecting the bitmap.
|
||||
* This happens after a mode setting change.
|
||||
* - it avoids massive GDI objects locking when only the destination surface needs it.
|
||||
* - It makes (small) performance gains.
|
||||
*/
|
||||
BOOL
|
||||
UserDrawIconEx(
|
||||
HDC hDc,
|
||||
|
@ -1055,18 +1062,21 @@ UserDrawIconEx(
|
|||
HBRUSH hbrFlickerFreeDraw,
|
||||
UINT diFlags)
|
||||
{
|
||||
PSURFACE psurfDest, psurfMask, psurfColor, psurfOffScreen;
|
||||
PDC pdc = NULL;
|
||||
BOOL Ret = FALSE;
|
||||
HBITMAP hbmMask, hbmColor;
|
||||
BITMAP bmpColor, bm;
|
||||
BOOL DoFlickerFree;
|
||||
INT iOldBkColor = 0, iOldTxtColor = 0;
|
||||
BOOL bOffScreen, bAlpha = FALSE;
|
||||
RECTL rcDest, rcSrc;
|
||||
CLIPOBJ* pdcClipObj = NULL;
|
||||
EXLATEOBJ exlo;
|
||||
|
||||
HDC hMemDC, hDestDC = hDc;
|
||||
HGDIOBJ hOldOffBrush = 0;
|
||||
HGDIOBJ hOldOffBmp = 0;
|
||||
HBITMAP hTmpBmp = 0, hOffBmp = 0;
|
||||
BOOL bAlpha = FALSE;
|
||||
INT x=xLeft, y=yTop;
|
||||
/* Stupid case */
|
||||
if((diFlags & DI_NORMAL) == 0)
|
||||
{
|
||||
ERR("DrawIconEx called without mask or color bitmap to draw.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hbmMask = pIcon->IconInfo.hbmMask;
|
||||
hbmColor = pIcon->IconInfo.hbmColor;
|
||||
|
@ -1074,44 +1084,50 @@ UserDrawIconEx(
|
|||
if (istepIfAniCur)
|
||||
ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
|
||||
|
||||
if (!hbmMask || !GreGetObject(hbmMask, sizeof(BITMAP), (PVOID)&bm))
|
||||
/*
|
||||
* Get our objects.
|
||||
* Shared locks are enough, we are only reading those bitmaps
|
||||
*/
|
||||
psurfMask = SURFACE_ShareLockSurface(hbmMask);
|
||||
if(psurfMask == NULL)
|
||||
{
|
||||
ERR("Unable to lock the mask surface.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (hbmColor && !GreGetObject(hbmColor, sizeof(BITMAP), (PVOID)&bmpColor))
|
||||
/* Color bitmap is not mandatory */
|
||||
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);
|
||||
psurfColor = NULL;
|
||||
}
|
||||
else if ((psurfColor = SURFACE_ShareLockSurface(hbmColor)) == NULL)
|
||||
{
|
||||
ERR("Unable to lock the color bitmap.\n");
|
||||
SURFACE_ShareUnlockSurface(psurfMask);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(!(hMemDC = NtGdiCreateCompatibleDC(hDc)))
|
||||
{
|
||||
ERR("NtGdiCreateCompatibleDC failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
/* Set source rect */
|
||||
RECTL_vSetRect(&rcSrc, 0, 0, pIcon->Size.cx, pIcon->Size.cy);
|
||||
|
||||
/* Check for alpha */
|
||||
if (hbmColor
|
||||
&& (bmpColor.bmBitsPixel == 32)
|
||||
&& (diFlags & DI_IMAGE))
|
||||
if (psurfColor &&
|
||||
(psurfColor->SurfObj.iBitmapFormat == BMF_32BPP) &&
|
||||
(diFlags & DI_IMAGE))
|
||||
{
|
||||
SURFACE *psurfOff = NULL;
|
||||
PFN_DIB_GetPixel fnSource_GetPixel = NULL;
|
||||
INT i, j;
|
||||
|
||||
/* In order to correctly display 32 bit icons Windows first scans the image,
|
||||
because information about transparency is not stored in any image's headers */
|
||||
psurfOff = SURFACE_ShareLockSurface(hbmColor);
|
||||
if (psurfOff)
|
||||
fnSource_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel;
|
||||
for (i = 0; i < psurfColor->SurfObj.sizlBitmap.cx; i++)
|
||||
{
|
||||
fnSource_GetPixel = DibFunctionsForBitmapFormat[psurfOff->SurfObj.iBitmapFormat].DIB_GetPixel;
|
||||
if (fnSource_GetPixel)
|
||||
for (j = 0; j < psurfColor->SurfObj.sizlBitmap.cy; j++)
|
||||
{
|
||||
for (i = 0; i < psurfOff->SurfObj.sizlBitmap.cx; i++)
|
||||
{
|
||||
for (j = 0; j < psurfOff->SurfObj.sizlBitmap.cy; j++)
|
||||
{
|
||||
bAlpha = ((BYTE)(fnSource_GetPixel(&psurfOff->SurfObj, i, j) >> 24) & 0xff);
|
||||
bAlpha = ((BYTE)(fnSource_GetPixel(&psurfColor->SurfObj, i, j) >> 24) & 0xff);
|
||||
if (bAlpha)
|
||||
break;
|
||||
}
|
||||
|
@ -1119,64 +1135,147 @@ UserDrawIconEx(
|
|||
break;
|
||||
}
|
||||
}
|
||||
SURFACE_ShareUnlockSurface(psurfOff);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fix width parameter, if needed */
|
||||
if (!cxWidth)
|
||||
cxWidth = ((diFlags & DI_DEFAULTSIZE) ?
|
||||
UserGetSystemMetrics(SM_CXICON) : pIcon->Size.cx);
|
||||
{
|
||||
if(diFlags & DI_DEFAULTSIZE)
|
||||
cxWidth = pIcon->IconInfo.fIcon ?
|
||||
UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR);
|
||||
else
|
||||
cxWidth = pIcon->Size.cx;
|
||||
}
|
||||
|
||||
/* Fix height parameter, if needed */
|
||||
if (!cyHeight)
|
||||
cyHeight = ((diFlags & DI_DEFAULTSIZE) ?
|
||||
UserGetSystemMetrics(SM_CYICON) : pIcon->Size.cy);
|
||||
|
||||
DoFlickerFree = (hbrFlickerFreeDraw &&
|
||||
(GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH));
|
||||
|
||||
if (DoFlickerFree)
|
||||
{
|
||||
hDestDC = NtGdiCreateCompatibleDC(hDc);
|
||||
if(!hDestDC)
|
||||
{
|
||||
ERR("NtGdiCreateCompatibleDC failed!\n");
|
||||
Ret = FALSE;
|
||||
goto Cleanup ;
|
||||
}
|
||||
hOffBmp = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight);
|
||||
if(!hOffBmp)
|
||||
{
|
||||
ERR("NtGdiCreateCompatibleBitmap failed!\n");
|
||||
goto Cleanup ;
|
||||
}
|
||||
hOldOffBmp = NtGdiSelectBitmap(hDestDC, hOffBmp);
|
||||
hOldOffBrush = NtGdiSelectBrush(hDestDC, hbrFlickerFreeDraw);
|
||||
NtGdiPatBlt(hDestDC, 0, 0, cxWidth, cyHeight, PATCOPY);
|
||||
NtGdiSelectBrush(hDestDC, hOldOffBrush);
|
||||
x=y=0;
|
||||
if(diFlags & DI_DEFAULTSIZE)
|
||||
cyHeight = pIcon->IconInfo.fIcon ?
|
||||
UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR);
|
||||
else
|
||||
cyHeight = pIcon->Size.cy;
|
||||
}
|
||||
|
||||
/* Set Background/foreground colors */
|
||||
iOldTxtColor = IntGdiSetTextColor(hDc, 0); // Black
|
||||
iOldBkColor = IntGdiSetBkColor(hDc, 0x00FFFFFF); // White
|
||||
/* Should we render off-screen? */
|
||||
bOffScreen = hbrFlickerFreeDraw && (GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH);
|
||||
|
||||
if (bOffScreen)
|
||||
{
|
||||
/* Yes: Allocate and paint the offscreen surface */
|
||||
EBRUSHOBJ eboFill;
|
||||
PBRUSH pbrush = BRUSH_ShareLockBrush(hbrFlickerFreeDraw);
|
||||
|
||||
TRACE("Performing off-screen rendering.\n");
|
||||
|
||||
if(!pbrush)
|
||||
{
|
||||
ERR("Failed to get brush object.\n");
|
||||
SURFACE_ShareUnlockSurface(psurfMask);
|
||||
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
psurfOffScreen = SURFACE_AllocSurface(STYPE_BITMAP,
|
||||
cxWidth, cyHeight, psurfColor->SurfObj.iBitmapFormat,
|
||||
0, 0, NULL);
|
||||
if(!psurfOffScreen)
|
||||
{
|
||||
ERR("Failed to allocate the off-screen surface.\n");
|
||||
SURFACE_ShareUnlockSurface(psurfMask);
|
||||
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
||||
BRUSH_ShareUnlockBrush(pbrush);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Paint the brush */
|
||||
EBRUSHOBJ_vInit(&eboFill, pbrush, psurfOffScreen, 0x00FFFFFF, 0, NULL);
|
||||
RECTL_vSetRect(&rcDest, 0, 0, cxWidth, cyHeight);
|
||||
|
||||
Ret = IntEngBitBlt(&psurfOffScreen->SurfObj,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&rcDest,
|
||||
NULL,
|
||||
NULL,
|
||||
&eboFill.BrushObject,
|
||||
&pbrush->ptOrigin,
|
||||
ROP4_PATCOPY);
|
||||
|
||||
/* Clean up everything */
|
||||
EBRUSHOBJ_vCleanup(&eboFill);
|
||||
BRUSH_ShareUnlockBrush(pbrush);
|
||||
|
||||
if(!Ret)
|
||||
{
|
||||
ERR("Failed to paint the off-screen surface.\n");
|
||||
SURFACE_ShareUnlockSurface(psurfMask);
|
||||
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
||||
GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* We now have our destination surface */
|
||||
psurfDest = psurfOffScreen;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We directly draw to the DC */
|
||||
TRACE("Performing on screen rendering.\n");
|
||||
|
||||
psurfOffScreen = NULL;
|
||||
pdc = DC_LockDc(hDc);
|
||||
if(!pdc)
|
||||
{
|
||||
ERR("Could not lock the destination DC.\n");
|
||||
SURFACE_ShareUnlockSurface(psurfMask);
|
||||
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
||||
return FALSE;
|
||||
}
|
||||
/* Calculate destination rectangle */
|
||||
RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
|
||||
IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
|
||||
RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
|
||||
|
||||
/* Prepare the underlying surface */
|
||||
DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
|
||||
|
||||
/* Get the clip object */
|
||||
pdcClipObj = pdc->rosdc.CombinedClip;
|
||||
|
||||
/* We now have our destination surface and rectangle */
|
||||
psurfDest = pdc->dclevel.pSurface;
|
||||
|
||||
if(psurfDest == NULL)
|
||||
{
|
||||
/* Empty DC */
|
||||
DC_vFinishBlit(pdc, NULL);
|
||||
DC_UnlockDc(pdc);
|
||||
SURFACE_ShareUnlockSurface(psurfMask);
|
||||
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now do the rendering */
|
||||
if(bAlpha && (diFlags & DI_IMAGE))
|
||||
{
|
||||
BLENDFUNCTION pixelblend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
|
||||
BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } };
|
||||
BYTE Alpha;
|
||||
INT i, j;
|
||||
PSURFACE psurf;
|
||||
PSURFACE psurf = NULL;
|
||||
PBYTE ptr ;
|
||||
HBITMAP hMemBmp = NULL;
|
||||
HBITMAP hsurfCopy = NULL;
|
||||
|
||||
hMemBmp = BITMAP_CopyBitmap(hbmColor);
|
||||
if(!hMemBmp)
|
||||
hsurfCopy = BITMAP_CopyBitmap(hbmColor);
|
||||
if(!hsurfCopy)
|
||||
{
|
||||
ERR("BITMAP_CopyBitmap failed!");
|
||||
goto CleanupAlpha;
|
||||
}
|
||||
|
||||
psurf = SURFACE_ShareLockSurface(hMemBmp);
|
||||
psurf = SURFACE_ShareLockSurface(hsurfCopy);
|
||||
if(!psurf)
|
||||
{
|
||||
ERR("SURFACE_LockSurface failed!\n");
|
||||
|
@ -1198,109 +1297,181 @@ UserDrawIconEx(
|
|||
}
|
||||
}
|
||||
|
||||
SURFACE_ShareUnlockSurface(psurf);
|
||||
/* Initialize color translation object */
|
||||
EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0xFFFFFFFF, 0xFFFFFFFF, 0);
|
||||
|
||||
hTmpBmp = NtGdiSelectBitmap(hMemDC, hMemBmp);
|
||||
/* Now do it */
|
||||
Ret = IntEngAlphaBlend(&psurfDest->SurfObj,
|
||||
&psurf->SurfObj,
|
||||
pdcClipObj,
|
||||
&exlo.xlo,
|
||||
&rcDest,
|
||||
&rcSrc,
|
||||
&blendobj);
|
||||
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
|
||||
Ret = NtGdiAlphaBlend(hDestDC,
|
||||
x,
|
||||
y,
|
||||
cxWidth,
|
||||
cyHeight,
|
||||
hMemDC,
|
||||
0,
|
||||
0,
|
||||
pIcon->Size.cx,
|
||||
pIcon->Size.cy,
|
||||
pixelblend,
|
||||
NULL);
|
||||
NtGdiSelectBitmap(hMemDC, hTmpBmp);
|
||||
CleanupAlpha:
|
||||
if(hMemBmp) NtGdiDeleteObjectApp(hMemBmp);
|
||||
if(psurf) SURFACE_ShareUnlockSurface(psurf);
|
||||
if(hsurfCopy) NtGdiDeleteObjectApp(hsurfCopy);
|
||||
if(Ret) goto done;
|
||||
ERR("NtGdiAlphaBlend failed!\n");
|
||||
}
|
||||
|
||||
if (diFlags & DI_MASK)
|
||||
{
|
||||
DWORD rop = (diFlags & DI_IMAGE) ? SRCAND : SRCCOPY;
|
||||
hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmMask);
|
||||
NtGdiStretchBlt(hDestDC,
|
||||
x,
|
||||
y,
|
||||
cxWidth,
|
||||
cyHeight,
|
||||
hMemDC,
|
||||
0,
|
||||
0,
|
||||
pIcon->Size.cx,
|
||||
pIcon->Size.cy,
|
||||
rop,
|
||||
0);
|
||||
NtGdiSelectBitmap(hMemDC, hTmpBmp);
|
||||
DWORD rop4 = (diFlags & DI_IMAGE) ? ROP4_SRCAND : ROP4_SRCCOPY;
|
||||
|
||||
EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
|
||||
|
||||
Ret = IntEngStretchBlt(&psurfDest->SurfObj,
|
||||
&psurfMask->SurfObj,
|
||||
NULL,
|
||||
pdcClipObj,
|
||||
&exlo.xlo,
|
||||
NULL,
|
||||
&rcDest,
|
||||
&rcSrc,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
rop4);
|
||||
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
|
||||
if(!Ret)
|
||||
{
|
||||
ERR("Failed to mask the bitmap data.\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if(diFlags & DI_IMAGE)
|
||||
{
|
||||
if (hbmColor)
|
||||
if (psurfColor)
|
||||
{
|
||||
DWORD rop = (diFlags & DI_MASK) ? SRCINVERT : SRCCOPY ;
|
||||
hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmColor);
|
||||
NtGdiStretchBlt(hDestDC,
|
||||
x,
|
||||
y,
|
||||
cxWidth,
|
||||
cyHeight,
|
||||
hMemDC,
|
||||
0,
|
||||
0,
|
||||
pIcon->Size.cx,
|
||||
pIcon->Size.cy,
|
||||
rop,
|
||||
0);
|
||||
NtGdiSelectBitmap(hMemDC, hTmpBmp);
|
||||
DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY ;
|
||||
|
||||
EXLATEOBJ_vInitialize(&exlo, psurfColor->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
|
||||
|
||||
Ret = IntEngStretchBlt(&psurfDest->SurfObj,
|
||||
&psurfColor->SurfObj,
|
||||
NULL,
|
||||
pdcClipObj,
|
||||
&exlo.xlo,
|
||||
NULL,
|
||||
&rcDest,
|
||||
&rcSrc,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
rop4);
|
||||
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
|
||||
if(!Ret)
|
||||
{
|
||||
ERR("Failed to render the icon bitmap.\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Mask bitmap holds the information in its second half */
|
||||
DWORD rop = (diFlags & DI_MASK) ? SRCINVERT : SRCCOPY ;
|
||||
hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmMask);
|
||||
NtGdiStretchBlt(hDestDC,
|
||||
x,
|
||||
y,
|
||||
cxWidth,
|
||||
cyHeight,
|
||||
hMemDC,
|
||||
0,
|
||||
pIcon->Size.cy,
|
||||
pIcon->Size.cx,
|
||||
pIcon->Size.cy,
|
||||
rop,
|
||||
0);
|
||||
NtGdiSelectBitmap(hMemDC, hTmpBmp);
|
||||
/* 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);
|
||||
|
||||
EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
|
||||
|
||||
Ret = IntEngStretchBlt(&psurfDest->SurfObj,
|
||||
&psurfMask->SurfObj,
|
||||
NULL,
|
||||
pdcClipObj,
|
||||
&exlo.xlo,
|
||||
NULL,
|
||||
&rcDest,
|
||||
&rcSrc,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
rop4);
|
||||
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
|
||||
if(!Ret)
|
||||
{
|
||||
ERR("Failed to render the icon bitmap.\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if(hDestDC != hDc)
|
||||
/* We're done. Was it a double buffered draw ? */
|
||||
if(bOffScreen)
|
||||
{
|
||||
NtGdiBitBlt(hDc, xLeft, yTop, cxWidth, cyHeight, hDestDC, 0, 0, SRCCOPY, 0, 0);
|
||||
/* Yes. Draw it back to our DC */
|
||||
POINTL ptSrc = {0, 0};
|
||||
pdc = DC_LockDc(hDc);
|
||||
if(!pdc)
|
||||
{
|
||||
ERR("Could not lock the destination DC.\n");
|
||||
return FALSE;
|
||||
}
|
||||
/* Calculate destination rectangle */
|
||||
RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
|
||||
IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
|
||||
RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
|
||||
|
||||
/* Prepare the underlying surface */
|
||||
DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
|
||||
|
||||
/* Get the clip object */
|
||||
pdcClipObj = pdc->rosdc.CombinedClip;
|
||||
|
||||
/* We now have our destination surface and rectangle */
|
||||
psurfDest = pdc->dclevel.pSurface;
|
||||
if(!psurfDest)
|
||||
{
|
||||
/* So, you did all of this for an empty DC. */
|
||||
DC_UnlockDc(pdc);
|
||||
goto Cleanup2;
|
||||
}
|
||||
|
||||
/* Restore foreground and background colors */
|
||||
IntGdiSetBkColor(hDc, iOldBkColor);
|
||||
IntGdiSetTextColor(hDc, iOldTxtColor);
|
||||
/* Color translation */
|
||||
EXLATEOBJ_vInitialize(&exlo, psurfOffScreen->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
|
||||
|
||||
Ret = TRUE ;
|
||||
/* Blt it! */
|
||||
Ret = IntEngBitBlt(&psurfDest->SurfObj,
|
||||
&psurfOffScreen->SurfObj,
|
||||
NULL,
|
||||
pdcClipObj,
|
||||
&exlo.xlo,
|
||||
&rcDest,
|
||||
&ptSrc,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ROP4_SRCCOPY);
|
||||
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
}
|
||||
Cleanup:
|
||||
NtGdiDeleteObjectApp(hMemDC);
|
||||
if(hDestDC != hDc)
|
||||
if(pdc)
|
||||
{
|
||||
if(hOldOffBmp) NtGdiSelectBitmap(hDestDC, hOldOffBmp);
|
||||
NtGdiDeleteObjectApp(hDestDC);
|
||||
if(hOffBmp) NtGdiDeleteObjectApp(hOffBmp);
|
||||
DC_vFinishBlit(pdc, NULL);
|
||||
DC_UnlockDc(pdc);
|
||||
}
|
||||
|
||||
Cleanup2:
|
||||
/* Delete off screen rendering surface */
|
||||
if(psurfOffScreen)
|
||||
GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
|
||||
|
||||
/* Unlock other surfaces */
|
||||
SURFACE_ShareUnlockSurface(psurfMask);
|
||||
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue