* Sync up to trunk head (r65298).

svn path=/branches/shell-experiments/; revision=65299
This commit is contained in:
Amine Khaldi 2014-11-06 19:24:18 +00:00
parent 2060ee5d9c
commit e8103dd4d3
12 changed files with 229 additions and 158 deletions

View file

@ -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;
}

View file

@ -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))
{

View file

@ -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))
{

View file

@ -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,

View file

@ -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
{

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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))
{

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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];