mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 00:45:24 +00:00
* Sync up to trunk head (r65298).
svn path=/branches/shell-experiments/; revision=65299
This commit is contained in:
parent
2060ee5d9c
commit
e8103dd4d3
12 changed files with 229 additions and 158 deletions
|
@ -565,11 +565,14 @@ VfatCreateFile(
|
|||
LONG idx, FileNameLen;
|
||||
|
||||
ParentFcb = (FileObject->RelatedFileObject != NULL) ? FileObject->RelatedFileObject->FsContext : NULL;
|
||||
Status = vfatGetFCBForFile(DeviceExt, &ParentFcb, &TargetFcb, &PathNameU);
|
||||
|
||||
if (Status == STATUS_SUCCESS)
|
||||
if (ParentFcb)
|
||||
{
|
||||
vfatGrabFCB(DeviceExt, ParentFcb);
|
||||
}
|
||||
Status = vfatGetFCBForFile(DeviceExt, &ParentFcb, &TargetFcb, &PathNameU);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
vfatReleaseFCB(DeviceExt, TargetFcb);
|
||||
Irp->IoStatus.Information = FILE_EXISTS;
|
||||
}
|
||||
|
@ -580,7 +583,7 @@ VfatCreateFile(
|
|||
|
||||
idx = FileObject->FileName.Length / sizeof(WCHAR) - 1;
|
||||
|
||||
/* Skip tailing \ - if any */
|
||||
/* Skip trailing \ - if any */
|
||||
if (PathNameU.Buffer[idx] == L'\\')
|
||||
{
|
||||
--idx;
|
||||
|
@ -623,6 +626,7 @@ VfatCreateFile(
|
|||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
pFcb = FileObject->FsContext;
|
||||
ASSERT(pFcb == ParentFcb);
|
||||
|
||||
if (pFcb->OpenHandleCount == 0)
|
||||
{
|
||||
|
@ -640,7 +644,6 @@ VfatCreateFile(
|
|||
FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
vfatReleaseFCB(DeviceExt, ParentFcb);
|
||||
VfatCloseFile(DeviceExt, FileObject);
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -201,12 +201,6 @@ FATGetNextDirEntry(
|
|||
CcUnpinData(*pContext);
|
||||
}
|
||||
|
||||
if (!pDirFcb->FileObject)
|
||||
{
|
||||
DPRINT1("Buggy FCB (cleaned up)! %S (%d / %u)\n", pDirFcb->PathNameBuffer, pDirFcb->RefCount, pDirFcb->OpenHandleCount);
|
||||
return STATUS_NO_MORE_ENTRIES;
|
||||
}
|
||||
|
||||
if (FileOffset.u.LowPart >= pDirFcb->RFCB.FileSize.u.LowPart ||
|
||||
!CcMapData(pDirFcb->FileObject, &FileOffset, PAGE_SIZE, TRUE, pContext, pPage))
|
||||
{
|
||||
|
|
|
@ -167,11 +167,6 @@ vfatFindDirSpace(
|
|||
{
|
||||
CcUnpinData(Context);
|
||||
}
|
||||
if (!pDirFcb->FileObject)
|
||||
{
|
||||
DPRINT1("Buggy FCB (cleaned up)! %S (%d / %u)\n", pDirFcb->PathNameBuffer, pDirFcb->RefCount, pDirFcb->OpenHandleCount);
|
||||
return FALSE;
|
||||
}
|
||||
if (!CcPinRead(pDirFcb->FileObject, &FileOffset, DeviceExt->FatInfo.BytesPerCluster,
|
||||
TRUE, &Context, (PVOID*)&pFatEntry))
|
||||
{
|
||||
|
|
|
@ -371,6 +371,13 @@ vfatUpdateFCB(
|
|||
|
||||
DPRINT("vfatUpdateFCB(%p, %p, %wZ, %wZ, %p)\n", pVCB, Fcb, LongName, ShortName, ParentFcb);
|
||||
|
||||
/* Get full path name */
|
||||
Status = vfatMakeFullName(ParentFcb, LongName, ShortName, &Fcb->PathNameU);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Delete old name */
|
||||
if (Fcb->PathNameBuffer)
|
||||
{
|
||||
|
@ -380,13 +387,6 @@ vfatUpdateFCB(
|
|||
/* Delete from table */
|
||||
vfatDelFCBFromTable(pVCB, Fcb);
|
||||
|
||||
/* Get full path name */
|
||||
Status = vfatMakeFullName(ParentFcb, LongName, ShortName, &Fcb->PathNameU);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Split it properly */
|
||||
Fcb->PathNameBuffer = Fcb->PathNameU.Buffer;
|
||||
Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
|
||||
|
@ -414,8 +414,8 @@ vfatUpdateFCB(
|
|||
/* Add to the table */
|
||||
vfatAddFCBToTable(pVCB, Fcb);
|
||||
|
||||
/* If we moved accross directories, dereferenced our old parent
|
||||
* We also derefence in case we're just renaming since AddFCBToTable references it
|
||||
/* If we moved across directories, dereference our old parent
|
||||
* We also dereference in case we're just renaming since AddFCBToTable references it
|
||||
*/
|
||||
vfatReleaseFCB(pVCB, OldParent);
|
||||
|
||||
|
@ -887,7 +887,7 @@ vfatGetFCBForFile(
|
|||
if (parentFCB)
|
||||
{
|
||||
vfatReleaseFCB(pVCB, parentFCB);
|
||||
parentFCB = 0;
|
||||
parentFCB = NULL;
|
||||
}
|
||||
// fail if element in FCB is not a directory
|
||||
if (!vfatFCBIsDirectory(FCB))
|
||||
|
@ -910,6 +910,8 @@ vfatGetFCBForFile(
|
|||
if (FileNameU.Length + parentFCB->LongNameU.Length - Length > FileNameU.MaximumLength)
|
||||
{
|
||||
vfatReleaseFCB(pVCB, parentFCB);
|
||||
*pParentFCB = NULL;
|
||||
*pFCB = NULL;
|
||||
return STATUS_OBJECT_NAME_INVALID;
|
||||
}
|
||||
RtlMoveMemory(prev + parentFCB->LongNameU.Length / sizeof(WCHAR), curr,
|
||||
|
|
|
@ -106,6 +106,13 @@ Fast486ReadMemory(PFAST486_STATE State,
|
|||
/* We mustn't prefetch across a page boundary */
|
||||
State->PrefetchAddress = PAGE_ALIGN(State->PrefetchAddress)
|
||||
| (FAST486_PAGE_SIZE - FAST486_CACHE_SIZE);
|
||||
|
||||
if ((LinearAddress - State->PrefetchAddress + Size) >= FAST486_CACHE_SIZE)
|
||||
{
|
||||
/* We can't prefetch without possibly violating page permissions */
|
||||
State->PrefetchValid = FALSE;
|
||||
return Fast486ReadLinearMemory(State, LinearAddress, Buffer, Size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Prefetch */
|
||||
|
@ -546,7 +553,12 @@ Fast486TaskSwitch(PFAST486_STATE State, FAST486_TASK_SWITCH_TYPE Type, USHORT Se
|
|||
|
||||
/* Calculate the limit of the new TSS */
|
||||
NewTssLimit = NewTssDescriptor.Limit | (NewTssDescriptor.LimitHigh << 16);
|
||||
if (NewTssDescriptor.Granularity) NewTssLimit <<= 12;
|
||||
|
||||
if (NewTssDescriptor.Granularity)
|
||||
{
|
||||
NewTssLimit <<= 12;
|
||||
NewTssLimit |= 0x00000FFF;
|
||||
}
|
||||
|
||||
if (NewTssLimit < sizeof(FAST486_TSS))
|
||||
{
|
||||
|
@ -732,7 +744,12 @@ Fast486TaskSwitch(PFAST486_STATE State, FAST486_TASK_SWITCH_TYPE Type, USHORT Se
|
|||
State->Ldtr.Selector = NewTss.Ldtr;
|
||||
State->Ldtr.Base = GdtEntry.Base | (GdtEntry.BaseMid << 16) | (GdtEntry.BaseHigh << 24);
|
||||
State->Ldtr.Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
|
||||
if (GdtEntry.Granularity) State->Ldtr.Limit <<= 12;
|
||||
|
||||
if (GdtEntry.Granularity)
|
||||
{
|
||||
State->Ldtr.Limit <<= 12;
|
||||
State->Ldtr.Limit |= 0x00000FFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -594,16 +594,12 @@ Fast486LoadSegmentInternal(PFAST486_STATE State,
|
|||
{
|
||||
/* Regular code segment */
|
||||
|
||||
if ((GET_SEGMENT_RPL(Selector) > Fast486GetCurrentPrivLevel(State))
|
||||
|| (Fast486GetCurrentPrivLevel(State) != GdtEntry.Dpl))
|
||||
if ((GET_SEGMENT_RPL(Selector) < Fast486GetCurrentPrivLevel(State)))
|
||||
{
|
||||
Fast486ExceptionWithErrorCode(State, Exception, Selector);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update CPL */
|
||||
State->Cpl = GET_SEGMENT_RPL(Selector);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -653,7 +649,11 @@ Fast486LoadSegmentInternal(PFAST486_STATE State,
|
|||
CachedDescriptor->Size = GdtEntry.Size;
|
||||
|
||||
/* Check for page granularity */
|
||||
if (GdtEntry.Granularity) CachedDescriptor->Limit <<= 12;
|
||||
if (GdtEntry.Granularity)
|
||||
{
|
||||
CachedDescriptor->Limit <<= 12;
|
||||
CachedDescriptor->Limit |= 0x00000FFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -730,6 +730,13 @@ Fast486ProcessGate(PFAST486_STATE State, USHORT Selector, ULONG Offset, BOOLEAN
|
|||
|
||||
default:
|
||||
{
|
||||
/* Security check for jumps and calls only */
|
||||
if (State->Cpl != Descriptor.Dpl)
|
||||
{
|
||||
Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -475,7 +475,12 @@ FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLsl)
|
|||
|
||||
/* Calculate the limit */
|
||||
Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
|
||||
if (GdtEntry.Granularity) Limit <<= 12;
|
||||
|
||||
if (GdtEntry.Granularity)
|
||||
{
|
||||
Limit <<= 12;
|
||||
Limit |= 0x00000FFF;
|
||||
}
|
||||
|
||||
/* Set ZF */
|
||||
State->Flags.Zf = TRUE;
|
||||
|
|
|
@ -4474,6 +4474,63 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeRetFar)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) && !State->Flags.Vm)
|
||||
{
|
||||
INT i;
|
||||
INT OldCpl = Fast486GetCurrentPrivLevel(State);
|
||||
ULONG StackPtr;
|
||||
ULONG StackSel;
|
||||
|
||||
if (GET_SEGMENT_RPL(Segment) > OldCpl)
|
||||
{
|
||||
/* Pop ESP */
|
||||
if (!Fast486StackPop(State, &StackPtr))
|
||||
{
|
||||
/* Exception */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pop SS */
|
||||
if (!Fast486StackPop(State, &StackSel))
|
||||
{
|
||||
/* Exception */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the CPL */
|
||||
State->Cpl = GET_SEGMENT_RPL(Segment);
|
||||
|
||||
if (State->Cpl > OldCpl)
|
||||
{
|
||||
/* Load new SS */
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_SS, StackSel))
|
||||
{
|
||||
/* Exception */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set ESP */
|
||||
if (Size) State->GeneralRegs[FAST486_REG_ESP].Long = StackPtr;
|
||||
else State->GeneralRegs[FAST486_REG_ESP].LowWord = LOWORD(StackPtr);
|
||||
|
||||
/* Check segment security */
|
||||
for (i = 0; i < FAST486_NUM_SEG_REGS; i++)
|
||||
{
|
||||
/* Don't check CS or SS */
|
||||
if ((i == FAST486_REG_CS) || (i == FAST486_REG_SS)) continue;
|
||||
|
||||
if ((State->Cpl > State->SegmentRegs[i].Dpl)
|
||||
&& (!State->SegmentRegs[i].Executable
|
||||
|| !State->SegmentRegs[i].DirConf))
|
||||
{
|
||||
/* Load the NULL descriptor in the segment */
|
||||
if (!Fast486LoadSegment(State, i, 0)) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Load new (E)IP, and if necessary, pop the parameters */
|
||||
if (Size)
|
||||
{
|
||||
|
@ -4582,7 +4639,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIret)
|
|||
/* Check for protected mode */
|
||||
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
|
||||
{
|
||||
INT Cpl = Fast486GetCurrentPrivLevel(State);
|
||||
INT OldCpl = Fast486GetCurrentPrivLevel(State);
|
||||
|
||||
if (State->Flags.Vm)
|
||||
{
|
||||
|
@ -4660,7 +4717,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIret)
|
|||
if (Size) State->InstPtr.Long = InstPtr;
|
||||
else State->InstPtr.LowWord = LOWORD(InstPtr);
|
||||
|
||||
if (GET_SEGMENT_RPL(CodeSel) > Cpl)
|
||||
if (GET_SEGMENT_RPL(CodeSel) > OldCpl)
|
||||
{
|
||||
/* Pop ESP */
|
||||
if (!Fast486StackPop(State, &StackPtr))
|
||||
|
@ -4675,7 +4732,22 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIret)
|
|||
/* Exception */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the CPL */
|
||||
State->Cpl = GET_SEGMENT_RPL(CodeSel);
|
||||
|
||||
/* Set the new flags */
|
||||
if (Size) State->Flags.Long = NewFlags.Long & PROT_MODE_FLAGS_MASK;
|
||||
else State->Flags.LowWord = NewFlags.LowWord & PROT_MODE_FLAGS_MASK;
|
||||
State->Flags.AlwaysSet = TRUE;
|
||||
|
||||
/* Set additional flags */
|
||||
if (OldCpl <= State->Flags.Iopl) State->Flags.If = NewFlags.If;
|
||||
if (OldCpl == 0) State->Flags.Iopl = NewFlags.Iopl;
|
||||
|
||||
if (State->Cpl > OldCpl)
|
||||
{
|
||||
/* Load new SS */
|
||||
if (!Fast486LoadSegment(State, FAST486_REG_SS, StackSel))
|
||||
{
|
||||
|
@ -4686,21 +4758,6 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIret)
|
|||
/* Set ESP */
|
||||
if (Size) State->GeneralRegs[FAST486_REG_ESP].Long = StackPtr;
|
||||
else State->GeneralRegs[FAST486_REG_ESP].LowWord = LOWORD(StackPtr);
|
||||
}
|
||||
|
||||
/* Set the new flags */
|
||||
if (Size) State->Flags.Long = NewFlags.Long & PROT_MODE_FLAGS_MASK;
|
||||
else State->Flags.LowWord = NewFlags.LowWord & PROT_MODE_FLAGS_MASK;
|
||||
State->Flags.AlwaysSet = TRUE;
|
||||
|
||||
/* Set additional flags */
|
||||
if (Cpl <= State->Flags.Iopl) State->Flags.If = NewFlags.If;
|
||||
if (Cpl == 0) State->Flags.Iopl = NewFlags.Iopl;
|
||||
|
||||
if (GET_SEGMENT_RPL(CodeSel) > Cpl)
|
||||
{
|
||||
/* Update the CPL */
|
||||
Cpl = Fast486GetCurrentPrivLevel(State);
|
||||
|
||||
/* Check segment security */
|
||||
for (i = 0; i < FAST486_NUM_SEG_REGS; i++)
|
||||
|
@ -4708,7 +4765,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeIret)
|
|||
/* Don't check CS or SS */
|
||||
if ((i == FAST486_REG_CS) || (i == FAST486_REG_SS)) continue;
|
||||
|
||||
if ((Cpl > State->SegmentRegs[i].Dpl)
|
||||
if ((State->Cpl > State->SegmentRegs[i].Dpl)
|
||||
&& (!State->SegmentRegs[i].Executable
|
||||
|| !State->SegmentRegs[i].DirConf))
|
||||
{
|
||||
|
|
|
@ -1804,7 +1804,12 @@ FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0F00)
|
|||
State->Ldtr.Selector = Selector;
|
||||
State->Ldtr.Base = GdtEntry.Base | (GdtEntry.BaseMid << 16) | (GdtEntry.BaseHigh << 24);
|
||||
State->Ldtr.Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
|
||||
if (GdtEntry.Granularity) State->Ldtr.Limit <<= 12;
|
||||
|
||||
if (GdtEntry.Granularity)
|
||||
{
|
||||
State->Ldtr.Limit <<= 12;
|
||||
State->Ldtr.Limit |= 0x00000FFF;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1886,7 +1891,12 @@ FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0F00)
|
|||
State->TaskReg.Selector = Selector;
|
||||
State->TaskReg.Base = GdtEntry.Base | (GdtEntry.BaseMid << 16) | (GdtEntry.BaseHigh << 24);
|
||||
State->TaskReg.Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
|
||||
if (GdtEntry.Granularity) State->TaskReg.Limit <<= 12;
|
||||
|
||||
if (GdtEntry.Granularity)
|
||||
{
|
||||
State->TaskReg.Limit <<= 12;
|
||||
State->TaskReg.Limit |= 0x00000FFF;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1580,8 +1580,8 @@ IopQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
|||
if (OpenPacket.ParseCheck != TRUE)
|
||||
{
|
||||
/* Parse failed */
|
||||
DPRINT1("IopQueryAttributesFile failed for '%wZ' with 0x%lx\n",
|
||||
ObjectAttributes->ObjectName, Status);
|
||||
DPRINT("IopQueryAttributesFile failed for '%wZ' with 0x%lx\n",
|
||||
ObjectAttributes->ObjectName, Status);
|
||||
return Status;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1132,7 +1132,7 @@ NtGdiExtFloodFill(
|
|||
goto cleanup;
|
||||
}
|
||||
else
|
||||
RECTL_vSetRect(&DestRect, 0, psurf->SurfObj.sizlBitmap.cx, 0, psurf->SurfObj.sizlBitmap.cy);
|
||||
RECTL_vSetRect(&DestRect, 0, 0, psurf->SurfObj.sizlBitmap.cx, psurf->SurfObj.sizlBitmap.cy);
|
||||
|
||||
DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ static DWORD USER32_GetResourceTable(LPBYTE peimage,DWORD pesize,LPBYTE *retptr)
|
|||
}
|
||||
if (*((DWORD*)(peimage + mz_header->e_lfanew)) == IMAGE_NT_SIGNATURE )
|
||||
return IMAGE_NT_SIGNATURE;
|
||||
#if 0
|
||||
#ifdef WINE
|
||||
if (*((WORD*)(peimage + mz_header->e_lfanew)) == IMAGE_OS2_SIGNATURE )
|
||||
{
|
||||
IMAGE_OS2_HEADER * ne_header;
|
||||
|
@ -132,7 +132,7 @@ static DWORD USER32_GetResourceTable(LPBYTE peimage,DWORD pesize,LPBYTE *retptr)
|
|||
#endif
|
||||
return 0; /* failed */
|
||||
}
|
||||
#if 0
|
||||
#ifdef WINE
|
||||
/*************************************************************************
|
||||
* USER32_LoadResource
|
||||
*/
|
||||
|
@ -160,9 +160,6 @@ static BYTE * ICO_LoadIcon( LPBYTE peimage, LPicoICONDIRENTRY lpiIDE, ULONG *uSi
|
|||
*
|
||||
* Reads .ico file and build phony ICONDIR struct
|
||||
*/
|
||||
#define HEADER_SIZE (sizeof(CURSORICONDIR) - sizeof (CURSORICONDIRENTRY))
|
||||
#define HEADER_SIZE_FILE (sizeof(icoICONDIR) - sizeof (icoICONDIRENTRY))
|
||||
|
||||
static BYTE * ICO_GetIconDirectory( LPBYTE peimage, LPicoICONDIR* lplpiID, ULONG *uSize )
|
||||
{
|
||||
CURSORICONDIR * lpcid; /* icon resource in resource-dir format */
|
||||
|
@ -177,7 +174,7 @@ static BYTE * ICO_GetIconDirectory( LPBYTE peimage, LPicoICONDIR* lplpiID, ULONG
|
|||
return 0;
|
||||
|
||||
/* allocate the phony ICONDIR structure */
|
||||
*uSize = lpcid->idCount * sizeof(CURSORICONDIRENTRY) + HEADER_SIZE;
|
||||
*uSize = FIELD_OFFSET(CURSORICONDIR, idEntries[lpcid->idCount]);
|
||||
if( (lpID = HeapAlloc(GetProcessHeap(),0, *uSize) ))
|
||||
{
|
||||
/* copy the header */
|
||||
|
@ -188,7 +185,7 @@ static BYTE * ICO_GetIconDirectory( LPBYTE peimage, LPicoICONDIR* lplpiID, ULONG
|
|||
/* copy the entries */
|
||||
for( i=0; i < lpcid->idCount; i++ )
|
||||
{
|
||||
memcpy(&lpID->idEntries[i], &lpcid->idEntries[i], sizeof(CURSORICONDIRENTRY) - 2);
|
||||
memcpy(&lpID->idEntries[i], &lpcid->idEntries[i], sizeof(CURSORICONDIRENTRY) - 2);
|
||||
lpID->idEntries[i].wResId = i;
|
||||
}
|
||||
|
||||
|
@ -224,7 +221,7 @@ static UINT ICO_ExtractIconExW(
|
|||
LPBYTE pData;
|
||||
DWORD sig;
|
||||
HANDLE hFile;
|
||||
UINT16 iconDirCount = 0; //,iconCount = 0;
|
||||
UINT16 iconDirCount = 0, iconCount = 0;
|
||||
LPBYTE peimage;
|
||||
HANDLE fmapping;
|
||||
DWORD fsizeh,fsizel;
|
||||
|
@ -274,8 +271,8 @@ static UINT ICO_ExtractIconExW(
|
|||
|
||||
sig = USER32_GetResourceTable(peimage, fsizel, &pData);
|
||||
|
||||
#ifdef WINE
|
||||
/* ico file or NE exe/dll*/
|
||||
#if 0
|
||||
if (sig==IMAGE_OS2_SIGNATURE || sig==1) /* .ICO file */
|
||||
{
|
||||
BYTE *pCIDir = 0;
|
||||
|
@ -283,8 +280,9 @@ static UINT ICO_ExtractIconExW(
|
|||
NE_NAMEINFO *pIconStorage = NULL;
|
||||
NE_NAMEINFO *pIconDir = NULL;
|
||||
LPicoICONDIR lpiID = NULL;
|
||||
ULONG uSize = 0;
|
||||
|
||||
TRACE("-- OS2/icon Signature (0x%08lx)\n", sig);
|
||||
TRACE("-- OS2/icon Signature (0x%08x)\n", sig);
|
||||
|
||||
if (pData == (BYTE*)-1)
|
||||
{
|
||||
|
@ -292,7 +290,7 @@ static UINT ICO_ExtractIconExW(
|
|||
if (pCIDir)
|
||||
{
|
||||
iconDirCount = 1; iconCount = lpiID->idCount;
|
||||
TRACE("-- icon found %p 0x%08lx 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount);
|
||||
TRACE("-- icon found %p 0x%08x 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount);
|
||||
}
|
||||
}
|
||||
else while (pTInfo->type_id && !(pIconStorage && pIconDir))
|
||||
|
@ -317,7 +315,7 @@ static UINT ICO_ExtractIconExW(
|
|||
if (nIcons == 0)
|
||||
{
|
||||
ret = iconDirCount;
|
||||
if (lpiID && pCIDir) /* *.ico file, deallocate heap pointer*/
|
||||
if (lpiID) /* *.ico file, deallocate heap pointer*/
|
||||
HeapFree(GetProcessHeap(), 0, pCIDir);
|
||||
}
|
||||
else if (nIconIndex < iconDirCount)
|
||||
|
@ -331,9 +329,10 @@ static UINT ICO_ExtractIconExW(
|
|||
/* .ICO files have only one icon directory */
|
||||
if (lpiID == NULL) /* not *.ico */
|
||||
pCIDir = USER32_LoadResource(peimage, pIconDir + i + nIconIndex, *(WORD*)pData, &uSize);
|
||||
pIconId[i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, (i & 1) ? cx2 : cx1, (i & 1) ? cy2 : cy1, flags);
|
||||
pIconId[i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, cx1, cy1, flags);
|
||||
if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, cx2, cy2, flags);
|
||||
}
|
||||
if (lpiID && pCIDir) /* *.ico file, deallocate heap pointer*/
|
||||
if (lpiID) /* *.ico file, deallocate heap pointer*/
|
||||
HeapFree(GetProcessHeap(), 0, pCIDir);
|
||||
|
||||
for (icon = 0; icon < nIcons; icon++)
|
||||
|
@ -347,8 +346,13 @@ static UINT ICO_ExtractIconExW(
|
|||
pCIDir = USER32_LoadResource(peimage, pIconStorage + i, *(WORD*)pData, &uSize);
|
||||
|
||||
if (pCIDir)
|
||||
RetPtr[icon] = (HICON)CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000,
|
||||
(icon & 1) ? cx2 : cx1, (icon & 1) ? cy2 : cy1, flags);
|
||||
{
|
||||
RetPtr[icon] = CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000,
|
||||
cx1, cy1, flags);
|
||||
if (cx2 && cy2)
|
||||
RetPtr[++icon] = CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000,
|
||||
cx2, cy2, flags);
|
||||
}
|
||||
else
|
||||
RetPtr[icon] = 0;
|
||||
}
|
||||
|
@ -356,54 +360,62 @@ static UINT ICO_ExtractIconExW(
|
|||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (sig == 1) /* .ICO file */
|
||||
{
|
||||
TRACE("-- icon Signature (0x%08x)\n", sig);
|
||||
|
||||
if (pData == (BYTE*)-1)
|
||||
{
|
||||
INT dataOffset;
|
||||
LPICONIMAGE entry;
|
||||
CURSORICONDIR *lpcid = (CURSORICONDIR*)peimage;
|
||||
INT cx[2] = {cx1, cx2}, cy[2] = {cy1, cy2};
|
||||
INT index;
|
||||
|
||||
if (lpcid->idType != 1)
|
||||
return 0;
|
||||
|
||||
for(index = 0; index < 2; index++)
|
||||
{
|
||||
dataOffset = LookupIconIdFromDirectoryEx(peimage, TRUE, cx[index], cy[index], flags);
|
||||
|
||||
if (dataOffset)
|
||||
{
|
||||
HICON icon;
|
||||
entry = (LPICONIMAGE)(peimage + dataOffset);
|
||||
icon = CreateIconFromResourceEx(peimage + dataOffset, entry->icHeader.biSizeImage, TRUE, 0x00030000, cx[index], cy[index], flags);
|
||||
|
||||
if (icon)
|
||||
{
|
||||
RetPtr[index] = icon;
|
||||
iconCount = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ret = iconCount; /* return number of retrieved icons */
|
||||
}
|
||||
#endif
|
||||
/* end ico file */
|
||||
|
||||
/* exe/dll */
|
||||
else if( sig == IMAGE_NT_SIGNATURE )
|
||||
#endif
|
||||
if( sig == IMAGE_NT_SIGNATURE )
|
||||
{
|
||||
LPBYTE idata,igdata;
|
||||
PIMAGE_DOS_HEADER dheader;
|
||||
PIMAGE_NT_HEADERS pe_header;
|
||||
PIMAGE_SECTION_HEADER pe_sections;
|
||||
const IMAGE_RESOURCE_DIRECTORY *rootresdir,*iconresdir,*icongroupresdir;
|
||||
const IMAGE_RESOURCE_DATA_ENTRY *idataent,*igdataent;
|
||||
const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent;
|
||||
UINT i, j;
|
||||
BYTE *idata, *igdata;
|
||||
const IMAGE_RESOURCE_DIRECTORY *rootresdir, *iconresdir, *icongroupresdir;
|
||||
const IMAGE_RESOURCE_DATA_ENTRY *idataent, *igdataent;
|
||||
const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent;
|
||||
ULONG size;
|
||||
UINT i;
|
||||
|
||||
dheader = (PIMAGE_DOS_HEADER)peimage;
|
||||
pe_header = (PIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew); /* it is a pe header, USER32_GetResourceTable checked that */
|
||||
pe_sections = (PIMAGE_SECTION_HEADER)(((char*)pe_header) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER)
|
||||
+ pe_header->FileHeader.SizeOfOptionalHeader);
|
||||
rootresdir = NULL;
|
||||
|
||||
/* search for the root resource directory */
|
||||
for (i=0;i<pe_header->FileHeader.NumberOfSections;i++)
|
||||
{
|
||||
if (pe_sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
|
||||
continue;
|
||||
if (fsizel < pe_sections[i].PointerToRawData+pe_sections[i].SizeOfRawData) {
|
||||
FIXME("File %s too short (section is at %ld bytes, real size is %ld)\n",
|
||||
debugstr_w(lpszExeFileName),
|
||||
pe_sections[i].PointerToRawData+pe_sections[i].SizeOfRawData,
|
||||
fsizel
|
||||
);
|
||||
goto end;
|
||||
}
|
||||
/* FIXME: doesn't work when the resources are not in a separate section */
|
||||
if (pe_sections[i].VirtualAddress == pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress)
|
||||
{
|
||||
rootresdir = (PIMAGE_RESOURCE_DIRECTORY)(peimage+pe_sections[i].PointerToRawData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rootresdir)
|
||||
{
|
||||
WARN("haven't found section for resource directory.\n");
|
||||
goto end; /* failure */
|
||||
}
|
||||
rootresdir = RtlImageDirectoryEntryToData((HMODULE)peimage, FALSE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size);
|
||||
if (!rootresdir)
|
||||
{
|
||||
WARN("haven't found section for resource directory.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* search for the group icon directory */
|
||||
if (!(icongroupresdir = find_entry_by_id(rootresdir, LOWORD(RT_GROUP_ICON), rootresdir)))
|
||||
|
@ -465,37 +477,21 @@ static UINT ICO_ExtractIconExW(
|
|||
const IMAGE_RESOURCE_DIRECTORY *resdir;
|
||||
|
||||
/* go down this resource entry, name */
|
||||
resdir = (const IMAGE_RESOURCE_DIRECTORY*)((const char *)rootresdir+(xresent->OffsetToDirectory));
|
||||
resdir = (const IMAGE_RESOURCE_DIRECTORY *)((const char *)rootresdir + xresent->OffsetToDirectory);
|
||||
|
||||
/* default language (0) */
|
||||
resdir = find_entry_default(resdir,rootresdir);
|
||||
igdataent = (const IMAGE_RESOURCE_DATA_ENTRY*)resdir;
|
||||
|
||||
/* lookup address in mapped image for virtual address */
|
||||
igdata = NULL;
|
||||
|
||||
for (j=0;j<pe_header->FileHeader.NumberOfSections;j++)
|
||||
{
|
||||
if (igdataent->OffsetToData < pe_sections[j].VirtualAddress)
|
||||
continue;
|
||||
if (igdataent->OffsetToData+igdataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData)
|
||||
continue;
|
||||
|
||||
if (igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData+igdataent->Size > fsizel) {
|
||||
FIXME("overflow in PE lookup (%s has len %ld, have offset %ld), short file?\n", debugstr_w(lpszExeFileName), fsizel,
|
||||
igdataent->OffsetToData - pe_sections[j].VirtualAddress + pe_sections[j].PointerToRawData + igdataent->Size);
|
||||
goto end; /* failure */
|
||||
}
|
||||
igdata = peimage+(igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData);
|
||||
}
|
||||
|
||||
if (!igdata)
|
||||
igdata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, igdataent->OffsetToData, NULL);
|
||||
if (!igdata)
|
||||
{
|
||||
FIXME("no matching real address for icongroup!\n");
|
||||
goto end; /* failure */
|
||||
}
|
||||
pIconId[i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx1, cy1, flags);
|
||||
if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx2, cy2, flags);
|
||||
if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx2, cy2, flags);
|
||||
}
|
||||
|
||||
if (!(iconresdir=find_entry_by_id(rootresdir,LOWORD(RT_ICON),rootresdir)))
|
||||
|
@ -508,32 +504,17 @@ static UINT ICO_ExtractIconExW(
|
|||
{
|
||||
const IMAGE_RESOURCE_DIRECTORY *xresdir;
|
||||
xresdir = find_entry_by_id(iconresdir, LOWORD(pIconId[i]), rootresdir);
|
||||
if (!xresdir)
|
||||
{
|
||||
WARN("icon entry %d not found\n", LOWORD(pIconId[i]));
|
||||
if( !xresdir )
|
||||
{
|
||||
WARN("icon entry %d not found\n", LOWORD(pIconId[i]));
|
||||
RetPtr[i]=0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
xresdir = find_entry_default(xresdir, rootresdir);
|
||||
if (!xresdir)
|
||||
{
|
||||
WARN("icon entry %d not found\n", LOWORD(pIconId[i]));
|
||||
RetPtr[i]=0;
|
||||
continue;
|
||||
}
|
||||
idataent = (const IMAGE_RESOURCE_DATA_ENTRY*)xresdir;
|
||||
idata = NULL;
|
||||
|
||||
/* map virtual to address in image */
|
||||
for (j=0;j<pe_header->FileHeader.NumberOfSections;j++)
|
||||
{
|
||||
if (idataent->OffsetToData < pe_sections[j].VirtualAddress)
|
||||
continue;
|
||||
if (idataent->OffsetToData+idataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData)
|
||||
continue;
|
||||
idata = peimage+(idataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData);
|
||||
}
|
||||
if (!idata)
|
||||
idata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, idataent->OffsetToData, NULL);
|
||||
if (!idata)
|
||||
{
|
||||
WARN("no matching real address found for icondata!\n");
|
||||
RetPtr[i]=0;
|
||||
|
@ -644,7 +625,7 @@ UINT WINAPI PrivateExtractIconExW (
|
|||
cxsmicon = GetSystemMetrics(SM_CXSMICON);
|
||||
cysmicon = GetSystemMetrics(SM_CYSMICON);
|
||||
|
||||
ret = ICO_ExtractIconExW(lpwstrFile, hIcon, nIndex, 2, cxicon | (cxsmicon<<16),
|
||||
ret = ICO_ExtractIconExW(lpwstrFile, hIcon, nIndex, 2, cxicon | (cxsmicon<<16),
|
||||
cyicon | (cysmicon<<16), NULL, LR_DEFAULTCOLOR);
|
||||
*phIconLarge = hIcon[0];
|
||||
*phIconSmall = hIcon[1];
|
||||
|
|
Loading…
Reference in a new issue