Synchronize with trunk's revision r57599.

svn path=/branches/ros-csrss/; revision=57600
This commit is contained in:
Hermès Bélusca-Maïto 2012-10-23 19:54:03 +00:00
commit aab393ca70
36 changed files with 1985 additions and 571 deletions

View file

@ -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","olesvr32",0x00000000,"olesvr32.dll"
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olethk32",0x00000000,"olethk32.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","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","shell32",0x00000000,"shell32.dll"
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","url",0x00000000,"url.dll" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","url",0x00000000,"url.dll"
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","urlmon",0x00000000,"urlmon.dll" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","urlmon",0x00000000,"urlmon.dll"

View file

@ -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","olesvr32",0x00000000,"olesvr32.dll"
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olethk32",0x00000000,"olethk32.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","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","shell32",0x00000000,"shell32.dll"
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","url",0x00000000,"url.dll" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","url",0x00000000,"url.dll"
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","urlmon",0x00000000,"urlmon.dll" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","urlmon",0x00000000,"urlmon.dll"

View file

@ -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","olesvr32",0x00000000,"olesvr32.dll"
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olethk32",0x00000000,"olethk32.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","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","shell32",0x00000000,"shell32.dll"
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","url",0x00000000,"url.dll" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","url",0x00000000,"url.dll"
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","urlmon",0x00000000,"urlmon.dll" HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","urlmon",0x00000000,"urlmon.dll"

View file

@ -13,11 +13,11 @@ spec2def(lsasrv.dll lsasrv.spec ADD_IMPORTLIB)
list(APPEND SOURCE list(APPEND SOURCE
authport.c authport.c
database.c database.c
lookup.c
lsarpc.c lsarpc.c
lsasrv.c lsasrv.c
policy.c policy.c
privileges.c privileges.c
sids.c
lsasrv.rc lsasrv.rc
${CMAKE_CURRENT_BINARY_DIR}/lsasrv_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/lsasrv_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/lsasrv.def ${CMAKE_CURRENT_BINARY_DIR}/lsasrv.def

View file

@ -1,7 +1,7 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: Local Security Authority (LSA) Server * 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 * PURPOSE: Sid / Name lookup functions
* *
* PROGRAMMERS: Eric Kohl * PROGRAMMERS: Eric Kohl
@ -72,8 +72,8 @@ typedef struct _WELL_KNOWN_SID
{ {
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
PSID Sid; PSID Sid;
UNICODE_STRING Name; UNICODE_STRING AccountName;
UNICODE_STRING Domain; UNICODE_STRING DomainName;
SID_NAME_USE Use; SID_NAME_USE Use;
} WELL_KNOWN_SID, *PWELL_KNOWN_SID; } WELL_KNOWN_SID, *PWELL_KNOWN_SID;
@ -202,8 +202,8 @@ BOOLEAN
LsapCreateSid(PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, LsapCreateSid(PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
UCHAR SubAuthorityCount, UCHAR SubAuthorityCount,
PULONG SubAuthorities, PULONG SubAuthorities,
PWSTR Name, PWSTR AccountName,
PWSTR Domain, PWSTR DomainName,
SID_NAME_USE Use) SID_NAME_USE Use)
{ {
PWELL_KNOWN_SID SidEntry; PWELL_KNOWN_SID SidEntry;
@ -235,11 +235,11 @@ LsapCreateSid(PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
*p = SubAuthorities[i]; *p = SubAuthorities[i];
} }
RtlInitUnicodeString(&SidEntry->Name, RtlInitUnicodeString(&SidEntry->AccountName,
Name); AccountName);
RtlInitUnicodeString(&SidEntry->Domain, RtlInitUnicodeString(&SidEntry->DomainName,
Domain); DomainName);
SidEntry->Use = Use; SidEntry->Use = Use;
@ -472,6 +472,13 @@ LsapInitSids(VOID)
L"NT AUTHORITY", L"NT AUTHORITY",
SidTypeWellKnownGroup); SidTypeWellKnownGroup);
LsapCreateSid(&NtAuthority,
1,
SubAuthorities,
L"LOCALSERVICE",
L"NT AUTHORITY",
SidTypeWellKnownGroup);
/* Network Service Sid */ /* Network Service Sid */
SubAuthorities[0] = SECURITY_NETWORK_SERVICE_RID; SubAuthorities[0] = SECURITY_NETWORK_SERVICE_RID;
LsapCreateSid(&NtAuthority, LsapCreateSid(&NtAuthority,
@ -481,6 +488,13 @@ LsapInitSids(VOID)
L"NT AUTHORITY", L"NT AUTHORITY",
SidTypeWellKnownGroup); SidTypeWellKnownGroup);
LsapCreateSid(&NtAuthority,
1,
SubAuthorities,
L"NETWORKSERVICE",
L"NT AUTHORITY",
SidTypeWellKnownGroup);
/* Builtin Domain Sid */ /* Builtin Domain Sid */
SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID; SubAuthorities[0] = SECURITY_BUILTIN_DOMAIN_RID;
LsapCreateSid(&NtAuthority, LsapCreateSid(&NtAuthority,
@ -653,7 +667,7 @@ LsapLookupWellKnownSid(PSID Sid)
PWELL_KNOWN_SID PWELL_KNOWN_SID
LsapLookupWellKnownName(PUNICODE_STRING Name) LsapLookupIsolatedWellKnownName(PUNICODE_STRING AccountName)
{ {
PLIST_ENTRY ListEntry; PLIST_ENTRY ListEntry;
PWELL_KNOWN_SID Ptr; PWELL_KNOWN_SID Ptr;
@ -664,7 +678,33 @@ LsapLookupWellKnownName(PUNICODE_STRING Name)
Ptr = CONTAINING_RECORD(ListEntry, Ptr = CONTAINING_RECORD(ListEntry,
WELL_KNOWN_SID, WELL_KNOWN_SID,
ListEntry); 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; 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 static
NTSTATUS NTSTATUS
LsapLookupIsolatedNames(DWORD Count, LsapLookupIsolatedNames(DWORD Count,
@ -1004,18 +1075,24 @@ LsapLookupIsolatedNames(DWORD Count,
TRACE("Mapping name: %wZ\n", &AccountNames[i]); TRACE("Mapping name: %wZ\n", &AccountNames[i]);
/* Look-up all well-known names */ /* Look-up all well-known names */
ptr = LsapLookupWellKnownName((PUNICODE_STRING)&AccountNames[i]); ptr = LsapLookupIsolatedWellKnownName((PUNICODE_STRING)&AccountNames[i]);
if (ptr != NULL) if (ptr != NULL)
{ {
SidsBuffer[i].Use = ptr->Use; 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].DomainIndex = -1;
SidsBuffer[i].Flags = 0; SidsBuffer[i].Flags = 0;
if (ptr->Use == SidTypeDomain) if (ptr->Use == SidTypeDomain)
{ {
Status = LsapAddDomainToDomainsList(DomainsBuffer, Status = LsapAddDomainToDomainsList(DomainsBuffer,
&ptr->Name, &ptr->AccountName,
ptr->Sid, ptr->Sid,
&DomainIndex); &DomainIndex);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -1025,11 +1102,11 @@ LsapLookupIsolatedNames(DWORD Count,
} }
else else
{ {
ptr2= LsapLookupWellKnownName(&ptr->Domain); ptr2= LsapLookupIsolatedWellKnownName(&ptr->DomainName);
if (ptr2 != NULL) if (ptr2 != NULL)
{ {
Status = LsapAddDomainToDomainsList(DomainsBuffer, Status = LsapAddDomainToDomainsList(DomainsBuffer,
&ptr2->Name, &ptr2->AccountName,
ptr2->Sid, ptr2->Sid,
&DomainIndex); &DomainIndex);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -1072,7 +1149,13 @@ LsapLookupIsolatedNames(DWORD Count,
if (RtlEqualUnicodeString((PUNICODE_STRING)&AccountNames[i], &BuiltinDomainName, TRUE)) if (RtlEqualUnicodeString((PUNICODE_STRING)&AccountNames[i], &BuiltinDomainName, TRUE))
{ {
SidsBuffer[i].Use = SidTypeDomain; 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].DomainIndex = -1;
SidsBuffer[i].Flags = 0; SidsBuffer[i].Flags = 0;
@ -1093,7 +1176,12 @@ LsapLookupIsolatedNames(DWORD Count,
if (RtlEqualUnicodeString((PUNICODE_STRING)&AccountNames[i], &AccountDomainName, TRUE)) if (RtlEqualUnicodeString((PUNICODE_STRING)&AccountNames[i], &AccountDomainName, TRUE))
{ {
SidsBuffer[i].Use = SidTypeDomain; 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].DomainIndex = -1;
SidsBuffer[i].Flags = 0; SidsBuffer[i].Flags = 0;
@ -1183,7 +1271,10 @@ LsapLookupIsolatedBuiltinNames(DWORD Count,
SidsBuffer[i].Sid = CreateSidFromSidAndRid(BuiltinDomainSid, SidsBuffer[i].Sid = CreateSidFromSidAndRid(BuiltinDomainSid,
RelativeIds.Element[0]); RelativeIds.Element[0]);
if (SidsBuffer[i].Sid == NULL) if (SidsBuffer[i].Sid == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done; goto done;
}
SidsBuffer[i].DomainIndex = -1; SidsBuffer[i].DomainIndex = -1;
SidsBuffer[i].Flags = 0; SidsBuffer[i].Flags = 0;
@ -1278,7 +1369,10 @@ LsapLookupIsolatedAccountNames(DWORD Count,
SidsBuffer[i].Sid = CreateSidFromSidAndRid(AccountDomainSid, SidsBuffer[i].Sid = CreateSidFromSidAndRid(AccountDomainSid,
RelativeIds.Element[0]); RelativeIds.Element[0]);
if (SidsBuffer[i].Sid == NULL) if (SidsBuffer[i].Sid == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done; goto done;
}
SidsBuffer[i].DomainIndex = -1; SidsBuffer[i].DomainIndex = -1;
SidsBuffer[i].Flags = 0; 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 static
NTSTATUS NTSTATUS
LsapLookupBuiltinNames(DWORD Count, LsapLookupBuiltinNames(DWORD Count,
@ -1359,6 +1561,8 @@ LsapLookupBuiltinNames(DWORD Count,
if (!RtlEqualUnicodeString((PUNICODE_STRING)&DomainNames[i], &BuiltinDomainName, TRUE)) if (!RtlEqualUnicodeString((PUNICODE_STRING)&DomainNames[i], &BuiltinDomainName, TRUE))
continue; continue;
TRACE("Mapping name: %wZ\\%wZ\n", &DomainNames[i], &AccountNames[i]);
Status = SamrLookupNamesInDomain(DomainHandle, Status = SamrLookupNamesInDomain(DomainHandle,
1, 1,
&AccountNames[i], &AccountNames[i],
@ -1370,7 +1574,10 @@ LsapLookupBuiltinNames(DWORD Count,
SidsBuffer[i].Sid = CreateSidFromSidAndRid(BuiltinDomainSid, SidsBuffer[i].Sid = CreateSidFromSidAndRid(BuiltinDomainSid,
RelativeIds.Element[0]); RelativeIds.Element[0]);
if (SidsBuffer[i].Sid == NULL) if (SidsBuffer[i].Sid == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done; goto done;
}
SidsBuffer[i].DomainIndex = -1; SidsBuffer[i].DomainIndex = -1;
SidsBuffer[i].Flags = 0; SidsBuffer[i].Flags = 0;
@ -1451,6 +1658,8 @@ LsapLookupAccountNames(DWORD Count,
if (!RtlEqualUnicodeString((PUNICODE_STRING)&DomainNames[i], &AccountDomainName, TRUE)) if (!RtlEqualUnicodeString((PUNICODE_STRING)&DomainNames[i], &AccountDomainName, TRUE))
continue; continue;
TRACE("Mapping name: %wZ\\%wZ\n", &DomainNames[i], &AccountNames[i]);
Status = SamrLookupNamesInDomain(DomainHandle, Status = SamrLookupNamesInDomain(DomainHandle,
1, 1,
&AccountNames[i], &AccountNames[i],
@ -1462,7 +1671,10 @@ LsapLookupAccountNames(DWORD Count,
SidsBuffer[i].Sid = CreateSidFromSidAndRid(AccountDomainSid, SidsBuffer[i].Sid = CreateSidFromSidAndRid(AccountDomainSid,
RelativeIds.Element[0]); RelativeIds.Element[0]);
if (SidsBuffer[i].Sid == NULL) if (SidsBuffer[i].Sid == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done; goto done;
}
SidsBuffer[i].DomainIndex = -1; SidsBuffer[i].DomainIndex = -1;
SidsBuffer[i].Flags = 0; SidsBuffer[i].Flags = 0;
@ -1509,13 +1721,10 @@ LsapLookupNames(DWORD Count,
PRPC_UNICODE_STRING DomainNames = NULL; PRPC_UNICODE_STRING DomainNames = NULL;
PRPC_UNICODE_STRING AccountNames = NULL; PRPC_UNICODE_STRING AccountNames = NULL;
ULONG SidsBufferLength; ULONG SidsBufferLength;
// ULONG DomainIndex;
ULONG i; ULONG i;
ULONG Mapped = 0; ULONG Mapped = 0;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
// PWELL_KNOWN_SID ptr, ptr2;
//TRACE("()\n"); //TRACE("()\n");
TranslatedSids->Entries = 0; TranslatedSids->Entries = 0;
@ -1621,7 +1830,22 @@ LsapLookupNames(DWORD Count,
if (Mapped == Count) if (Mapped == Count)
goto done; 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, Status = LsapLookupBuiltinNames(Count,
DomainNames, DomainNames,
@ -1755,16 +1979,22 @@ LsapLookupWellKnownSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
NamesBuffer[i].Use = ptr->Use; NamesBuffer[i].Use = ptr->Use;
NamesBuffer[i].Flags = 0; NamesBuffer[i].Flags = 0;
NamesBuffer[i].Name.Buffer = MIDL_user_allocate(ptr->Name.MaximumLength); NamesBuffer[i].Name.Length = ptr->AccountName.Length;
NamesBuffer[i].Name.Length = ptr->Name.Length; NamesBuffer[i].Name.MaximumLength = ptr->AccountName.MaximumLength;
NamesBuffer[i].Name.MaximumLength = ptr->Name.MaximumLength; NamesBuffer[i].Name.Buffer = MIDL_user_allocate(ptr->AccountName.MaximumLength);
RtlCopyMemory(NamesBuffer[i].Name.Buffer, ptr->Name.Buffer, ptr->Name.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) if (ptr2 != NULL)
{ {
Status = LsapAddDomainToDomainsList(DomainsBuffer, Status = LsapAddDomainToDomainsList(DomainsBuffer,
&ptr2->Name, &ptr2->AccountName,
ptr2->Sid, ptr2->Sid,
&DomainIndex); &DomainIndex);
if (!NT_SUCCESS(Status)) 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 NTSTATUS
LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer, LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains, PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
@ -2229,16 +2383,6 @@ LsapLookupSids(PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
if (Mapped == SidEnumBuffer->Entries) if (Mapped == SidEnumBuffer->Entries)
goto done; 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: done:
TRACE("done Status: %lx Mapped: %lu\n", Status, Mapped); TRACE("done Status: %lx Mapped: %lu\n", Status, Mapped);

View file

@ -118,6 +118,32 @@ LsapSetObjectAttribute(PLSA_DB_OBJECT DbObject,
LPVOID AttributeData, LPVOID AttributeData,
ULONG AttributeSize); 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 */ /* lsarpc.c */
VOID VOID
LsarStartRpcServer(VOID); LsarStartRpcServer(VOID);
@ -201,30 +227,4 @@ LsarpEnumeratePrivileges(DWORD *EnumerationContext,
PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer, PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer,
DWORD PreferedMaximumLength); 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 */ /* EOF */

View file

@ -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 NTSTATUS
NTAPI NTAPI
SamCloseHandle(IN SAM_HANDLE SamHandle) 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 NTSTATUS
NTAPI NTAPI
SamEnumerateAliasesInDomain(IN SAM_HANDLE DomainHandle, 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 NTSTATUS
NTAPI NTAPI
SamGetMembersInAlias(IN SAM_HANDLE AliasHandle, 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 NTSTATUS
NTAPI NTAPI
SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle, 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 NTSTATUS
NTAPI NTAPI
SamSetInformationAlias(IN SAM_HANDLE AliasHandle, 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 NTSTATUS
NTAPI NTAPI
SamShutdownSamServer(IN SAM_HANDLE ServerHandle) SamShutdownSamServer(IN SAM_HANDLE ServerHandle)

View file

@ -1,6 +1,6 @@
@ stdcall SamAddMemberToAlias(ptr ptr) @ stdcall SamAddMemberToAlias(ptr ptr)
@ stub SamAddMemberToGroup @ stdcall SamAddMemberToGroup(ptr long long)
@ stub SamAddMultipleMembersToAlias @ stdcall SamAddMultipleMembersToAlias(ptr ptr long)
@ stub SamChangePasswordUser2 @ stub SamChangePasswordUser2
@ stub SamChangePasswordUser3 @ stub SamChangePasswordUser3
@ stub SamChangePasswordUser @ stub SamChangePasswordUser
@ -11,9 +11,9 @@
@ stdcall SamCreateGroupInDomain(ptr ptr long ptr ptr) @ stdcall SamCreateGroupInDomain(ptr ptr long ptr ptr)
@ stdcall SamCreateUser2InDomain(ptr ptr long long ptr ptr ptr) @ stdcall SamCreateUser2InDomain(ptr ptr long long ptr ptr ptr)
@ stdcall SamCreateUserInDomain(ptr ptr long ptr ptr) @ stdcall SamCreateUserInDomain(ptr ptr long ptr ptr)
@ stub SamDeleteAlias @ stdcall SamDeleteAlias(ptr)
@ stub SamDeleteGroup @ stdcall SamDeleteGroup(ptr)
@ stub SamDeleteUser @ stdcall SamDeleteUser(ptr)
@ stdcall SamEnumerateAliasesInDomain(ptr ptr ptr long ptr) @ stdcall SamEnumerateAliasesInDomain(ptr ptr ptr long ptr)
@ stdcall SamEnumerateDomainsInSamServer(ptr ptr ptr long ptr) @ stdcall SamEnumerateDomainsInSamServer(ptr ptr ptr long ptr)
@ stdcall SamEnumerateGroupsInDomain(ptr ptr ptr long ptr) @ stdcall SamEnumerateGroupsInDomain(ptr ptr ptr long ptr)
@ -22,9 +22,9 @@
@ stdcall SamGetAliasMembership(ptr long ptr ptr ptr) @ stdcall SamGetAliasMembership(ptr long ptr ptr ptr)
@ stub SamGetCompatibilityMode @ stub SamGetCompatibilityMode
@ stub SamGetDisplayEnumerationIndex @ stub SamGetDisplayEnumerationIndex
@ stub SamGetGroupsForUser @ stdcall SamGetGroupsForUser(ptr ptr ptr)
@ stdcall SamGetMembersInAlias(ptr ptr ptr) @ stdcall SamGetMembersInAlias(ptr ptr ptr)
@ stub SamGetMembersInGroup @ stdcall SamGetMembersInGroup(ptr ptr ptr ptr)
@ stdcall SamLookupDomainInSamServer(ptr ptr ptr) @ stdcall SamLookupDomainInSamServer(ptr ptr ptr)
@ stdcall SamLookupIdsInDomain(ptr long ptr ptr ptr) @ stdcall SamLookupIdsInDomain(ptr long ptr ptr ptr)
@ stdcall SamLookupNamesInDomain(ptr long ptr ptr ptr) @ stdcall SamLookupNamesInDomain(ptr long ptr ptr ptr)
@ -37,18 +37,18 @@
@ stdcall SamQueryInformationDomain(ptr long ptr) @ stdcall SamQueryInformationDomain(ptr long ptr)
@ stdcall SamQueryInformationGroup(ptr long ptr) @ stdcall SamQueryInformationGroup(ptr long ptr)
@ stdcall SamQueryInformationUser(ptr long ptr) @ stdcall SamQueryInformationUser(ptr long ptr)
@ stub SamQuerySecurityObject @ stdcall SamQuerySecurityObject(ptr long ptr)
@ stub SamRemoveMemberFromAlias @ stdcall SamRemoveMemberFromAlias(ptr long)
@ stub SamRemoveMemberFromForeignDomain @ stdcall SamRemoveMemberFromForeignDomain(ptr long)
@ stub SamRemoveMemberFromGroup @ stdcall SamRemoveMemberFromGroup(ptr long)
@ stub SamRemoveMultipleMembersFromAlias @ stdcall SamRemoveMultipleMembersFromAlias(ptr ptr long)
@ stub SamRidToSid @ stdcall SamRidToSid(ptr long ptr)
@ stdcall SamSetInformationAlias(ptr long ptr) @ stdcall SamSetInformationAlias(ptr long ptr)
@ stdcall SamSetInformationDomain(ptr long ptr) @ stdcall SamSetInformationDomain(ptr long ptr)
@ stdcall SamSetInformationGroup(ptr long ptr) @ stdcall SamSetInformationGroup(ptr long ptr)
@ stdcall SamSetInformationUser(ptr long ptr) @ stdcall SamSetInformationUser(ptr long ptr)
@ stub SamSetMemberAttributesOfGroup @ stdcall SamSetMemberAttributesOfGroup(ptr long long)
@ stub SamSetSecurityObject @ stdcall SamSetSecurityObject(ptr long ptr)
@ stdcall SamShutdownSamServer(ptr) @ stdcall SamShutdownSamServer(ptr)
@ stub SamTestPrivateFunctionsDomain @ stub SamTestPrivateFunctionsDomain
@ stub SamTestPrivateFunctionsUser @ stub SamTestPrivateFunctionsUser

View file

@ -83,26 +83,38 @@ static int SIC_LoadOverlayIcon(int icon_idx);
* NOTES * NOTES
* Creates a new icon as a copy of the passed-in icon, overlayed with a * Creates a new icon as a copy of the passed-in icon, overlayed with a
* shortcut image. * shortcut image.
* FIXME: This should go to the ImageList implementation!
*/ */
static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large) static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
{ ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo; {
HICON ShortcutIcon, TargetIcon; ICONINFO ShortcutIconInfo, TargetIconInfo;
BITMAP SourceBitmapInfo, ShortcutBitmapInfo; HICON ShortcutIcon = NULL, TargetIcon;
HDC SourceDC = NULL, BITMAP TargetBitmapInfo, ShortcutBitmapInfo;
ShortcutDC = NULL, HDC ShortcutDC = NULL,
TargetDC = NULL, TargetDC = NULL;
ScreenDC = NULL; HBITMAP OldShortcutBitmap = NULL,
HBITMAP OldSourceBitmap = NULL,
OldShortcutBitmap = NULL,
OldTargetBitmap = NULL; OldTargetBitmap = NULL;
static int s_imgListIdx = -1; static int s_imgListIdx = -1;
ZeroMemory(&ShortcutIconInfo, sizeof(ShortcutIconInfo));
ZeroMemory(&TargetIconInfo, sizeof(TargetIconInfo));
/* Get information about the source icon and shortcut overlay */ /* Get information about the source icon and shortcut overlay.
if (! GetIconInfo(SourceIcon, &SourceIconInfo) * We will write over the source bitmaps to get the final ones */
|| 0 == GetObjectW(SourceIconInfo.hbmColor, sizeof(BITMAP), &SourceBitmapInfo)) if (! GetIconInfo(SourceIcon, &TargetIconInfo))
return NULL;
/* Is it possible with the ImageList implementation? */
if(!TargetIconInfo.hbmColor)
{ {
return NULL; /* 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 */ /* search for the shortcut icon only once */
@ -121,23 +133,25 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
} else } else
ShortcutIcon = NULL; ShortcutIcon = NULL;
if (NULL == ShortcutIcon if (!ShortcutIcon || !GetIconInfo(ShortcutIcon, &ShortcutIconInfo))
|| ! GetIconInfo(ShortcutIcon, &ShortcutIconInfo)
|| 0 == GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo))
{ {
return NULL; goto fail;
}
/* 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;
}
if(!GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo))
{
goto fail;
} }
TargetIconInfo = SourceIconInfo; /* Setup the masks */
TargetIconInfo.hbmMask = NULL;
TargetIconInfo.hbmColor = NULL;
/* 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;
ShortcutDC = CreateCompatibleDC(NULL); ShortcutDC = CreateCompatibleDC(NULL);
if (NULL == ShortcutDC) goto fail; if (NULL == ShortcutDC) goto fail;
OldShortcutBitmap = (HBITMAP)SelectObject(ShortcutDC, ShortcutIconInfo.hbmMask); OldShortcutBitmap = (HBITMAP)SelectObject(ShortcutDC, ShortcutIconInfo.hbmMask);
@ -145,44 +159,120 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
TargetDC = CreateCompatibleDC(NULL); TargetDC = CreateCompatibleDC(NULL);
if (NULL == TargetDC) goto fail; 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); OldTargetBitmap = (HBITMAP)SelectObject(TargetDC, TargetIconInfo.hbmMask);
if (NULL == OldTargetBitmap) goto fail; if (NULL == OldTargetBitmap) goto fail;
/* Create the target mask by ANDing the source and shortcut masks */ /* Create the complete mask by ANDing the source and shortcut masks.
if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight, * NOTE: in an ImageList, all icons have the same dimensions */
SourceDC, 0, 0, SRCCOPY) || if (!BitBlt(TargetDC, 0, 0, ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight, ShortcutDC, 0, 0, SRCAND))
ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
ShortcutDC, 0, 0, SRCAND))
{ {
goto fail; goto fail;
} }
/* Setup the source and target xor bitmap */ /*
if (NULL == SelectObject(SourceDC, SourceIconInfo.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;
}
i = j = 0;
pixel = (PULONG)bits;
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)) NULL == SelectObject(TargetDC, TargetIconInfo.hbmColor))
{ goto fail;
goto fail; if (!MaskBlt(TargetDC, 0, 0, ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
}
/* Copy the source color bitmap to the target */
if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight,
SourceDC, 0, 0, SRCCOPY)) goto fail;
/* 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,
ShortcutDC, 0, 0, ShortcutIconInfo.hbmMask, 0, 0, ShortcutDC, 0, 0, ShortcutIconInfo.hbmMask, 0, 0,
MAKEROP4(0xAA0000, SRCCOPY))) 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 /* Clean up, we're not goto'ing to 'fail' after this so we can be lazy and not set
handles to NULL */ handles to NULL */
SelectObject(TargetDC, OldTargetBitmap); SelectObject(TargetDC, OldTargetBitmap);
DeleteObject(TargetDC); DeleteDC(TargetDC);
SelectObject(ShortcutDC, OldShortcutBitmap); SelectObject(ShortcutDC, OldShortcutBitmap);
DeleteObject(ShortcutDC); DeleteDC(ShortcutDC);
SelectObject(SourceDC, OldSourceBitmap);
DeleteObject(SourceDC);
/* Create the icon using the bitmaps prepared earlier */ /* Create the icon using the bitmaps prepared earlier */
TargetIcon = CreateIconIndirect(&TargetIconInfo); 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 */ /* CreateIconIndirect copies the bitmaps, so we can release our bitmaps now */
DeleteObject(TargetIconInfo.hbmColor); DeleteObject(TargetIconInfo.hbmColor);
DeleteObject(TargetIconInfo.hbmMask); DeleteObject(TargetIconInfo.hbmMask);
/* Delete what GetIconInfo gave us */
DeleteObject(ShortcutIconInfo.hbmColor);
DeleteObject(ShortcutIconInfo.hbmMask);
DestroyIcon(ShortcutIcon);
return TargetIcon; return TargetIcon;
fail: fail:
/* Clean up scratch resources we created */ /* Clean up scratch resources we created */
if (NULL != OldTargetBitmap) SelectObject(TargetDC, OldTargetBitmap); 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.hbmColor) DeleteObject(TargetIconInfo.hbmColor);
if (NULL != TargetIconInfo.hbmMask) DeleteObject(TargetIconInfo.hbmMask); if (NULL != TargetIconInfo.hbmMask) DeleteObject(TargetIconInfo.hbmMask);
if (NULL != TargetDC) DeleteObject(TargetDC); if (NULL != ShortcutIconInfo.hbmColor) DeleteObject(ShortcutIconInfo.hbmColor);
if (NULL != OldShortcutBitmap) SelectObject(ShortcutDC, OldShortcutBitmap); if (NULL != ShortcutIconInfo.hbmMask) DeleteObject(ShortcutIconInfo.hbmColor);
if (NULL != ShortcutDC) DeleteObject(ShortcutDC); if (NULL != ShortcutIcon) DestroyIcon(ShortcutIcon);
if (NULL != OldSourceBitmap) SelectObject(SourceDC, OldSourceBitmap);
if (NULL != SourceDC) DeleteObject(SourceDC);
return NULL; return NULL;
} }
@ -228,7 +321,8 @@ fail:
* appends an icon pair to the end of the cache * appends an icon pair to the end of the cache
*/ */
static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags) static INT SIC_IconAppend (LPCWSTR sSourceFile, INT dwSourceIndex, HICON hSmallIcon, HICON hBigIcon, DWORD dwFlags)
{ LPSIC_ENTRY lpsice; {
LPSIC_ENTRY lpsice;
INT ret, index, index1; INT ret, index, index1;
WCHAR path[MAX_PATH]; WCHAR path[MAX_PATH];
TRACE("%s %i %p %p\n", debugstr_w(sSourceFile), dwSourceIndex, hSmallIcon ,hBigIcon); 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); index = DPA_InsertPtr(sic_hdpa, 0x7fff, lpsice);
if ( INVALID_INDEX == index ) if ( INVALID_INDEX == index )
{ {
HeapFree(GetProcessHeap(), 0, lpsice->sSourceFile); ret = INVALID_INDEX;
SHFree(lpsice); goto leave;
ret = INVALID_INDEX;
} }
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))
{ {
index = ImageList_AddIcon (ShellSmallIconList, hSmallIcon); WARN("Something went wrong when adding the icon to the list: small - 0x%x, big - 0x%x.\n",
index1= ImageList_AddIcon (ShellBigIconList, hBigIcon); index, index1);
if(index != -1) ImageList_Remove(ShellSmallIconList, index);
if (index!=index1) if(index1 != -1) ImageList_Remove(ShellBigIconList, index1);
{ ret = INVALID_INDEX;
FIXME("iconlists out of sync 0x%x 0x%x\n", index, index1); goto leave;
}
lpsice->dwListIndex = index;
ret = lpsice->dwListIndex;
} }
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); LeaveCriticalSection(&SHELL32_SicCS);
return ret; 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 * gets small/big icon by number from a file
*/ */
static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags) static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
{ HICON hiconLarge=0; {
HICON hiconSmall=0; HICON hiconLarge=0;
HICON hiconLargeShortcut; HICON hiconSmall=0;
HICON hiconSmallShortcut; UINT ret;
#if defined(__CYGWIN__) || defined (__MINGW32__) || defined(_MSC_VER)
static UINT (WINAPI*PrivateExtractIconExW)(LPCWSTR,int,HICON*,HICON*,UINT) = NULL; static UINT (WINAPI*PrivateExtractIconExW)(LPCWSTR,int,HICON*,HICON*,UINT) = NULL;
if (!PrivateExtractIconExW) { if (!PrivateExtractIconExW)
{
HMODULE hUser32 = GetModuleHandleA("user32"); HMODULE hUser32 = GetModuleHandleA("user32");
PrivateExtractIconExW = (UINT(WINAPI*)(LPCWSTR,int,HICON*,HICON*,UINT)) GetProcAddress(hUser32, "PrivateExtractIconExW"); PrivateExtractIconExW = (UINT(WINAPI*)(LPCWSTR,int,HICON*,HICON*,UINT)) GetProcAddress(hUser32, "PrivateExtractIconExW");
} }
if (PrivateExtractIconExW) if (PrivateExtractIconExW)
{
PrivateExtractIconExW(sSourceFile, dwSourceIndex, &hiconLarge, &hiconSmall, 1); PrivateExtractIconExW(sSourceFile, dwSourceIndex, &hiconLarge, &hiconSmall, 1);
}
else else
#endif
{ {
PrivateExtractIconsW(sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, NULL, 1, 0); PrivateExtractIconsW(sSourceFile, dwSourceIndex, 32, 32, &hiconLarge, NULL, 1, 0);
PrivateExtractIconsW(sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, NULL, 1, 0); PrivateExtractIconsW(sSourceFile, dwSourceIndex, 16, 16, &hiconSmall, NULL, 1, 0);
@ -298,29 +407,36 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
if ( !hiconLarge || !hiconSmall) if ( !hiconLarge || !hiconSmall)
{ {
WARN("failure loading icon %i from %s (%p %p)\n", dwSourceIndex, debugstr_w(sSourceFile), 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)) if (0 != (dwFlags & GIL_FORSHORTCUT))
{ {
hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE); HICON hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE);
hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE); HICON hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE);
if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut) if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut)
{ {
hiconLarge = hiconLargeShortcut; DestroyIcon(hiconLarge);
hiconSmall = hiconSmallShortcut; DestroyIcon(hiconSmall);
} hiconLarge = hiconLargeShortcut;
else hiconSmall = hiconSmallShortcut;
{ }
WARN("Failed to create shortcut overlayed icons\n"); else
if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut); {
if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut); WARN("Failed to create shortcut overlayed icons\n");
dwFlags &= ~ GIL_FORSHORTCUT; if (NULL != hiconLargeShortcut) DestroyIcon(hiconLargeShortcut);
} if (NULL != hiconSmallShortcut) DestroyIcon(hiconSmallShortcut);
dwFlags &= ~ GIL_FORSHORTCUT;
}
} }
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] * SIC_GetIconIndex [internal]
@ -367,6 +483,7 @@ INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
LeaveCriticalSection(&SHELL32_SicCS); LeaveCriticalSection(&SHELL32_SicCS);
return ret; return ret;
} }
/***************************************************************************** /*****************************************************************************
* SIC_Initialize [internal] * SIC_Initialize [internal]
*/ */
@ -378,6 +495,7 @@ BOOL SIC_Initialize(void)
HDC hDC; HDC hDC;
INT bpp; INT bpp;
DWORD ilMask; DWORD ilMask;
BOOL result = FALSE;
TRACE("Entered SIC_Initialize\n"); TRACE("Entered SIC_Initialize\n");
@ -397,11 +515,11 @@ BOOL SIC_Initialize(void)
if (!hDC) if (!hDC)
{ {
ERR("Failed to create information context (error %d)\n", GetLastError()); ERR("Failed to create information context (error %d)\n", GetLastError());
return FALSE; goto end;
} }
bpp = GetDeviceCaps(hDC, BITSPIXEL); bpp = GetDeviceCaps(hDC, BITSPIXEL);
ReleaseDC(NULL, hDC); DeleteDC(hDC);
if (bpp <= 4) if (bpp <= 4)
ilMask = ILC_COLOR4; ilMask = ILC_COLOR4;
@ -428,61 +546,83 @@ BOOL SIC_Initialize(void)
ilMask, ilMask,
100, 100,
100); 100);
if (!ShellSmallIconList)
{
ERR("Failed to create the small icon list.\n");
goto end;
}
ShellBigIconList = ImageList_Create(cx_large, ShellBigIconList = ImageList_Create(cx_large,
cy_large, cy_large,
ilMask, ilMask,
100, 100,
100); 100);
if (ShellSmallIconList) if (!ShellBigIconList)
{ {
/* Load the document icon, which is used as the default if an icon isn't found. */ ERR("Failed to create the big icon list.\n");
hSm = (HICON)LoadImageW(shell32_hInstance, goto end;
MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
IMAGE_ICON,
cx_small,
cy_small,
LR_SHARED | LR_DEFAULTCOLOR);
if (!hSm)
{
ERR("Failed to load IDI_SHELL_DOCUMENT icon1!\n");
return FALSE;
}
} }
else
/* 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),
IMAGE_ICON,
cx_small,
cy_small,
LR_SHARED | LR_DEFAULTCOLOR);
if (!hSm)
{ {
ERR("Failed to load ShellSmallIconList\n"); ERR("Failed to load small IDI_SHELL_DOCUMENT icon!\n");
return FALSE; goto end;
} }
if (ShellBigIconList) hLg = (HICON)LoadImageW(shell32_hInstance,
MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
IMAGE_ICON,
cx_large,
cy_large,
LR_SHARED | LR_DEFAULTCOLOR);
if (!hLg)
{ {
hLg = (HICON)LoadImageW(shell32_hInstance, ERR("Failed to load large IDI_SHELL_DOCUMENT icon!\n");
MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT), goto end;
IMAGE_ICON,
cx_large,
cy_large,
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;
} }
SIC_IconAppend(swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0); if(SIC_IconAppend(swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0) == INVALID_INDEX)
SIC_IconAppend(swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0); {
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); TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
return TRUE; return result;
} }
/************************************************************************* /*************************************************************************
* SIC_Destroy * SIC_Destroy
* *

View file

@ -306,6 +306,38 @@ HidP_GetScaledUsageValue(
return HidParser_GetScaledUsageValue(&Parser, PreparsedData, ReportType, UsagePage, LinkCollection, Usage, UsageValue, Report, ReportLength); 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 HIDAPI
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -405,24 +437,6 @@ HidP_GetLinkCollectionNodes(
return STATUS_NOT_IMPLEMENTED; 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 NTSTATUS
NTAPI NTAPI
HidP_SysPowerEvent ( HidP_SysPowerEvent (

View file

@ -37,6 +37,7 @@ MouHid_GetButtonMove(
OUT PLONG LastY) OUT PLONG LastY)
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG ValueX, ValueY;
/* init result */ /* init result */
*LastX = 0; *LastX = 0;
@ -44,17 +45,50 @@ MouHid_GetButtonMove(
/* get scaled usage value x */ /* 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); 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);
/* FIXME handle error */ if (Status != HIDP_STATUS_SUCCESS)
ASSERT(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 */ /* 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); 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);
/* FIXME handle error */ if (Status != HIDP_STATUS_SUCCESS)
ASSERT(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 VOID
MouHid_GetButtonFlags( MouHid_GetButtonFlags(
IN PMOUHID_DEVICE_EXTENSION DeviceExtension, IN PMOUHID_DEVICE_EXTENSION DeviceExtension,
@ -132,6 +166,12 @@ MouHid_GetButtonFlags(
TempList = DeviceExtension->CurrentUsageList; TempList = DeviceExtension->CurrentUsageList;
DeviceExtension->CurrentUsageList = DeviceExtension->PreviousUsageList; DeviceExtension->CurrentUsageList = DeviceExtension->PreviousUsageList;
DeviceExtension->PreviousUsageList = TempList; DeviceExtension->PreviousUsageList = TempList;
if (DeviceExtension->MouseAbsolute)
{
// mouse operates absolute
*ButtonFlags |= MOUSE_MOVE_ABSOLUTE;
}
} }
VOID VOID
@ -195,12 +235,12 @@ MouHid_ReadCompletion(
return STATUS_MORE_PROCESSING_REQUIRED; return STATUS_MORE_PROCESSING_REQUIRED;
} }
/* get mouse change flags */
MouHid_GetButtonFlags(DeviceExtension, &ButtonFlags);
/* get mouse change */ /* get mouse change */
MouHid_GetButtonMove(DeviceExtension, &LastX, &LastY); MouHid_GetButtonMove(DeviceExtension, &LastX, &LastY);
/* get mouse change flags */
MouHid_GetButtonFlags(DeviceExtension, &ButtonFlags);
/* init input data */ /* init input data */
RtlZeroMemory(&MouseInputData, sizeof(MOUSE_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); DPRINT("[MOUHID] LastX %ld LastY %ld Flags %x ButtonData %x\n", MouseInputData.LastX, MouseInputData.LastY, MouseInputData.ButtonFlags, MouseInputData.ButtonData);
/* dispatch mouse action */ /* dispatch mouse action */
@ -700,10 +746,10 @@ MouHid_StartDevice(
DeviceExtension->PreparsedData = PreparsedData; DeviceExtension->PreparsedData = PreparsedData;
ValueCapsLength = 1; 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; 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 */ /* now check for wheel mouse support */
ValueCapsLength = 1; ValueCapsLength = 1;

View file

@ -109,6 +109,22 @@ typedef struct
// //
UCHAR StopReadReport; 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; }MOUHID_DEVICE_EXTENSION, *PMOUHID_DEVICE_EXTENSION;
#define WHEEL_DELTA 120 #define WHEEL_DELTA 120

View file

@ -474,8 +474,11 @@ USBD_ParseDescriptors(
return CommonDescriptor; return CommonDescriptor;
} }
/* sanity check */ if (CommonDescriptor->bLength == 0)
ASSERT(CommonDescriptor->bLength); {
/* invalid usb descriptor */
return NULL;
}
/* move to next descriptor */ /* move to next descriptor */
CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength); CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);

View file

@ -819,6 +819,7 @@ CreateDeviceIds(
LPWSTR DeviceString; LPWSTR DeviceString;
WCHAR Buffer[200]; WCHAR Buffer[200];
PHUB_CHILDDEVICE_EXTENSION UsbChildExtension; PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
PHUB_DEVICE_EXTENSION HubDeviceExtension;
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor; PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
@ -828,6 +829,9 @@ CreateDeviceIds(
// //
UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)UsbChildDeviceObject->DeviceExtension; UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)UsbChildDeviceObject->DeviceExtension;
// get hub device extension
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) UsbChildExtension->ParentDeviceObject->DeviceExtension;
// //
// get device descriptor // get device descriptor
// //
@ -1011,10 +1015,12 @@ CreateDeviceIds(
// //
if (UsbChildExtension->DeviceDesc.iSerialNumber) if (UsbChildExtension->DeviceDesc.iSerialNumber)
{ {
LPWSTR SerialBuffer = NULL;
Status = GetUsbStringDescriptor(UsbChildDeviceObject, Status = GetUsbStringDescriptor(UsbChildDeviceObject,
UsbChildExtension->DeviceDesc.iSerialNumber, UsbChildExtension->DeviceDesc.iSerialNumber,
0, 0,
(PVOID*)&UsbChildExtension->usInstanceId.Buffer, (PVOID*)&SerialBuffer,
&UsbChildExtension->usInstanceId.Length); &UsbChildExtension->usInstanceId.Length);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -1022,15 +1028,31 @@ CreateDeviceIds(
return Status; return Status;
} }
UsbChildExtension->usInstanceId.MaximumLength = UsbChildExtension->usInstanceId.Length; // construct instance id buffer
DPRINT("Usb InstanceId %wZ\n", &UsbChildExtension->usInstanceId); 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 else
{ {
// //
// the device did not provide a serial number, lets create a pseudo instance id // 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)); UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR));
if (UsbChildExtension->usInstanceId.Buffer == NULL) if (UsbChildExtension->usInstanceId.Buffer == NULL)
{ {
@ -1304,6 +1326,7 @@ CreateUsbChildDeviceObject(
} }
HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] = NewChildDeviceObject; HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] = NewChildDeviceObject;
HubDeviceExtension->InstanceCount++;
IoInvalidateDeviceRelations(RootHubDeviceObject, BusRelations); IoInvalidateDeviceRelations(RootHubDeviceObject, BusRelations);
return STATUS_SUCCESS; return STATUS_SUCCESS;

View file

@ -558,6 +558,7 @@ USBHUB_PdoHandlePnp(
ULONG Index; ULONG Index;
ULONG bFound; ULONG bFound;
PDEVICE_RELATIONS DeviceRelation; PDEVICE_RELATIONS DeviceRelation;
PDEVICE_OBJECT ParentDevice;
UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension; UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp); Stack = IoGetCurrentIrpStackLocation(Irp);
@ -645,6 +646,7 @@ USBHUB_PdoHandlePnp(
{ {
PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension; PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension;
PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface; PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface;
ParentDevice = UsbChildExtension->ParentDeviceObject;
DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n"); DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
@ -671,10 +673,13 @@ USBHUB_PdoHandlePnp(
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
/* delete device */
IoDeleteDevice(DeviceObject);
if (bFound) if (bFound)
{ {
/* Delete the device object */ /* invalidate device relations */
IoDeleteDevice(DeviceObject); IoInvalidateDeviceRelations(ParentDevice, BusRelations);
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -731,6 +736,12 @@ USBHUB_PdoHandlePnp(
IoSkipCurrentIrpStackLocation(Irp); IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp); return IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp);
} }
case IRP_MN_SURPRISE_REMOVAL:
{
DPRINT("[USBHUB] HandlePnp IRP_MN_SURPRISE_REMOVAL\n");
Status = STATUS_SUCCESS;
break;
}
default: default:
{ {
DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction); DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);

View file

@ -103,8 +103,9 @@ typedef struct _HUB_DEVICE_EXTENSION
PVOID RootHubHandle; PVOID RootHubHandle;
USB_BUS_INTERFACE_USBDI_V2 DeviceInterface; USB_BUS_INTERFACE_USBDI_V2 DeviceInterface;
UNICODE_STRING SymbolicLinkName; UNICODE_STRING SymbolicLinkName;
ULONG InstanceCount;
} HUB_DEVICE_EXTENSION, *PHUB_DEVICE_EXTENSION; } HUB_DEVICE_EXTENSION, *PHUB_DEVICE_EXTENSION;
// createclose.c // createclose.c

View file

@ -125,10 +125,19 @@ USBSTOR_FdoHandleRemoveDevice(
IN OUT PIRP Irp) IN OUT PIRP Irp)
{ {
NTSTATUS Status; 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 */ /* Send the IRP down the stack */
IoSkipCurrentIrpStackLocation(Irp); IoSkipCurrentIrpStackLocation(Irp);
@ -264,7 +273,7 @@ USBSTOR_FdoHandleStartDevice(
// //
// create pdo // create pdo
// //
Status = USBSTOR_CreatePDO(DeviceObject, Index, &DeviceExtension->ChildPDO[Index]); Status = USBSTOR_CreatePDO(DeviceObject, Index);
// //
// check for failure // check for failure
@ -282,6 +291,7 @@ USBSTOR_FdoHandleStartDevice(
// increment pdo index // increment pdo index
// //
Index++; Index++;
DeviceExtension->InstanceCount++;
}while(Index < DeviceExtension->MaxLUN); }while(Index < DeviceExtension->MaxLUN);
@ -340,8 +350,20 @@ USBSTOR_FdoHandlePnp(
switch(IoStack->MinorFunction) 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: case IRP_MN_QUERY_DEVICE_RELATIONS:
{ {
DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS %p\n", DeviceObject);
Status = USBSTOR_FdoHandleDeviceRelations(DeviceExtension, Irp); Status = USBSTOR_FdoHandleDeviceRelations(DeviceExtension, Irp);
break; break;
} }

View file

@ -676,9 +676,9 @@ USBSTOR_PdoHandleQueryInstanceId(
else 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 // check if no unique id
// //
Caps = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities; Caps = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
Caps->UniqueID = TRUE; //FIXME Caps->UniqueID = FALSE; // no unique id is supported
Caps->Removable = TRUE; //FIXME Caps->Removable = TRUE; //FIXME
} }
break; break;
@ -929,6 +929,11 @@ USBSTOR_PdoHandlePnp(
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
break; break;
} }
case IRP_MN_SURPRISE_REMOVAL:
{
Status = STATUS_SUCCESS;
break;
}
default: default:
{ {
// //
@ -1256,13 +1261,19 @@ USBSTOR_SendFormatCapacityIrp(
NTSTATUS NTSTATUS
USBSTOR_CreatePDO( USBSTOR_CreatePDO(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN UCHAR LUN, IN UCHAR LUN)
OUT PDEVICE_OBJECT *ChildDeviceObject)
{ {
PDEVICE_OBJECT PDO; PDEVICE_OBJECT PDO;
NTSTATUS Status; NTSTATUS Status;
PPDO_DEVICE_EXTENSION PDODeviceExtension; PPDO_DEVICE_EXTENSION PDODeviceExtension;
PUFI_INQUIRY_RESPONSE Response; PUFI_INQUIRY_RESPONSE Response;
PFDO_DEVICE_EXTENSION FDODeviceExtension;
//
// get device extension
//
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
// //
// create child device object // create child device object
@ -1292,7 +1303,7 @@ USBSTOR_CreatePDO(
RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION)); RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
PDODeviceExtension->Common.IsFDO = FALSE; PDODeviceExtension->Common.IsFDO = FALSE;
PDODeviceExtension->LowerDeviceObject = DeviceObject; PDODeviceExtension->LowerDeviceObject = DeviceObject;
PDODeviceExtension->PDODeviceObject = ChildDeviceObject; PDODeviceExtension->PDODeviceObject = &FDODeviceExtension->ChildPDO[LUN];
PDODeviceExtension->Self = PDO; PDODeviceExtension->Self = PDO;
PDODeviceExtension->LUN = LUN; PDODeviceExtension->LUN = LUN;
@ -1309,7 +1320,7 @@ USBSTOR_CreatePDO(
// //
// output device object // output device object
// //
*ChildDeviceObject = PDO; FDODeviceExtension->ChildPDO[LUN] = PDO;
// //
// send inquiry command by irp // send inquiry command by irp

View file

@ -71,6 +71,7 @@ typedef struct
PSCSI_REQUEST_BLOCK LastTimerActiveSrb; // last timer tick active srb PSCSI_REQUEST_BLOCK LastTimerActiveSrb; // last timer tick active srb
ULONG SrbErrorHandlingActive; // error handling of srb is activated ULONG SrbErrorHandlingActive; // error handling of srb is activated
ULONG TimerWorkQueueEnabled; // timer work queue enabled ULONG TimerWorkQueueEnabled; // timer work queue enabled
ULONG InstanceCount; // pdo instance count
}FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; }FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
typedef struct typedef struct
@ -364,8 +365,7 @@ USBSTOR_PdoHandlePnp(
NTSTATUS NTSTATUS
USBSTOR_CreatePDO( USBSTOR_CreatePDO(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN UCHAR LUN, IN UCHAR LUN);
OUT PDEVICE_OBJECT *ChildDeviceObject);
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// //

View file

@ -271,6 +271,12 @@ typedef enum _GROUP_INFORMATION_CLASS
GroupReplicationInformation GroupReplicationInformation
} GROUP_INFORMATION_CLASS; } GROUP_INFORMATION_CLASS;
typedef struct _GROUP_MEMBERSHIP
{
ULONG RelativeId;
ULONG Attributes;
} GROUP_MEMBERSHIP, *PGROUP_MEMBERSHIP;
typedef enum _USER_INFORMATION_CLASS typedef enum _USER_INFORMATION_CLASS
{ {
UserGeneralInformation = 1, UserGeneralInformation = 1,
@ -322,6 +328,12 @@ SamAddMemberToGroup(IN SAM_HANDLE GroupHandle,
IN ULONG MemberId, IN ULONG MemberId,
IN ULONG Attributes); IN ULONG Attributes);
NTSTATUS
NTAPI
SamAddMultipleMembersToAlias(IN SAM_HANDLE AliasHandle,
IN PSID *MemberIds,
IN ULONG MemberCount);
NTSTATUS NTSTATUS
NTAPI NTAPI
SamCloseHandle(IN SAM_HANDLE SamHandle); SamCloseHandle(IN SAM_HANDLE SamHandle);
@ -367,6 +379,18 @@ SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
OUT PSAM_HANDLE UserHandle, OUT PSAM_HANDLE UserHandle,
OUT PULONG RelativeId); 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 NTSTATUS
NTAPI NTAPI
SamEnumerateAliasesInDomain(IN SAM_HANDLE DomainHandle, SamEnumerateAliasesInDomain(IN SAM_HANDLE DomainHandle,
@ -412,12 +436,25 @@ SamGetAliasMembership(IN SAM_HANDLE DomainHandle,
OUT PULONG MembershipCount, OUT PULONG MembershipCount,
OUT PULONG *Aliases); OUT PULONG *Aliases);
NTSTATUS
NTAPI
SamGetGroupsForUser(IN SAM_HANDLE UserHandle,
OUT PGROUP_MEMBERSHIP *Groups,
OUT PULONG MembershipCount);
NTSTATUS NTSTATUS
NTAPI NTAPI
SamGetMembersInAlias(IN SAM_HANDLE AliasHandle, SamGetMembersInAlias(IN SAM_HANDLE AliasHandle,
OUT PSID **MemberIds, OUT PSID **MemberIds,
OUT PULONG MemberCount); OUT PULONG MemberCount);
NTSTATUS
NTAPI
SamGetMembersInGroup(IN SAM_HANDLE GroupHandle,
OUT PULONG *MemberIds,
OUT PULONG *Attributes,
OUT PULONG MemberCount);
NTSTATUS NTSTATUS
NTAPI NTAPI
SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle, SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle,
@ -492,11 +529,39 @@ SamQueryInformationUser(IN SAM_HANDLE UserHandle,
IN USER_INFORMATION_CLASS UserInformationClass, IN USER_INFORMATION_CLASS UserInformationClass,
OUT PVOID *Buffer); OUT PVOID *Buffer);
NTSTATUS
NTAPI
SamQuerySecurityObject(IN SAM_HANDLE ObjectHandle,
IN SECURITY_INFORMATION SecurityInformation,
OUT PSECURITY_DESCRIPTOR *SecurityDescriptor);
NTSTATUS NTSTATUS
NTAPI NTAPI
SamRemoveMemberFromAlias(IN SAM_HANDLE AliasHandle, SamRemoveMemberFromAlias(IN SAM_HANDLE AliasHandle,
IN PSID MemberId); 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 NTSTATUS
NTAPI NTAPI
SamSetInformationAlias(IN SAM_HANDLE AliasHandle, SamSetInformationAlias(IN SAM_HANDLE AliasHandle,
@ -521,6 +586,18 @@ SamSetInformationUser(IN SAM_HANDLE UserHandle,
IN USER_INFORMATION_CLASS UserInformationClass, IN USER_INFORMATION_CLASS UserInformationClass,
IN PVOID Buffer); 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 NTSTATUS
NTAPI NTAPI
SamShutdownSamServer(IN SAM_HANDLE ServerHandle); SamShutdownSamServer(IN SAM_HANDLE ServerHandle);

View file

@ -99,11 +99,13 @@ typedef struct _SAMPR_SR_SECURITY_DESCRIPTOR
[size_is(Length)] unsigned char* SecurityDescriptor; [size_is(Length)] unsigned char* SecurityDescriptor;
} SAMPR_SR_SECURITY_DESCRIPTOR, *PSAMPR_SR_SECURITY_DESCRIPTOR; } SAMPR_SR_SECURITY_DESCRIPTOR, *PSAMPR_SR_SECURITY_DESCRIPTOR;
cpp_quote("#ifndef _NTSAM_")
typedef struct _GROUP_MEMBERSHIP typedef struct _GROUP_MEMBERSHIP
{ {
unsigned long RelativeId; unsigned long RelativeId;
unsigned long Attributes; unsigned long Attributes;
} GROUP_MEMBERSHIP, *PGROUP_MEMBERSHIP; } GROUP_MEMBERSHIP, *PGROUP_MEMBERSHIP;
cpp_quote("#endif")
typedef struct _SAMPR_GET_GROUPS_BUFFER typedef struct _SAMPR_GET_GROUPS_BUFFER
{ {

View file

@ -24,23 +24,23 @@
#define WINE_UNICODE_INLINE static inline #define WINE_UNICODE_INLINE static inline
#endif #endif
#define memicmpW(s1,s2,n) _wcsnicmp((const wchar_t *)(s1),(const wchar_t *)(s2),(n)) #define memicmpW(s1,s2,n) _wcsnicmp((s1),(s2),(n))
#define strlenW(s) wcslen((const wchar_t *)(s)) #define strlenW(s) wcslen((s))
#define strcpyW(d,s) wcscpy((wchar_t *)(d),(const wchar_t *)(s)) #define strcpyW(d,s) wcscpy((d),(s))
#define strcatW(d,s) wcscat((wchar_t *)(d),(const wchar_t *)(s)) #define strcatW(d,s) wcscat((d),(s))
#define strcspnW(d,s) wcscspn((wchar_t *)(d),(const wchar_t *)(s)) #define strcspnW(d,s) wcscspn((d),(s))
#define strstrW(d,s) wcsstr((const wchar_t *)(d),(const wchar_t *)(s)) #define strstrW(d,s) wcsstr((d),(s))
#define strtolW(s,e,b) wcstol((const wchar_t *)(s),(wchar_t **)(e),(b)) #define strtolW(s,e,b) wcstol((s),(e),(b))
#define strchrW(s,c) wcschr((const wchar_t *)(s),(wchar_t)(c)) #define strchrW(s,c) wcschr((s),(c))
#define strrchrW(s,c) wcsrchr((const wchar_t *)(s),(wchar_t)(c)) #define strrchrW(s,c) wcsrchr((s),(c))
#define strncmpW(s1,s2,n) wcsncmp((const wchar_t *)(s1),(const wchar_t *)(s2),(n)) #define strncmpW(s1,s2,n) wcsncmp((s1),(s2),(n))
#define strncpyW(s1,s2,n) wcsncpy((wchar_t *)(s1),(const wchar_t *)(s2),(n)) #define strncpyW(s1,s2,n) wcsncpy((s1),(s2),(n))
#define strcmpW(s1,s2) wcscmp((const wchar_t *)(s1),(const wchar_t *)(s2)) #define strcmpW(s1,s2) wcscmp((s1),(s2))
#define strcmpiW(s1,s2) _wcsicmp((const wchar_t *)(s1),(const wchar_t *)(s2)) #define strcmpiW(s1,s2) _wcsicmp((s1),(s2))
#define strncmpiW(s1,s2,n) _wcsnicmp((const wchar_t *)(s1),(const wchar_t *)(s2),(n)) #define strncmpiW(s1,s2,n) _wcsnicmp((s1),(s2),(n))
#define strtoulW(s1,s2,b) wcstoul((const wchar_t *)(s1),(wchar_t **)(s2),(b)) #define strtoulW(s1,s2,b) wcstoul((s1),(s2),(b))
#define strspnW(str, accept) wcsspn((const wchar_t *)(str), (const wchar_t *)(accept)) #define strspnW(str, accept) wcsspn((str),(accept))
#define strpbrkW(str, accept) wcspbrk((const wchar_t *)(str), (const wchar_t *)(accept)) #define strpbrkW(str, accept) wcspbrk((str),(accept))
#define tolowerW(n) towlower((n)) #define tolowerW(n) towlower((n))
#define toupperW(n) towupper((n)) #define toupperW(n) towupper((n))
#define islowerW(n) iswlower((n)) #define islowerW(n) iswlower((n))
@ -51,10 +51,10 @@
#define isxdigitW(n) iswxdigit((n)) #define isxdigitW(n) iswxdigit((n))
#define isspaceW(n) iswspace((n)) #define isspaceW(n) iswspace((n))
#define iscntrlW(n) iswcntrl((n)) #define iscntrlW(n) iswcntrl((n))
#define atoiW(s) _wtoi((const wchar_t *)(s)) #define atoiW(s) _wtoi((s))
#define atolW(s) _wtol((const wchar_t *)(s)) #define atolW(s) _wtol((s))
#define strlwrW(s) _wcslwr((wchar_t *)(s)) #define strlwrW(s) _wcslwr((s))
#define struprW(s) _wcsupr((wchar_t *)(s)) #define struprW(s) _wcsupr((s))
#define sprintfW swprintf #define sprintfW swprintf
#define vsprintfW vswprintf #define vsprintfW vswprintf
#define snprintfW _snwprintf #define snprintfW _snwprintf

View file

@ -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_STATUS
HidParser_GetScaledUsageValueWithReport( HidParser_GetScaledUsageValueWithReport(
@ -652,11 +749,18 @@ HidParser_GetScaledUsageValueWithReport(
// //
// logical boundaries are signed values // logical boundaries are signed values
// //
// FIXME: scale with physical min/max
if ((Data & ~(ReportItem->Mask >> 1)) != 0) if ((Data & ~(ReportItem->Mask >> 1)) != 0)
{ {
Data |= ~ReportItem->Mask; Data |= ~ReportItem->Mask;
} }
} }
else
{
// HACK: logical boundaries are absolute values
return HIDPARSER_STATUS_BAD_LOG_PHY_VALUES;
}
// //
// store result // store result

View file

@ -34,6 +34,8 @@ TranslateHidParserStatus(
return HIDP_STATUS_I8042_TRANS_UNKNOWN; return HIDP_STATUS_I8042_TRANS_UNKNOWN;
case HIDPARSER_STATUS_COLLECTION_NOT_FOUND: case HIDPARSER_STATUS_COLLECTION_NOT_FOUND:
return HIDP_STATUS_NOT_IMPLEMENTED; //FIXME 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); DPRINT1("TranslateHidParserStatus Status %ld not implemented\n", Status);
return HIDP_STATUS_NOT_IMPLEMENTED; return HIDP_STATUS_NOT_IMPLEMENTED;
@ -952,9 +954,54 @@ HidParser_GetUsageValue(
IN PCHAR Report, IN PCHAR Report,
IN ULONG ReportLength) IN ULONG ReportLength)
{ {
UNIMPLEMENTED HIDPARSER_STATUS ParserStatus;
ASSERT(FALSE);
return STATUS_NOT_IMPLEMENTED; //
// 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 NTSTATUS

View file

@ -48,7 +48,8 @@ typedef enum
HIDPARSER_STATUS_INVALID_REPORT_TYPE = -6, HIDPARSER_STATUS_INVALID_REPORT_TYPE = -6,
HIDPARSER_STATUS_BUFFER_TOO_SMALL = -7, HIDPARSER_STATUS_BUFFER_TOO_SMALL = -7,
HIDPARSER_STATUS_USAGE_NOT_FOUND = -8, 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; }HIDPARSER_STATUS_CODES;
typedef struct typedef struct
@ -200,6 +201,7 @@ HidParser_GetLinkCollectionNodes(
OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes, OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
IN OUT PULONG LinkCollectionNodesLength); IN OUT PULONG LinkCollectionNodesLength);
HIDAPI HIDAPI
NTSTATUS NTSTATUS
NTAPI NTAPI

View file

@ -327,6 +327,17 @@ HidParser_GetScaledUsageValueWithReport(
IN PCHAR ReportDescriptor, IN PCHAR ReportDescriptor,
IN ULONG ReportDescriptorLength); 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 */ /* parser.c */
HIDPARSER_STATUS HIDPARSER_STATUS

View file

@ -285,6 +285,11 @@ PoVolumeDevice(
IN PDEVICE_OBJECT DeviceObject IN PDEVICE_OBJECT DeviceObject
); );
VOID
NTAPI
PoRemoveVolumeDevice(
IN PDEVICE_OBJECT DeviceObject);
// //
// Power State routines // Power State routines
// //

View file

@ -1035,6 +1035,9 @@ IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
/* Set the pending delete flag */ /* Set the pending delete flag */
IoGetDevObjExtension(DeviceObject)->ExtensionFlags |= DOE_DELETE_PENDING; IoGetDevObjExtension(DeviceObject)->ExtensionFlags |= DOE_DELETE_PENDING;
/* Unlink with the power manager */
if (DeviceObject->Vpb) PoRemoveVolumeDevice(DeviceObject);
/* Check if the device object can be unloaded */ /* Check if the device object can be unloaded */
if (!DeviceObject->ReferenceCount) IopUnloadDevice(DeviceObject); if (!DeviceObject->ReferenceCount) IopUnloadDevice(DeviceObject);
} }

View file

@ -97,7 +97,52 @@ PoVolumeDevice(IN PDEVICE_OBJECT DeviceObject)
KeReleaseGuardedMutex(&PopVolumeLock); KeReleaseGuardedMutex(&PopVolumeLock);
} }
} }
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 VOID
NTAPI NTAPI
PopFlushVolumeWorker(IN PVOID Context) PopFlushVolumeWorker(IN PVOID Context)

View file

@ -50,11 +50,15 @@ InitBrushImpl(VOID)
VOID VOID
NTAPI 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(pebo);
ASSERT(pbrush); ASSERT(pbrush);
ASSERT(pdc);
pebo->BrushObject.flColorType = 0; pebo->BrushObject.flColorType = 0;
pebo->BrushObject.pvRbrush = NULL; pebo->BrushObject.pvRbrush = NULL;
@ -63,20 +67,24 @@ EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
pebo->flattrs = pbrush->flAttrs; pebo->flattrs = pbrush->flAttrs;
/* Initialize 1 bpp fore and back colors */ /* Initialize 1 bpp fore and back colors */
pebo->crCurrentBack = pdc->pdcattr->crBackgroundClr; pebo->crCurrentBack = crBackgroundClr;
pebo->crCurrentText = pdc->pdcattr->crForegroundClr; pebo->crCurrentText = crForegroundClr;
pebo->psurfTrg = pdc->dclevel.pSurface; pebo->psurfTrg = psurf;
/* We are initializing for a new memory DC */ /* We are initializing for a new memory DC */
if(!pebo->psurfTrg) if(!pebo->psurfTrg)
pebo->psurfTrg = psurfDefaultBitmap; pebo->psurfTrg = psurfDefaultBitmap;
ASSERT(pebo->psurfTrg); ASSERT(pebo->psurfTrg);
ASSERT(pebo->psurfTrg->ppal); ASSERT(pebo->psurfTrg->ppal);
/* Initialize palettes */
pebo->ppalSurf = pebo->psurfTrg->ppal; pebo->ppalSurf = pebo->psurfTrg->ppal;
GDIOBJ_vReferenceObjectByPointer(&pebo->ppalSurf->BaseObject); GDIOBJ_vReferenceObjectByPointer(&pebo->ppalSurf->BaseObject);
pebo->ppalDC = pdc->dclevel.ppal; pebo->ppalDC = ppalDC;
if(!pebo->ppalDC)
pebo->ppalDC = gppalDefault;
GDIOBJ_vReferenceObjectByPointer(&pebo->ppalDC->BaseObject); GDIOBJ_vReferenceObjectByPointer(&pebo->ppalDC->BaseObject);
pebo->ppalDIB = NULL;
if (pbrush->flAttrs & BR_IS_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 VOID
FASTCALL FASTCALL
EBRUSHOBJ_vSetSolidRGBColor(EBRUSHOBJ *pebo, COLORREF crColor) EBRUSHOBJ_vSetSolidRGBColor(EBRUSHOBJ *pebo, COLORREF crColor)
@ -157,13 +175,15 @@ EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo)
VOID VOID
NTAPI NTAPI
EBRUSHOBJ_vUpdate(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc) EBRUSHOBJ_vUpdateFromDC(EBRUSHOBJ *pebo,
PBRUSH pbrush,
PDC pdc)
{ {
/* Cleanup the brush */ /* Cleanup the brush */
EBRUSHOBJ_vCleanup(pebo); EBRUSHOBJ_vCleanup(pebo);
/* Reinitialize */ /* Reinitialize */
EBRUSHOBJ_vInit(pebo, pbrush, pdc); EBRUSHOBJ_vInitFromDC(pebo, pbrush, pdc);
} }
/** /**

View file

@ -600,6 +600,21 @@ EXLATEOBJ_vInitXlateFromDCs(
pexlo->ppalDstDc = pdcDst->dclevel.ppal; 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 VOID
NTAPI NTAPI
EXLATEOBJ_vCleanup(PEXLATEOBJ pexlo) EXLATEOBJ_vCleanup(PEXLATEOBJ pexlo)

View file

@ -7,9 +7,7 @@
*/ */
#include <win32k.h> #include <win32k.h>
DBG_DEFAULT_CHANNEL(GdiBlt);
#define NDEBUG
#include <debug.h>
#define ROP_USES_SOURCE(Rop) (((((Rop) & 0xCC0000) >> 2) != ((Rop) & 0x330000)) || ((((Rop) & 0xCC000000) >> 2) != ((Rop) & 0x33000000))) #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)) #define ROP_USES_MASK(Rop) (((Rop) & 0xFF000000) != (((Rop) & 0xff0000) << 8))
@ -49,12 +47,12 @@ NtGdiAlphaBlend(
return FALSE; return FALSE;
} }
DPRINT("Locking DCs\n"); TRACE("Locking DCs\n");
ahDC[0] = hDCDest; ahDC[0] = hDCDest;
ahDC[1] = hDCSrc ; ahDC[1] = hDCSrc ;
if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ*)ahDC, apObj, GDIObjType_DC_TYPE)) 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); EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
@ -102,7 +100,7 @@ NtGdiAlphaBlend(
} }
/* Prepare DCs for blit */ /* Prepare DCs for blit */
DPRINT("Preparing DCs for blit\n"); TRACE("Preparing DCs for blit\n");
DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect); DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
/* Determine surfaces to be used in the bitblt */ /* Determine surfaces to be used in the bitblt */
@ -124,7 +122,7 @@ NtGdiAlphaBlend(
EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest); EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
/* Perform the alpha blend operation */ /* Perform the alpha blend operation */
DPRINT("Performing the alpha blend\n"); TRACE("Performing the alpha blend\n");
bResult = IntEngAlphaBlend(&BitmapDest->SurfObj, bResult = IntEngAlphaBlend(&BitmapDest->SurfObj,
&BitmapSrc->SurfObj, &BitmapSrc->SurfObj,
DCDest->rosdc.CombinedClip, DCDest->rosdc.CombinedClip,
@ -135,7 +133,7 @@ NtGdiAlphaBlend(
EXLATEOBJ_vCleanup(&exlo); EXLATEOBJ_vCleanup(&exlo);
leave : leave :
DPRINT("Finishing blit\n"); TRACE("Finishing blit\n");
DC_vFinishBlit(DCDest, DCSrc); DC_vFinishBlit(DCDest, DCSrc);
GDIOBJ_vUnlockObject(&DCSrc->BaseObject); GDIOBJ_vUnlockObject(&DCSrc->BaseObject);
GDIOBJ_vUnlockObject(&DCDest->BaseObject); GDIOBJ_vUnlockObject(&DCDest->BaseObject);
@ -197,12 +195,12 @@ NtGdiTransparentBlt(
BOOL Ret = FALSE; BOOL Ret = FALSE;
EXLATEOBJ exlo; EXLATEOBJ exlo;
DPRINT("Locking DCs\n"); TRACE("Locking DCs\n");
ahDC[0] = hdcDst; ahDC[0] = hdcDst;
ahDC[1] = hdcSrc ; ahDC[1] = hdcSrc ;
if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ*)ahDC, apObj, GDIObjType_DC_TYPE)) 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); EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
@ -343,7 +341,7 @@ NtGdiMaskBlt(
} }
else if(psurfMask) else if(psurfMask)
{ {
DPRINT1("Getting Mask bitmap without needing it?\n"); WARN("Getting Mask bitmap without needing it?\n");
SURFACE_ShareUnlockSurface(psurfMask); SURFACE_ShareUnlockSurface(psurfMask);
psurfMask = NULL; psurfMask = NULL;
} }
@ -351,12 +349,12 @@ NtGdiMaskBlt(
MaskPoint.y = yMask; MaskPoint.y = yMask;
/* Take care of source and destination bitmap */ /* Take care of source and destination bitmap */
DPRINT("Locking DCs\n"); TRACE("Locking DCs\n");
ahDC[0] = hdcDest; ahDC[0] = hdcDest;
ahDC[1] = UsesSource ? hdcSrc : NULL; ahDC[1] = UsesSource ? hdcSrc : NULL;
if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ*)ahDC, apObj, GDIObjType_DC_TYPE)) 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); EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
@ -367,7 +365,7 @@ NtGdiMaskBlt(
if (NULL == DCDest) if (NULL == DCDest)
{ {
if(DCSrc) DC_UnlockDc(DCSrc); 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; return FALSE;
} }
@ -497,7 +495,7 @@ NtGdiPlgBlt(
IN INT yMask, IN INT yMask,
IN DWORD crBackColor) IN DWORD crBackColor)
{ {
UNIMPLEMENTED; FIXME("NtGdiPlgBlt: unimplemented.\n");
return FALSE; return FALSE;
} }
@ -558,7 +556,7 @@ GreStretchBltMask(
ahDC[2] = UsesMask ? hDCMask : NULL; ahDC[2] = UsesMask ? hDCMask : NULL;
if (!GDIOBJ_bLockMultipleObjects(3, (HGDIOBJ*)ahDC, apObj, GDIObjType_DC_TYPE)) 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); EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
@ -651,7 +649,7 @@ GreStretchBltMask(
(BitmapMask->SurfObj.sizlBitmap.cx < WidthSrc || (BitmapMask->SurfObj.sizlBitmap.cx < WidthSrc ||
BitmapMask->SurfObj.sizlBitmap.cy < HeightSrc)) 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, BitmapMask->SurfObj.sizlBitmap.cx, BitmapMask->SurfObj.sizlBitmap.cy,
WidthSrc, HeightSrc); WidthSrc, HeightSrc);
EXLATEOBJ_vCleanup(&exlo); EXLATEOBJ_vCleanup(&exlo);
@ -853,7 +851,7 @@ IntGdiPolyPatBlt(
if (pbrush != NULL) if (pbrush != NULL)
{ {
/* Initialize a brush object */ /* Initialize a brush object */
EBRUSHOBJ_vInit(&eboFill, pbrush, pdc); EBRUSHOBJ_vInitFromDC(&eboFill, pbrush, pdc);
IntPatBlt( IntPatBlt(
pdc, pdc,

View file

@ -98,6 +98,8 @@ BOOL NTAPI BRUSH_Cleanup(PVOID ObjectBody);
extern HSURF gahsurfHatch[HS_DDI_MAX]; extern HSURF gahsurfHatch[HS_DDI_MAX];
struct _SURFACE;
struct _PALETTE;
struct _DC; struct _DC;
INIT_FUNCTION INIT_FUNCTION
@ -107,7 +109,11 @@ InitBrushImpl(VOID);
VOID VOID
NTAPI 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 VOID
FASTCALL FASTCALL
@ -115,7 +121,7 @@ EBRUSHOBJ_vSetSolidRGBColor(EBRUSHOBJ *pebo, COLORREF crColor);
VOID VOID
NTAPI NTAPI
EBRUSHOBJ_vUpdate(EBRUSHOBJ *pebo, PBRUSH pbrush, struct _DC *pdc); EBRUSHOBJ_vUpdateFromDC(EBRUSHOBJ *pebo, PBRUSH pbrush, struct _DC *);
BOOL BOOL
NTAPI NTAPI

View file

@ -270,10 +270,10 @@ DC_vInitDc(
pdc->dcattr.ptlBrushOrigin = pdc->dclevel.ptlBrushOrigin; pdc->dcattr.ptlBrushOrigin = pdc->dclevel.ptlBrushOrigin;
/* Initialize EBRUSHOBJs */ /* Initialize EBRUSHOBJs */
EBRUSHOBJ_vInit(&pdc->eboFill, pdc->dclevel.pbrFill, pdc); EBRUSHOBJ_vInitFromDC(&pdc->eboFill, pdc->dclevel.pbrFill, pdc);
EBRUSHOBJ_vInit(&pdc->eboLine, pdc->dclevel.pbrLine, pdc); EBRUSHOBJ_vInitFromDC(&pdc->eboLine, pdc->dclevel.pbrLine, pdc);
EBRUSHOBJ_vInit(&pdc->eboText, pbrDefaultBrush, pdc); EBRUSHOBJ_vInitFromDC(&pdc->eboText, pbrDefaultBrush, pdc);
EBRUSHOBJ_vInit(&pdc->eboBackground, pbrDefaultBrush, pdc); EBRUSHOBJ_vInitFromDC(&pdc->eboBackground, pbrDefaultBrush, pdc);
/* Setup fill data */ /* Setup fill data */
pdc->dcattr.jROP2 = R2_COPYPEN; pdc->dcattr.jROP2 = R2_COPYPEN;

View file

@ -43,7 +43,7 @@ DC_vUpdateFillBrush(PDC pdc)
if (pdcattr->ulDirty_ & DIRTY_FILL) if (pdcattr->ulDirty_ & DIRTY_FILL)
{ {
/* Update eboFill */ /* Update eboFill */
EBRUSHOBJ_vUpdate(&pdc->eboFill, pdc->dclevel.pbrFill, pdc); EBRUSHOBJ_vUpdateFromDC(&pdc->eboFill, pdc->dclevel.pbrFill, pdc);
} }
/* Check for DC brush */ /* Check for DC brush */
@ -90,7 +90,7 @@ DC_vUpdateLineBrush(PDC pdc)
if (pdcattr->ulDirty_ & DIRTY_LINE) if (pdcattr->ulDirty_ & DIRTY_LINE)
{ {
/* Update eboLine */ /* Update eboLine */
EBRUSHOBJ_vUpdate(&pdc->eboLine, pdc->dclevel.pbrLine, pdc); EBRUSHOBJ_vUpdateFromDC(&pdc->eboLine, pdc->dclevel.pbrLine, pdc);
} }
/* Check for DC pen */ /* Check for DC pen */
@ -113,7 +113,7 @@ DC_vUpdateTextBrush(PDC pdc)
/* Timo : The text brush should never be changed. /* Timo : The text brush should never be changed.
* Jérôme : Yeah, but its palette must be updated anyway! */ * Jérôme : Yeah, but its palette must be updated anyway! */
if(pdcattr->ulDirty_ & DIRTY_TEXT) if(pdcattr->ulDirty_ & DIRTY_TEXT)
EBRUSHOBJ_vUpdate(&pdc->eboText, pbrDefaultBrush, pdc); EBRUSHOBJ_vUpdateFromDC(&pdc->eboText, pbrDefaultBrush, pdc);
/* Update the eboText's solid color */ /* Update the eboText's solid color */
EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboText, pdcattr->crForegroundClr); EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboText, pdcattr->crForegroundClr);
@ -129,7 +129,7 @@ DC_vUpdateBackgroundBrush(PDC pdc)
PDC_ATTR pdcattr = pdc->pdcattr; PDC_ATTR pdcattr = pdc->pdcattr;
if(pdcattr->ulDirty_ & DIRTY_BACKGROUND) if(pdcattr->ulDirty_ & DIRTY_BACKGROUND)
EBRUSHOBJ_vUpdate(&pdc->eboBackground, pbrDefaultBrush, pdc); EBRUSHOBJ_vUpdateFromDC(&pdc->eboBackground, pbrDefaultBrush, pdc);
/* Update the eboBackground's solid color */ /* Update the eboBackground's solid color */
EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboBackground, pdcattr->crBackgroundClr); EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboBackground, pdcattr->crBackgroundClr);

View file

@ -1042,7 +1042,14 @@ CLEANUP:
} }
#endif #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 BOOL
UserDrawIconEx( UserDrawIconEx(
HDC hDc, HDC hDc,
@ -1055,128 +1062,220 @@ UserDrawIconEx(
HBRUSH hbrFlickerFreeDraw, HBRUSH hbrFlickerFreeDraw,
UINT diFlags) UINT diFlags)
{ {
PSURFACE psurfDest, psurfMask, psurfColor, psurfOffScreen;
PDC pdc = NULL;
BOOL Ret = FALSE; BOOL Ret = FALSE;
HBITMAP hbmMask, hbmColor; HBITMAP hbmMask, hbmColor;
BITMAP bmpColor, bm; BOOL bOffScreen, bAlpha = FALSE;
BOOL DoFlickerFree; RECTL rcDest, rcSrc;
INT iOldBkColor = 0, iOldTxtColor = 0; CLIPOBJ* pdcClipObj = NULL;
EXLATEOBJ exlo;
HDC hMemDC, hDestDC = hDc;
HGDIOBJ hOldOffBrush = 0; /* Stupid case */
HGDIOBJ hOldOffBmp = 0; if((diFlags & DI_NORMAL) == 0)
HBITMAP hTmpBmp = 0, hOffBmp = 0; {
BOOL bAlpha = FALSE; ERR("DrawIconEx called without mask or color bitmap to draw.\n");
INT x=xLeft, y=yTop; return FALSE;
}
hbmMask = pIcon->IconInfo.hbmMask; hbmMask = pIcon->IconInfo.hbmMask;
hbmColor = pIcon->IconInfo.hbmColor; hbmColor = pIcon->IconInfo.hbmColor;
if (istepIfAniCur) if (istepIfAniCur)
ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n"); 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; 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; return FALSE;
} }
if(!(hMemDC = NtGdiCreateCompatibleDC(hDc))) /* Set source rect */
{ RECTL_vSetRect(&rcSrc, 0, 0, pIcon->Size.cx, pIcon->Size.cy);
ERR("NtGdiCreateCompatibleDC failed!\n");
return FALSE;
}
/* Check for alpha */ /* Check for alpha */
if (hbmColor if (psurfColor &&
&& (bmpColor.bmBitsPixel == 32) (psurfColor->SurfObj.iBitmapFormat == BMF_32BPP) &&
&& (diFlags & DI_IMAGE)) (diFlags & DI_IMAGE))
{ {
SURFACE *psurfOff = NULL;
PFN_DIB_GetPixel fnSource_GetPixel = NULL; PFN_DIB_GetPixel fnSource_GetPixel = NULL;
INT i, j; INT i, j;
/* In order to correctly display 32 bit icons Windows first scans the image, /* 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 */ because information about transparency is not stored in any image's headers */
psurfOff = SURFACE_ShareLockSurface(hbmColor); fnSource_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel;
if (psurfOff) for (i = 0; i < psurfColor->SurfObj.sizlBitmap.cx; i++)
{ {
fnSource_GetPixel = DibFunctionsForBitmapFormat[psurfOff->SurfObj.iBitmapFormat].DIB_GetPixel; for (j = 0; j < psurfColor->SurfObj.sizlBitmap.cy; j++)
if (fnSource_GetPixel)
{ {
for (i = 0; i < psurfOff->SurfObj.sizlBitmap.cx; i++) bAlpha = ((BYTE)(fnSource_GetPixel(&psurfColor->SurfObj, i, j) >> 24) & 0xff);
{ if (bAlpha)
for (j = 0; j < psurfOff->SurfObj.sizlBitmap.cy; j++) break;
{
bAlpha = ((BYTE)(fnSource_GetPixel(&psurfOff->SurfObj, i, j) >> 24) & 0xff);
if (bAlpha)
break;
}
if (bAlpha)
break;
}
} }
SURFACE_ShareUnlockSurface(psurfOff); if (bAlpha)
break;
} }
} }
/* Fix width parameter, if needed */
if (!cxWidth) if (!cxWidth)
cxWidth = ((diFlags & DI_DEFAULTSIZE) ?
UserGetSystemMetrics(SM_CXICON) : pIcon->Size.cx);
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(diFlags & DI_DEFAULTSIZE)
if(!hDestDC) cxWidth = pIcon->IconInfo.fIcon ?
{ UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR);
ERR("NtGdiCreateCompatibleDC failed!\n"); else
Ret = FALSE; cxWidth = pIcon->Size.cx;
goto Cleanup ; }
}
hOffBmp = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight); /* Fix height parameter, if needed */
if(!hOffBmp) if (!cyHeight)
{ {
ERR("NtGdiCreateCompatibleBitmap failed!\n"); if(diFlags & DI_DEFAULTSIZE)
goto Cleanup ; cyHeight = pIcon->IconInfo.fIcon ?
} UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR);
hOldOffBmp = NtGdiSelectBitmap(hDestDC, hOffBmp); else
hOldOffBrush = NtGdiSelectBrush(hDestDC, hbrFlickerFreeDraw); cyHeight = pIcon->Size.cy;
NtGdiPatBlt(hDestDC, 0, 0, cxWidth, cyHeight, PATCOPY);
NtGdiSelectBrush(hDestDC, hOldOffBrush);
x=y=0;
} }
/* Set Background/foreground colors */ /* Should we render off-screen? */
iOldTxtColor = IntGdiSetTextColor(hDc, 0); // Black bOffScreen = hbrFlickerFreeDraw && (GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH);
iOldBkColor = IntGdiSetBkColor(hDc, 0x00FFFFFF); // White
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)) 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; BYTE Alpha;
INT i, j; INT i, j;
PSURFACE psurf; PSURFACE psurf = NULL;
PBYTE ptr ; PBYTE ptr ;
HBITMAP hMemBmp = NULL; HBITMAP hsurfCopy = NULL;
hMemBmp = BITMAP_CopyBitmap(hbmColor); hsurfCopy = BITMAP_CopyBitmap(hbmColor);
if(!hMemBmp) if(!hsurfCopy)
{ {
ERR("BITMAP_CopyBitmap failed!"); ERR("BITMAP_CopyBitmap failed!");
goto CleanupAlpha; goto CleanupAlpha;
} }
psurf = SURFACE_ShareLockSurface(hMemBmp); psurf = SURFACE_ShareLockSurface(hsurfCopy);
if(!psurf) if(!psurf)
{ {
ERR("SURFACE_LockSurface failed!\n"); ERR("SURFACE_LockSurface failed!\n");
@ -1197,109 +1296,181 @@ UserDrawIconEx(
ptr += 4; ptr += 4;
} }
} }
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 = NtGdiAlphaBlend(hDestDC, Ret = IntEngAlphaBlend(&psurfDest->SurfObj,
x, &psurf->SurfObj,
y, pdcClipObj,
cxWidth, &exlo.xlo,
cyHeight, &rcDest,
hMemDC, &rcSrc,
0, &blendobj);
0,
pIcon->Size.cx, EXLATEOBJ_vCleanup(&exlo);
pIcon->Size.cy,
pixelblend,
NULL);
NtGdiSelectBitmap(hMemDC, hTmpBmp);
CleanupAlpha: CleanupAlpha:
if(hMemBmp) NtGdiDeleteObjectApp(hMemBmp); if(psurf) SURFACE_ShareUnlockSurface(psurf);
if(hsurfCopy) NtGdiDeleteObjectApp(hsurfCopy);
if(Ret) goto done; if(Ret) goto done;
ERR("NtGdiAlphaBlend failed!\n");
} }
if (diFlags & DI_MASK) if (diFlags & DI_MASK)
{ {
DWORD rop = (diFlags & DI_IMAGE) ? SRCAND : SRCCOPY; DWORD rop4 = (diFlags & DI_IMAGE) ? ROP4_SRCAND : ROP4_SRCCOPY;
hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmMask);
NtGdiStretchBlt(hDestDC, EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
x,
y, Ret = IntEngStretchBlt(&psurfDest->SurfObj,
cxWidth, &psurfMask->SurfObj,
cyHeight, NULL,
hMemDC, pdcClipObj,
0, &exlo.xlo,
0, NULL,
pIcon->Size.cx, &rcDest,
pIcon->Size.cy, &rcSrc,
rop, NULL,
0); NULL,
NtGdiSelectBitmap(hMemDC, hTmpBmp); NULL,
rop4);
EXLATEOBJ_vCleanup(&exlo);
if(!Ret)
{
ERR("Failed to mask the bitmap data.\n");
goto Cleanup;
}
} }
if(diFlags & DI_IMAGE) if(diFlags & DI_IMAGE)
{ {
if (hbmColor) if (psurfColor)
{ {
DWORD rop = (diFlags & DI_MASK) ? SRCINVERT : SRCCOPY ; DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY ;
hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmColor);
NtGdiStretchBlt(hDestDC, EXLATEOBJ_vInitialize(&exlo, psurfColor->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
x,
y, Ret = IntEngStretchBlt(&psurfDest->SurfObj,
cxWidth, &psurfColor->SurfObj,
cyHeight, NULL,
hMemDC, pdcClipObj,
0, &exlo.xlo,
0, NULL,
pIcon->Size.cx, &rcDest,
pIcon->Size.cy, &rcSrc,
rop, NULL,
0); NULL,
NtGdiSelectBitmap(hMemDC, hTmpBmp); NULL,
rop4);
EXLATEOBJ_vCleanup(&exlo);
if(!Ret)
{
ERR("Failed to render the icon bitmap.\n");
goto Cleanup;
}
} }
else else
{ {
/* Mask bitmap holds the information in its second half */ /* Mask bitmap holds the information in its bottom half */
DWORD rop = (diFlags & DI_MASK) ? SRCINVERT : SRCCOPY ; DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY;
hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmMask); RECTL_vOffsetRect(&rcSrc, 0, pIcon->Size.cy);
NtGdiStretchBlt(hDestDC,
x, EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
y,
cxWidth, Ret = IntEngStretchBlt(&psurfDest->SurfObj,
cyHeight, &psurfMask->SurfObj,
hMemDC, NULL,
0, pdcClipObj,
pIcon->Size.cy, &exlo.xlo,
pIcon->Size.cx, NULL,
pIcon->Size.cy, &rcDest,
rop, &rcSrc,
0); NULL,
NtGdiSelectBitmap(hMemDC, hTmpBmp); NULL,
NULL,
rop4);
EXLATEOBJ_vCleanup(&exlo);
if(!Ret)
{
ERR("Failed to render the icon bitmap.\n");
goto Cleanup;
}
} }
} }
done: 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;
}
/* Color translation */
EXLATEOBJ_vInitialize(&exlo, psurfOffScreen->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
/* Blt it! */
Ret = IntEngBitBlt(&psurfDest->SurfObj,
&psurfOffScreen->SurfObj,
NULL,
pdcClipObj,
&exlo.xlo,
&rcDest,
&ptSrc,
NULL,
NULL,
NULL,
ROP4_SRCCOPY);
EXLATEOBJ_vCleanup(&exlo);
} }
/* Restore foreground and background colors */
IntGdiSetBkColor(hDc, iOldBkColor);
IntGdiSetTextColor(hDc, iOldTxtColor);
Ret = TRUE ;
Cleanup: Cleanup:
NtGdiDeleteObjectApp(hMemDC); if(pdc)
if(hDestDC != hDc)
{ {
if(hOldOffBmp) NtGdiSelectBitmap(hDestDC, hOldOffBmp); DC_vFinishBlit(pdc, NULL);
NtGdiDeleteObjectApp(hDestDC); DC_UnlockDc(pdc);
if(hOffBmp) NtGdiDeleteObjectApp(hOffBmp);
} }
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; return Ret;
} }