- Fix NtUserCopyAcceleratorTable and NtUserCreateAcceleratorTable (ported from Wine). This is fixed 5 wine resources tests

svn path=/trunk/; revision=38651
This commit is contained in:
Dmitry Chapyshev 2009-01-08 19:35:29 +00:00
parent bc2d37c41a
commit 915dfcf6a7

View file

@ -293,31 +293,39 @@ NtUserCopyAcceleratorTable(
int EntriesCount) int EntriesCount)
{ {
PACCELERATOR_TABLE Accel; PACCELERATOR_TABLE Accel;
NTSTATUS Status;
int Ret; int Ret;
BOOL Done = FALSE;
DECLARE_RETURN(int); DECLARE_RETURN(int);
DPRINT("Enter NtUserCopyAcceleratorTable\n"); DPRINT("Enter NtUserCopyAcceleratorTable\n");
UserEnterShared(); UserEnterShared();
if (!(Accel = UserGetAccelObject(hAccel))) Accel = UserGetAccelObject(hAccel);
if ((Entries && (EntriesCount < 1)) || ((hAccel == NULL) || (!Accel)))
{ {
RETURN(0); RETURN(0);
} }
if (Accel->Count < EntriesCount)
EntriesCount = Accel->Count;
Ret = 0;
while (!Done)
{
if (Entries) if (Entries)
{ {
Ret = min(EntriesCount, Accel->Count); Entries[Ret].fVirt = Accel->Table[Ret].fVirt & 0x7f;
Status = MmCopyToCaller(Entries, Accel->Table, Ret * sizeof(ACCEL)); Entries[Ret].key = Accel->Table[Ret].key;
if (!NT_SUCCESS(Status)) Entries[Ret].cmd = Accel->Table[Ret].cmd;
{
SetLastNtError(Status); if(Ret + 1 == EntriesCount) Done = TRUE;
RETURN(0);
} }
}
else if((Accel->Table[Ret].fVirt & 0x80) != 0) Done = TRUE;
{
Ret = Accel->Count; Ret++;
} }
RETURN(Ret); RETURN(Ret);
@ -335,17 +343,18 @@ NtUserCreateAcceleratorTable(
SIZE_T EntriesCount) SIZE_T EntriesCount)
{ {
PACCELERATOR_TABLE Accel; PACCELERATOR_TABLE Accel;
NTSTATUS Status;
HACCEL hAccel; HACCEL hAccel;
INT Index;
DECLARE_RETURN(HACCEL); DECLARE_RETURN(HACCEL);
DPRINT("Enter NtUserCreateAcceleratorTable(Entries %p, EntriesCount %d)\n", DPRINT("Enter NtUserCreateAcceleratorTable(Entries %p, EntriesCount %d)\n",
Entries, EntriesCount); Entries, EntriesCount);
UserEnterExclusive(); UserEnterExclusive();
if (!Entries || !EntriesCount) if (!Entries || EntriesCount < 1)
{ {
RETURN( (HACCEL) 0 ); SetLastNtError(STATUS_INVALID_PARAMETER);
RETURN( (HACCEL) NULL );
} }
Accel = UserCreateObject(gHandleTable, (PHANDLE)&hAccel, otAccel, sizeof(ACCELERATOR_TABLE)); Accel = UserCreateObject(gHandleTable, (PHANDLE)&hAccel, otAccel, sizeof(ACCELERATOR_TABLE));
@ -353,7 +362,7 @@ NtUserCreateAcceleratorTable(
if (Accel == NULL) if (Accel == NULL)
{ {
SetLastNtError(STATUS_NO_MEMORY); SetLastNtError(STATUS_NO_MEMORY);
RETURN( (HACCEL) 0 ); RETURN( (HACCEL) NULL );
} }
Accel->Count = EntriesCount; Accel->Count = EntriesCount;
@ -365,18 +374,21 @@ NtUserCreateAcceleratorTable(
UserDereferenceObject(Accel); UserDereferenceObject(Accel);
UserDeleteObject(hAccel, otAccel); UserDeleteObject(hAccel, otAccel);
SetLastNtError(STATUS_NO_MEMORY); SetLastNtError(STATUS_NO_MEMORY);
RETURN( (HACCEL) 0); RETURN( (HACCEL) NULL);
} }
Status = MmCopyFromCaller(Accel->Table, Entries, EntriesCount * sizeof(ACCEL)); for (Index = 0; Index < EntriesCount; Index++)
if (!NT_SUCCESS(Status))
{ {
ExFreePoolWithTag(Accel->Table, TAG_ACCEL); Accel->Table[Index].fVirt = Entries[Index].fVirt&0x7f;
UserDereferenceObject(Accel); if(Accel->Table[Index].fVirt & FVIRTKEY)
UserDeleteObject(hAccel, otAccel); {
SetLastNtError(Status); Accel->Table[Index].key = Entries[Index].key;
RETURN((HACCEL) 0);
} }
Accel->Table[Index].cmd = Entries[Index].cmd;
}
/* Set the end-of-table terminator. */
Accel->Table[EntriesCount - 1].fVirt |= 0x80;
} }
/* FIXME: Save HandleTable in a list somewhere so we can clean it up again */ /* FIXME: Save HandleTable in a list somewhere so we can clean it up again */