mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 12:40:33 +00:00
Synchronize with trunk's revision r57599.
svn path=/branches/ros-csrss/; revision=57600
This commit is contained in:
commit
aab393ca70
36 changed files with 1985 additions and 571 deletions
|
@ -1221,6 +1221,7 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olecli32",0x0
|
||||||
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","olesvr32",0x00000000,"olesvr32.dll"
|
HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\KnownDlls","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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
return NULL;
|
||||||
|
|
||||||
|
/* Is it possible with the ImageList implementation? */
|
||||||
|
if(!TargetIconInfo.hbmColor)
|
||||||
|
{
|
||||||
|
/* Maybe we'll support this at some point */
|
||||||
|
FIXME("1bpp icon wants its overlay!\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!GetObjectW(TargetIconInfo.hbmColor, sizeof(BITMAP), &TargetBitmapInfo))
|
||||||
|
{
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* search for the shortcut icon only once */
|
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetIconInfo = SourceIconInfo;
|
/* Is it possible with the ImageLists ? */
|
||||||
TargetIconInfo.hbmMask = NULL;
|
if(!ShortcutIconInfo.hbmColor)
|
||||||
TargetIconInfo.hbmColor = NULL;
|
{
|
||||||
|
/* Maybe we'll support this at some point */
|
||||||
|
FIXME("Should draw 1bpp overlay!\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup the source, shortcut and target masks */
|
if(!GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo))
|
||||||
SourceDC = CreateCompatibleDC(NULL);
|
{
|
||||||
if (NULL == SourceDC) goto fail;
|
goto fail;
|
||||||
OldSourceBitmap = (HBITMAP)SelectObject(SourceDC, SourceIconInfo.hbmMask);
|
}
|
||||||
if (NULL == OldSourceBitmap) goto fail;
|
|
||||||
|
|
||||||
|
/* Setup the masks */
|
||||||
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,
|
|
||||||
ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
|
|
||||||
ShortcutDC, 0, 0, SRCAND))
|
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:
|
||||||
NULL == SelectObject(TargetDC, TargetIconInfo.hbmColor))
|
* 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;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the source color bitmap to the target */
|
i = j = 0;
|
||||||
if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmHeight,
|
pixel = (PULONG)bits;
|
||||||
SourceDC, 0, 0, SRCCOPY)) goto fail;
|
|
||||||
|
|
||||||
/* Copy the source xor bitmap to the target and clear out part of it by using
|
for(i=0; i<TargetBitmapInfo.bmHeight; i++)
|
||||||
the shortcut mask */
|
{
|
||||||
if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor)) goto fail;
|
for(j=0; j<TargetBitmapInfo.bmWidth; j++)
|
||||||
if (!MaskBlt(TargetDC, 0, SourceBitmapInfo.bmHeight - ShortcutBitmapInfo.bmHeight,
|
{
|
||||||
ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
|
add_alpha = (*pixel++ & 0xFF000000) != 0;
|
||||||
|
if(add_alpha) break;
|
||||||
|
}
|
||||||
|
if(add_alpha) break;
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(), 0, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate the bits */
|
||||||
|
bits = HeapAlloc(GetProcessHeap(), 0, ShortcutBitmapInfo.bmHeight*ShortcutBitmapInfo.bmWidthBytes);
|
||||||
|
if(!bits) goto fail;
|
||||||
|
|
||||||
|
ZeroMemory(buffer, sizeof(buffer));
|
||||||
|
lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
lpbmi->bmiHeader.biWidth = ShortcutBitmapInfo.bmWidth;
|
||||||
|
lpbmi->bmiHeader.biHeight = ShortcutBitmapInfo.bmHeight;
|
||||||
|
lpbmi->bmiHeader.biPlanes = 1;
|
||||||
|
lpbmi->bmiHeader.biBitCount = 32;
|
||||||
|
|
||||||
|
if(!GetDIBits(TargetDC, ShortcutIconInfo.hbmColor, 0, ShortcutBitmapInfo.bmHeight, bits, lpbmi, DIB_RGB_COLORS))
|
||||||
|
{
|
||||||
|
ERR("GetBIBits failed!\n");
|
||||||
|
HeapFree(GetProcessHeap(), 0, bits);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel = (PULONG)bits;
|
||||||
|
/* Remove alpha channel component or make it totally opaque */
|
||||||
|
for(i=0; i<ShortcutBitmapInfo.bmHeight; i++)
|
||||||
|
{
|
||||||
|
for(j=0; j<ShortcutBitmapInfo.bmWidth; j++)
|
||||||
|
{
|
||||||
|
if(add_alpha) *pixel++ |= 0xFF000000;
|
||||||
|
else *pixel++ &= 0x00FFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GetDIBits return BI_BITFIELDS with masks set to 0, and SetDIBits fails when masks are 0. The irony... */
|
||||||
|
lpbmi->bmiHeader.biCompression = BI_RGB;
|
||||||
|
|
||||||
|
/* Set the bits again */
|
||||||
|
if(!SetDIBits(TargetDC, ShortcutIconInfo.hbmColor, 0, ShortcutBitmapInfo.bmHeight, bits, lpbmi, DIB_RGB_COLORS))
|
||||||
|
{
|
||||||
|
ERR("SetBIBits failed!, %lu\n", GetLastError());
|
||||||
|
HeapFree(GetProcessHeap(), 0, bits);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(), 0, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now do the copy. We overwrite the original icon data */
|
||||||
|
if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor) ||
|
||||||
|
NULL == SelectObject(TargetDC, TargetIconInfo.hbmColor))
|
||||||
|
goto fail;
|
||||||
|
if (!MaskBlt(TargetDC, 0, 0, ShortcutBitmapInfo.bmWidth, ShortcutBitmapInfo.bmHeight,
|
||||||
ShortcutDC, 0, 0, ShortcutIconInfo.hbmMask, 0, 0,
|
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);
|
|
||||||
SHFree(lpsice);
|
|
||||||
ret = INVALID_INDEX;
|
ret = INVALID_INDEX;
|
||||||
|
goto leave;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
index = ImageList_AddIcon (ShellSmallIconList, hSmallIcon);
|
index = ImageList_AddIcon (ShellSmallIconList, hSmallIcon);
|
||||||
index1= ImageList_AddIcon (ShellBigIconList, hBigIcon);
|
index1= ImageList_AddIcon (ShellBigIconList, hBigIcon);
|
||||||
|
|
||||||
|
/* Something went wrong when allocating a new image in the list. Abort. */
|
||||||
|
if((index == -1) || (index1 == -1))
|
||||||
|
{
|
||||||
|
WARN("Something went wrong when adding the icon to the list: small - 0x%x, big - 0x%x.\n",
|
||||||
|
index, index1);
|
||||||
|
if(index != -1) ImageList_Remove(ShellSmallIconList, index);
|
||||||
|
if(index1 != -1) ImageList_Remove(ShellBigIconList, index1);
|
||||||
|
ret = INVALID_INDEX;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
if (index!=index1)
|
if (index!=index1)
|
||||||
{
|
{
|
||||||
FIXME("iconlists out of sync 0x%x 0x%x\n", index, index1);
|
FIXME("iconlists out of sync 0x%x 0x%x\n", index, index1);
|
||||||
|
/* What to do ???? */
|
||||||
}
|
}
|
||||||
lpsice->dwListIndex = index;
|
lpsice->dwListIndex = index;
|
||||||
ret = lpsice->dwListIndex;
|
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 hiconLarge=0;
|
||||||
HICON hiconSmall=0;
|
HICON hiconSmall=0;
|
||||||
HICON hiconLargeShortcut;
|
UINT ret;
|
||||||
HICON hiconSmallShortcut;
|
|
||||||
|
|
||||||
#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);
|
||||||
|
@ -299,15 +408,19 @@ 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)
|
||||||
{
|
{
|
||||||
|
DestroyIcon(hiconLarge);
|
||||||
|
DestroyIcon(hiconSmall);
|
||||||
hiconLarge = hiconLargeShortcut;
|
hiconLarge = hiconLargeShortcut;
|
||||||
hiconSmall = hiconSmallShortcut;
|
hiconSmall = hiconSmallShortcut;
|
||||||
}
|
}
|
||||||
|
@ -320,7 +433,10 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags);
|
ret = SIC_IconAppend (sSourceFile, dwSourceIndex, hiconSmall, hiconLarge, dwFlags);
|
||||||
|
DestroyIcon(hiconLarge);
|
||||||
|
DestroyIcon(hiconSmall);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* SIC_GetIconIndex [internal]
|
* 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,14 +546,23 @@ 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)
|
||||||
{
|
{
|
||||||
|
ERR("Failed to create the big icon list.\n");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
/* Load the document icon, which is used as the default if an icon isn't found. */
|
/* Load the document icon, which is used as the default if an icon isn't found. */
|
||||||
hSm = (HICON)LoadImageW(shell32_hInstance,
|
hSm = (HICON)LoadImageW(shell32_hInstance,
|
||||||
MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
|
MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
|
||||||
|
@ -445,18 +572,10 @@ BOOL SIC_Initialize(void)
|
||||||
LR_SHARED | LR_DEFAULTCOLOR);
|
LR_SHARED | LR_DEFAULTCOLOR);
|
||||||
if (!hSm)
|
if (!hSm)
|
||||||
{
|
{
|
||||||
ERR("Failed to load IDI_SHELL_DOCUMENT icon1!\n");
|
ERR("Failed to load small IDI_SHELL_DOCUMENT icon!\n");
|
||||||
return FALSE;
|
goto end;
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ERR("Failed to load ShellSmallIconList\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ShellBigIconList)
|
|
||||||
{
|
|
||||||
hLg = (HICON)LoadImageW(shell32_hInstance,
|
hLg = (HICON)LoadImageW(shell32_hInstance,
|
||||||
MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
|
MAKEINTRESOURCEW(IDI_SHELL_DOCUMENT),
|
||||||
IMAGE_ICON,
|
IMAGE_ICON,
|
||||||
|
@ -465,24 +584,45 @@ BOOL SIC_Initialize(void)
|
||||||
LR_SHARED | LR_DEFAULTCOLOR);
|
LR_SHARED | LR_DEFAULTCOLOR);
|
||||||
if (!hLg)
|
if (!hLg)
|
||||||
{
|
{
|
||||||
ERR("Failed to load IDI_SHELL_DOCUMENT icon2!\n");
|
ERR("Failed to load large IDI_SHELL_DOCUMENT icon!\n");
|
||||||
DestroyIcon(hSm);
|
goto end;
|
||||||
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
|
||||||
*
|
*
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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);
|
||||||
|
if (Status != HIDP_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* FIXME: handle more errors */
|
||||||
|
if (Status == HIDP_STATUS_BAD_LOG_PHY_VALUES)
|
||||||
|
{
|
||||||
|
/* FIXME: assume it operates in absolute mode */
|
||||||
|
DeviceExtension->MouseAbsolute = TRUE;
|
||||||
|
|
||||||
|
/* get unscaled value */
|
||||||
|
Status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_X, (PULONG)&ValueX, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||||
|
|
||||||
/* FIXME handle error */
|
/* FIXME handle error */
|
||||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
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);
|
||||||
|
if (Status != HIDP_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
// FIXME: handle more errors
|
||||||
|
if (Status == HIDP_STATUS_BAD_LOG_PHY_VALUES)
|
||||||
|
{
|
||||||
|
// assume it operates in absolute mode
|
||||||
|
DeviceExtension->MouseAbsolute = TRUE;
|
||||||
|
|
||||||
|
// get unscaled value
|
||||||
|
Status = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_GENERIC_Y, (PULONG)&ValueY, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
|
||||||
|
|
||||||
/* FIXME handle error */
|
/* FIXME handle error */
|
||||||
ASSERT(Status == HIDP_STATUS_SUCCESS);
|
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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
//
|
//
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,51 @@ PoVolumeDevice(IN PDEVICE_OBJECT DeviceObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
PoRemoveVolumeDevice(IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT_POWER_EXTENSION Dope;
|
||||||
|
PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* If the device already has the dope, return it */
|
||||||
|
DeviceExtension = IoGetDevObjExtension(DeviceObject);
|
||||||
|
if (!DeviceExtension->Dope)
|
||||||
|
{
|
||||||
|
/* no dope */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure we can flush safely */
|
||||||
|
KeAcquireGuardedMutex(&PopVolumeLock);
|
||||||
|
|
||||||
|
/* Get dope from device */
|
||||||
|
Dope = (PDEVICE_OBJECT_POWER_EXTENSION)DeviceExtension->Dope;
|
||||||
|
|
||||||
|
if (Dope->Volume.Flink)
|
||||||
|
{
|
||||||
|
/* Remove from volume from list */
|
||||||
|
RemoveEntryList(&Dope->Volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow flushes to go through */
|
||||||
|
KeReleaseGuardedMutex(&PopVolumeLock);
|
||||||
|
|
||||||
|
/* Now remove dope from device object */
|
||||||
|
KeAcquireSpinLock(&PopDopeGlobalLock, &OldIrql);
|
||||||
|
|
||||||
|
/* remove from dev obj */
|
||||||
|
DeviceExtension->Dope = NULL;
|
||||||
|
|
||||||
|
/* Release lock */
|
||||||
|
KeReleaseSpinLock(&PopDopeGlobalLock, OldIrql);
|
||||||
|
|
||||||
|
/* Free dope */
|
||||||
|
ExFreePoolWithTag(Dope, 'Dope');
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PopFlushVolumeWorker(IN PVOID Context)
|
PopFlushVolumeWorker(IN PVOID Context)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,18 +1062,21 @@ 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;
|
/* Stupid case */
|
||||||
HGDIOBJ hOldOffBrush = 0;
|
if((diFlags & DI_NORMAL) == 0)
|
||||||
HGDIOBJ hOldOffBmp = 0;
|
{
|
||||||
HBITMAP hTmpBmp = 0, hOffBmp = 0;
|
ERR("DrawIconEx called without mask or color bitmap to draw.\n");
|
||||||
BOOL bAlpha = FALSE;
|
return FALSE;
|
||||||
INT x=xLeft, y=yTop;
|
}
|
||||||
|
|
||||||
hbmMask = pIcon->IconInfo.hbmMask;
|
hbmMask = pIcon->IconInfo.hbmMask;
|
||||||
hbmColor = pIcon->IconInfo.hbmColor;
|
hbmColor = pIcon->IconInfo.hbmColor;
|
||||||
|
@ -1074,44 +1084,50 @@ UserDrawIconEx(
|
||||||
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);
|
||||||
{
|
|
||||||
for (j = 0; j < psurfOff->SurfObj.sizlBitmap.cy; j++)
|
|
||||||
{
|
|
||||||
bAlpha = ((BYTE)(fnSource_GetPixel(&psurfOff->SurfObj, i, j) >> 24) & 0xff);
|
|
||||||
if (bAlpha)
|
if (bAlpha)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1119,64 +1135,147 @@ UserDrawIconEx(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SURFACE_ShareUnlockSurface(psurfOff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Fix width parameter, if needed */
|
||||||
if (!cxWidth)
|
if (!cxWidth)
|
||||||
cxWidth = ((diFlags & DI_DEFAULTSIZE) ?
|
{
|
||||||
UserGetSystemMetrics(SM_CXICON) : pIcon->Size.cx);
|
if(diFlags & DI_DEFAULTSIZE)
|
||||||
|
cxWidth = pIcon->IconInfo.fIcon ?
|
||||||
|
UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR);
|
||||||
|
else
|
||||||
|
cxWidth = pIcon->Size.cx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix height parameter, if needed */
|
||||||
if (!cyHeight)
|
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)
|
cyHeight = pIcon->IconInfo.fIcon ?
|
||||||
{
|
UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR);
|
||||||
ERR("NtGdiCreateCompatibleDC failed!\n");
|
else
|
||||||
Ret = FALSE;
|
cyHeight = pIcon->Size.cy;
|
||||||
goto Cleanup ;
|
|
||||||
}
|
|
||||||
hOffBmp = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight);
|
|
||||||
if(!hOffBmp)
|
|
||||||
{
|
|
||||||
ERR("NtGdiCreateCompatibleBitmap failed!\n");
|
|
||||||
goto Cleanup ;
|
|
||||||
}
|
|
||||||
hOldOffBmp = NtGdiSelectBitmap(hDestDC, hOffBmp);
|
|
||||||
hOldOffBrush = NtGdiSelectBrush(hDestDC, hbrFlickerFreeDraw);
|
|
||||||
NtGdiPatBlt(hDestDC, 0, 0, cxWidth, cyHeight, PATCOPY);
|
|
||||||
NtGdiSelectBrush(hDestDC, hOldOffBrush);
|
|
||||||
x=y=0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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");
|
||||||
|
@ -1198,109 +1297,181 @@ UserDrawIconEx(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SURFACE_ShareUnlockSurface(psurf);
|
/* Initialize color translation object */
|
||||||
|
EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0xFFFFFFFF, 0xFFFFFFFF, 0);
|
||||||
|
|
||||||
hTmpBmp = NtGdiSelectBitmap(hMemDC, hMemBmp);
|
/* Now do it */
|
||||||
|
Ret = IntEngAlphaBlend(&psurfDest->SurfObj,
|
||||||
|
&psurf->SurfObj,
|
||||||
|
pdcClipObj,
|
||||||
|
&exlo.xlo,
|
||||||
|
&rcDest,
|
||||||
|
&rcSrc,
|
||||||
|
&blendobj);
|
||||||
|
|
||||||
|
EXLATEOBJ_vCleanup(&exlo);
|
||||||
|
|
||||||
Ret = NtGdiAlphaBlend(hDestDC,
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
cxWidth,
|
|
||||||
cyHeight,
|
|
||||||
hMemDC,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
pIcon->Size.cx,
|
|
||||||
pIcon->Size.cy,
|
|
||||||
pixelblend,
|
|
||||||
NULL);
|
|
||||||
NtGdiSelectBitmap(hMemDC, hTmpBmp);
|
|
||||||
CleanupAlpha:
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore foreground and background colors */
|
/* Color translation */
|
||||||
IntGdiSetBkColor(hDc, iOldBkColor);
|
EXLATEOBJ_vInitialize(&exlo, psurfOffScreen->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
|
||||||
IntGdiSetTextColor(hDc, iOldTxtColor);
|
|
||||||
|
|
||||||
Ret = TRUE ;
|
/* Blt it! */
|
||||||
|
Ret = IntEngBitBlt(&psurfDest->SurfObj,
|
||||||
|
&psurfOffScreen->SurfObj,
|
||||||
|
NULL,
|
||||||
|
pdcClipObj,
|
||||||
|
&exlo.xlo,
|
||||||
|
&rcDest,
|
||||||
|
&ptSrc,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
ROP4_SRCCOPY);
|
||||||
|
|
||||||
|
EXLATEOBJ_vCleanup(&exlo);
|
||||||
|
}
|
||||||
Cleanup:
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue