Author: akhaldi Date: Thu Nov 6 19:24:18 2014 New Revision: 65299
URL: http://svn.reactos.org/svn/reactos?rev=65299&view=rev Log: * Sync up to trunk head (r65298).
Modified: branches/shell-experiments/ (props changed) branches/shell-experiments/drivers/filesystems/fastfat/create.c branches/shell-experiments/drivers/filesystems/fastfat/direntry.c branches/shell-experiments/drivers/filesystems/fastfat/dirwr.c branches/shell-experiments/drivers/filesystems/fastfat/fcb.c branches/shell-experiments/lib/fast486/common.c branches/shell-experiments/lib/fast486/common.inl branches/shell-experiments/lib/fast486/extraops.c branches/shell-experiments/lib/fast486/opcodes.c branches/shell-experiments/lib/fast486/opgroups.c branches/shell-experiments/ntoskrnl/io/iomgr/file.c branches/shell-experiments/win32ss/gdi/ntgdi/fillshap.c branches/shell-experiments/win32ss/user/user32/misc/exticon.c
Propchange: branches/shell-experiments/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Thu Nov 6 19:24:18 2014 @@ -19,4 +19,4 @@ /branches/usb-bringup:51335,51337,51341-51343,51348,51350,51353,51355,51365-51369,51372,51384-54388,54396-54398,54736-54737,54752-54754,54756-54760,54762,54764-54765,54767-54768,54772,54774-54777,54781,54787,54790-54792,54797-54798,54806,54808,54834-54838,54843,54850,54852,54856,54858-54859 /branches/usb-bringup-trunk:55019-55543,55548-55554,55556-55567 /branches/wlan-bringup:54809-54998 -/trunk/reactos:61927-65270 +/trunk/reactos:61927-65298
Modified: branches/shell-experiments/drivers/filesystems/fastfat/create.c URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/drivers/filesy... ============================================================================== --- branches/shell-experiments/drivers/filesystems/fastfat/create.c [iso-8859-1] (original) +++ branches/shell-experiments/drivers/filesystems/fastfat/create.c [iso-8859-1] Thu Nov 6 19:24:18 2014 @@ -565,11 +565,14 @@ LONG idx, FileNameLen;
ParentFcb = (FileObject->RelatedFileObject != NULL) ? FileObject->RelatedFileObject->FsContext : NULL; + if (ParentFcb) + { + vfatGrabFCB(DeviceExt, ParentFcb); + } Status = vfatGetFCBForFile(DeviceExt, &ParentFcb, &TargetFcb, &PathNameU);
- if (Status == STATUS_SUCCESS) - { - vfatGrabFCB(DeviceExt, ParentFcb); + if (NT_SUCCESS(Status)) + { vfatReleaseFCB(DeviceExt, TargetFcb); Irp->IoStatus.Information = FILE_EXISTS; } @@ -580,7 +583,7 @@
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 @@ if (NT_SUCCESS(Status)) { pFcb = FileObject->FsContext; + ASSERT(pFcb == ParentFcb);
if (pFcb->OpenHandleCount == 0) { @@ -640,7 +644,6 @@ FALSE); if (!NT_SUCCESS(Status)) { - vfatReleaseFCB(DeviceExt, ParentFcb); VfatCloseFile(DeviceExt, FileObject); return Status; }
Modified: branches/shell-experiments/drivers/filesystems/fastfat/direntry.c URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/drivers/filesy... ============================================================================== --- branches/shell-experiments/drivers/filesystems/fastfat/direntry.c [iso-8859-1] (original) +++ branches/shell-experiments/drivers/filesystems/fastfat/direntry.c [iso-8859-1] Thu Nov 6 19:24:18 2014 @@ -201,12 +201,6 @@ 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)) {
Modified: branches/shell-experiments/drivers/filesystems/fastfat/dirwr.c URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/drivers/filesy... ============================================================================== --- branches/shell-experiments/drivers/filesystems/fastfat/dirwr.c [iso-8859-1] (original) +++ branches/shell-experiments/drivers/filesystems/fastfat/dirwr.c [iso-8859-1] Thu Nov 6 19:24:18 2014 @@ -166,11 +166,6 @@ if (Context) { 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))
Modified: branches/shell-experiments/drivers/filesystems/fastfat/fcb.c URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/drivers/filesy... ============================================================================== --- branches/shell-experiments/drivers/filesystems/fastfat/fcb.c [iso-8859-1] (original) +++ branches/shell-experiments/drivers/filesystems/fastfat/fcb.c [iso-8859-1] Thu Nov 6 19:24:18 2014 @@ -371,21 +371,21 @@
DPRINT("vfatUpdateFCB(%p, %p, %wZ, %wZ, %p)\n", pVCB, Fcb, LongName, ShortName, ParentFcb);
- /* Delete old name */ - if (Fcb->PathNameBuffer) - { - ExFreePoolWithTag(Fcb->PathNameBuffer, TAG_FCB); - } - - /* Delete from table */ - vfatDelFCBFromTable(pVCB, Fcb); - /* Get full path name */ Status = vfatMakeFullName(ParentFcb, LongName, ShortName, &Fcb->PathNameU); if (!NT_SUCCESS(Status)) { return Status; } + + /* Delete old name */ + if (Fcb->PathNameBuffer) + { + ExFreePoolWithTag(Fcb->PathNameBuffer, TAG_FCB); + } + + /* Delete from table */ + vfatDelFCBFromTable(pVCB, Fcb);
/* Split it properly */ Fcb->PathNameBuffer = Fcb->PathNameU.Buffer; @@ -414,8 +414,8 @@ /* 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 @@ 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 @@ 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,
Modified: branches/shell-experiments/lib/fast486/common.c URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/lib/fast486/co... ============================================================================== --- branches/shell-experiments/lib/fast486/common.c [iso-8859-1] (original) +++ branches/shell-experiments/lib/fast486/common.c [iso-8859-1] Thu Nov 6 19:24:18 2014 @@ -106,6 +106,13 @@ /* 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 @@
/* 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 @@ 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 {
Modified: branches/shell-experiments/lib/fast486/common.inl URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/lib/fast486/co... ============================================================================== --- branches/shell-experiments/lib/fast486/common.inl [iso-8859-1] (original) +++ branches/shell-experiments/lib/fast486/common.inl [iso-8859-1] Thu Nov 6 19:24:18 2014 @@ -594,16 +594,12 @@ { /* 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 @@ 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 @@
default: { + /* Security check for jumps and calls only */ + if (State->Cpl != Descriptor.Dpl) + { + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); + return FALSE; + } + return TRUE; } }
Modified: branches/shell-experiments/lib/fast486/extraops.c URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/lib/fast486/ex... ============================================================================== --- branches/shell-experiments/lib/fast486/extraops.c [iso-8859-1] (original) +++ branches/shell-experiments/lib/fast486/extraops.c [iso-8859-1] Thu Nov 6 19:24:18 2014 @@ -475,7 +475,12 @@
/* 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;
Modified: branches/shell-experiments/lib/fast486/opcodes.c URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/lib/fast486/op... ============================================================================== --- branches/shell-experiments/lib/fast486/opcodes.c [iso-8859-1] (original) +++ branches/shell-experiments/lib/fast486/opcodes.c [iso-8859-1] Thu Nov 6 19:24:18 2014 @@ -4474,6 +4474,63 @@ 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 @@ /* 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 @@ 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 @@ /* 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 @@ /* 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 @@ /* 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)) {
Modified: branches/shell-experiments/lib/fast486/opgroups.c URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/lib/fast486/op... ============================================================================== --- branches/shell-experiments/lib/fast486/opgroups.c [iso-8859-1] (original) +++ branches/shell-experiments/lib/fast486/opgroups.c [iso-8859-1] Thu Nov 6 19:24:18 2014 @@ -1804,7 +1804,12 @@ 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 @@ 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; }
Modified: branches/shell-experiments/ntoskrnl/io/iomgr/file.c URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/ntoskrnl/io/io... ============================================================================== --- branches/shell-experiments/ntoskrnl/io/iomgr/file.c [iso-8859-1] (original) +++ branches/shell-experiments/ntoskrnl/io/iomgr/file.c [iso-8859-1] Thu Nov 6 19:24:18 2014 @@ -1580,8 +1580,8 @@ 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
Modified: branches/shell-experiments/win32ss/gdi/ntgdi/fillshap.c URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/win32ss/gdi/nt... ============================================================================== --- branches/shell-experiments/win32ss/gdi/ntgdi/fillshap.c [iso-8859-1] (original) +++ branches/shell-experiments/win32ss/gdi/ntgdi/fillshap.c [iso-8859-1] Thu Nov 6 19:24:18 2014 @@ -1132,7 +1132,7 @@ 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);
Modified: branches/shell-experiments/win32ss/user/user32/misc/exticon.c URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/win32ss/user/u... ============================================================================== --- branches/shell-experiments/win32ss/user/user32/misc/exticon.c [iso-8859-1] (original) +++ branches/shell-experiments/win32ss/user/user32/misc/exticon.c [iso-8859-1] Thu Nov 6 19:24:18 2014 @@ -112,7 +112,7 @@ } 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 @@ #endif return 0; /* failed */ } -#if 0 +#ifdef WINE /************************************************************************* * USER32_LoadResource */ @@ -160,9 +160,6 @@ * * 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 @@ 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 @@ /* 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 @@ 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 @@
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 @@ NE_NAMEINFO *pIconStorage = NULL; NE_NAMEINFO *pIconDir = NULL; LPicoICONDIR lpiID = NULL; - - TRACE("-- OS2/icon Signature (0x%08lx)\n", sig); + ULONG uSize = 0; + + TRACE("-- OS2/icon Signature (0x%08x)\n", sig);
if (pData == (BYTE*)-1) { @@ -292,7 +290,7 @@ 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 @@ 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 @@ /* .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 @@ 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 @@ } } } +#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; - - 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 */ - } + { + 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; + + 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 @@ 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 @@ { 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 @@ 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];