user32:PrivateExtractIcons{AW} take 2

Rolf Kalbermatter rolf.kalbermatter at citeng.com
Tue Dec 3 05:11:05 CST 2002


I'm sorry for having sent earlier patches which seemed to be garbled with line
breaks. I'll try again and hope they come through ok this time, otherwise I
probably have to find a new email client ;-)

ChangeLog:
 * dlls/user/exticon.c
   - Modify PrivateExtraxtIcons{AW} to match better current MDSN documentation

 * include/winuser.h
   - Modify PrivateExtraxtIcons{AW} to match better current MDSN documentation

 * dlls/user/user32.spec
   - Modify parameter types for PrivateExtraxtIcons{AW} to the actual types

License: X11/LGPL
 
Index: dlls/user/exticon.c
===================================================================
RCS file: /home/wine/wine/dlls/user/exticon.c,v
retrieving revision 1.22
diff -u -r1.22 exticon.c
--- dlls/user/exticon.c	28 Oct 2002 20:11:40 -0000	1.22
+++ dlls/user/exticon.c	3 Dec 2002 09:55:05 -0000
@@ -240,17 +240,19 @@
  *  nIcons = 0: returns number of Icons in file
  *
  * returns
- *  failure:0; success: icon handle or nr of icons (nIconIndex-1)
+ *  failure:0; success: number of icons in file (nIcons = 0) or nr of icons retrieved
  */
-static HRESULT ICO_ExtractIconExW(
+static UINT ICO_ExtractIconExW(
 	LPCWSTR lpszExeFileName,
 	HICON * RetPtr,
 	INT nIconIndex,
 	UINT nIcons,
 	UINT cxDesired,
-	UINT cyDesired )
+	UINT cyDesired,
+	UINT *pIconId,
+	UINT flags)
 {
-	HRESULT		hRet = E_FAIL;
+	UINT		ret = 0;
 	LPBYTE		pData;
 	DWORD		sig;
 	HANDLE		hFile;
@@ -260,28 +262,28 @@
 	ULONG		uSize;
 	DWORD		fsizeh,fsizel;
 
-	TRACE("(file %s,start %d,extract %d\n", debugstr_w(lpszExeFileName), nIconIndex, nIcons);
+	TRACE("%s, %d, %d %p 0x%08x\n", debugstr_w(lpszExeFileName), nIconIndex, nIcons, pIconId, flags);
 
 	hFile = CreateFileW( lpszExeFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
-	if (hFile == INVALID_HANDLE_VALUE) return hRet;
+	if (hFile == INVALID_HANDLE_VALUE) return ret;
 	fsizel = GetFileSize(hFile,&fsizeh);
 
 	/* Map the file */
-	fmapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
-        CloseHandle( hFile );
+	fmapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
+	CloseHandle( hFile );
 	if (!fmapping)
 	{
 	  WARN("CreateFileMapping error %ld\n", GetLastError() );
-	  return hRet;
+	  return ret;
 	}
 
 	if ( !(peimage = MapViewOfFile(fmapping,FILE_MAP_READ,0,0,0)))
 	{
 	  WARN("MapViewOfFile error %ld\n", GetLastError() );
           CloseHandle( fmapping );
-	  return hRet;
+	  return ret;
 	}
-        CloseHandle( fmapping );
+	CloseHandle( fmapping );
 
 	sig = USER32_GetResourceTable(peimage,fsizel,&pData);
 
@@ -327,7 +329,7 @@
 	  {
 	    if( nIcons == 0 )
 	    {
-	      hRet = iconDirCount;
+	      ret = iconDirCount;
 	    }
 	    else if( nIconIndex < iconDirCount )
 	    {
@@ -340,7 +342,7 @@
 	        /* .ICO files have only one icon directory */
 	        if( lpiID == NULL )	/* *.ico */
 	          pCIDir = USER32_LoadResource( peimage, pIconDir + i, *(WORD*)pData, &uSize );
-	        RetPtr[i-nIconIndex] = (HICON)LookupIconIdFromDirectoryEx( pCIDir, TRUE, cxDesired, cyDesired, 0);
+	        RetPtr[i-nIconIndex] = (HICON)LookupIconIdFromDirectoryEx( pCIDir, TRUE, cxDesired, cyDesired, flags );
 	      }
 
 	      for( icon = nIconIndex; icon < nIconIndex + nIcons; icon++ )
@@ -349,16 +351,16 @@
 	        if( lpiID )
 	          pCIDir = ICO_LoadIcon( peimage, lpiID->idEntries + (int)RetPtr[icon-nIconIndex], &uSize);
 	        else
-		  for( i = 0; i < iconCount; i++ )
-		    if( pIconStorage[i].id == ((int)RetPtr[icon-nIconIndex] | 0x8000) )
-		      pCIDir = USER32_LoadResource( peimage, pIconStorage + i,*(WORD*)pData, &uSize );
+	          for ( i = 0; i < iconCount; i++ )
+	            if ( pIconStorage[i].id == ((int)RetPtr[icon-nIconIndex] | 0x8000) )
+	              pCIDir = USER32_LoadResource( peimage, pIconStorage + i,*(WORD*)pData, &uSize );
 
 	        if( pCIDir )
-		  RetPtr[icon-nIconIndex] = (HICON) CreateIconFromResourceEx(pCIDir,uSize,TRUE,0x00030000, cxDesired, cyDesired, LR_DEFAULTCOLOR);
+	          RetPtr[icon - nIconIndex] = (HICON)CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000, cxDesired, cyDesired, flags);
 	        else
-		  RetPtr[icon-nIconIndex] = 0;
+	          RetPtr[icon - nIconIndex] = 0;
 	      }
-	      hRet = S_OK;
+	      ret = icon - nIconIndex;	/* return number of retrieved icons */
 	    }
 	  }
 	}
@@ -419,7 +421,7 @@
 	  /* only number of icons requested */
 	  if( nIcons == 0 )
 	  {
-	    hRet = iconDirCount;
+	    ret = iconDirCount;
 	    goto end;		/* success */
 	  }
 
@@ -482,11 +484,12 @@
 	      if (igdataent->OffsetToData < pe_sections[j].VirtualAddress)
 	        continue;
 	      if (igdataent->OffsetToData+igdataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData)
-		continue;
+	        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 */
+	        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);
 	    }
@@ -496,9 +499,12 @@
 	      FIXME("no matching real address for icongroup!\n");
 	      goto end;	/* failure */
 	    }
-	    RetPtr[i] = (HICON)LookupIconIdFromDirectoryEx(igdata, TRUE, cxDesired, cyDesired, LR_DEFAULTCOLOR);
+	    RetPtr[i] = (HICON)LookupIconIdFromDirectoryEx(igdata, TRUE, cxDesired, cyDesired, flags);
 	  }
 
+	  if (pIconId)
+	  	*pIconId = LOWORD(*RetPtr);
+	  	 
 	  if (!(iconresdir=find_entry_by_id(rootresdir,LOWORD(RT_ICONW),rootresdir)))
 	  {
 	    WARN("No Iconresourcedirectory!\n");
@@ -507,9 +513,9 @@
 
 	  for (i=0; i<nIcons; i++)
 	  {
-              const IMAGE_RESOURCE_DIRECTORY *xresdir;
-              xresdir = find_entry_by_id(iconresdir,LOWORD(RetPtr[i]),rootresdir);
-              xresdir = find_entry_default(xresdir,rootresdir);
+        const IMAGE_RESOURCE_DIRECTORY *xresdir;
+        xresdir = find_entry_by_id(iconresdir,LOWORD(RetPtr[i]),rootresdir);
+        xresdir = find_entry_default(xresdir,rootresdir);
 	    idataent = (PIMAGE_RESOURCE_DATA_ENTRY)xresdir;
 	    idata = NULL;
 
@@ -528,13 +534,14 @@
 	      RetPtr[i]=0;
 	      continue;
 	    }
-	    RetPtr[i] = (HICON) CreateIconFromResourceEx(idata,idataent->Size,TRUE,0x00030000, cxDesired, cyDesired, LR_DEFAULTCOLOR);
+	    RetPtr[i] = (HICON) CreateIconFromResourceEx(idata,idataent->Size,TRUE,0x00030000, cxDesired, cyDesired, flags);
 	  }
-	  hRet = S_OK;	/* return first icon */
+	  ret = i;	/* return number of retrieved icons */
 	}			/* if(sig == IMAGE_NT_SIGNATURE) */
 
-end:	UnmapViewOfFile(peimage);	/* success */
-	return hRet;
+end:
+	UnmapViewOfFile(peimage);	/* success */
+	return ret;
 }
 
 /***********************************************************************
@@ -545,60 +552,75 @@
  *  the higher word of sizeXY contains the size of the small icon, the lower
  *  word the size of the big icon. phicon points to HICON[2].
  *
- * RETURNS
- *  nIcons > 0: HRESULT
- *  nIcons = 0: the number of icons
+ * FIXME:
+ * 1) should also support 16 bit EXE + DLLs, cursor and animated cursor as well
+ *    as bitmap files.
+ * 2) should return according to MSDN
+ *  phicons == NULL	: the number of icons in file or 0 on error
+ *  phicons != NULL	: the number of icons extracted or 0xFFFFFFFF on error
+ * 	  does return in Win2000
+ *  when file valid the number of icons or 0 on any error
+ *  when file invalid and phicon == NULL returns 0
+ *  when file invalid and phicon != NULL returns 0xFFFFFFFF
+ *
+ * *pIconID is always set to 0 when file invalid
+ * *pIconID is always set to 0xFFFFFFFF for valid icon and cursor files
+ * *pIconID is set to actual identifier for valid dll/exes or -1 on error
  */
 
-HRESULT WINAPI PrivateExtractIconsW (
+UINT WINAPI PrivateExtractIconsW (
 	LPCWSTR lpwstrFile,
 	int nIndex,
-	DWORD sizeX,
-	DWORD sizeY,
-	HICON * phicon,	/* [???] NOTE: HICON* */
-	DWORD w,	/* [in] NOTE: 0 */
-	UINT nIcons,
-	DWORD y )	/* [in] NOTE: 0x80 maybe LR_* constant */
+	int sizeX,
+	int sizeY,
+	HICON * phicon,	/* [out] pointer to array of HICON handles */
+	UINT* pIconId,	/* [out] pointer to returned icon identifier which fits best */
+	UINT nIcons,    /* [in] number of icons to retrieve */
+	UINT flags )	/* [in] LR_* flags used by LoadImage */
 {
-	DWORD ret;
-	TRACE("%s 0x%08x 0x%08lx 0x%08lx %p 0x%08lx 0x%08x 0x%08lx\n",
-	debugstr_w(lpwstrFile),nIndex, sizeX ,sizeY ,phicon,w,nIcons,y );
-
-	if ((nIcons == 2) && HIWORD(sizeX) && HIWORD(sizeY))
-	{
-	  ret = ICO_ExtractIconExW(lpwstrFile, phicon, nIndex, 1, sizeX & 0xffff, sizeY & 0xffff );
-	  if (!SUCCEEDED(ret)) return ret;
-	  ret = ICO_ExtractIconExW(lpwstrFile, phicon+1, nIndex, 1, (sizeX>>16) & 0xffff, (sizeY>>16) & 0xffff );
-	} else
-	  ret = ICO_ExtractIconExW(lpwstrFile, phicon, nIndex, nIcons, sizeX & 0xffff, sizeY & 0xffff );
-	return ret;
+    UINT ret;
+    TRACE("%s %d 0x%08lx 0x%08lx %p %p %d 0x%08lx\n",
+    debugstr_w(lpwstrFile), nIndex, sizeX, sizeY, phicon, pIconId, nIcons, flags);
+
+	if (pIconId) /* Invalidate icon identifier on entry */
+		*pIconId = 0xFFFFFFFF;
+		
+    if (!phicon)
+      return ICO_ExtractIconExW(lpwstrFile, NULL, nIndex, 0, sizeX & 0xffff, sizeY & 0xffff, pIconId, flags);
+		
+    if ((nIcons == 2) && HIWORD(sizeX) && HIWORD(sizeY))
+    {
+      ret = ICO_ExtractIconExW(lpwstrFile, phicon, nIndex, 1, sizeX & 0xffff, sizeY & 0xffff, pIconId, flags);
+      if (!SUCCEEDED(ret)) return ret;
+      ret = ICO_ExtractIconExW(lpwstrFile, phicon+1, nIndex, 1, (sizeX>>16) & 0xffff, (sizeY>>16) & 0xffff, pIconId, flags);
+    } else
+      ret = ICO_ExtractIconExW(lpwstrFile, phicon, nIndex, nIcons, sizeX & 0xffff, sizeY & 0xffff, pIconId, flags);
+    return ret;
 }
 
 /***********************************************************************
  *           PrivateExtractIconsA			[USER32.@]
  */
 
-HRESULT WINAPI PrivateExtractIconsA (
+UINT WINAPI PrivateExtractIconsA (
 	LPCSTR lpstrFile,
-	INT nIndex,
-	DWORD sizeX,
-	DWORD sizeY,
+	int nIndex,
+	int sizeX,
+	int sizeY,
 	HICON * phicon,
-	DWORD w,	/* [in] NOTE: 0 */
-	UINT  nIcons,
-	DWORD y )	/* [in] NOTE: 0x80 */
+	UINT* piconid,  /* [out] pointer to returned icon identifier which fits best */
+	UINT nIcons,    /* [in] number of icons to retrieve */
+	UINT flags )    /* [in] LR_* flags used by LoadImage */
 {
-	DWORD ret;
-        INT len = MultiByteToWideChar( CP_ACP, 0, lpstrFile, -1, NULL, 0 );
-        LPWSTR lpwstrFile = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
-
-        MultiByteToWideChar( CP_ACP, 0, lpstrFile, -1, lpwstrFile, len );
-	ret = PrivateExtractIconsW(
-		lpwstrFile, nIndex, sizeX, sizeY, phicon, w, nIcons, y
-	);
+    UINT ret;
+    INT len = MultiByteToWideChar(CP_ACP, 0, lpstrFile, -1, NULL, 0);
+    LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
 
-	HeapFree(GetProcessHeap(), 0, lpwstrFile);
-	return ret;
+    MultiByteToWideChar(CP_ACP, 0, lpstrFile, -1, lpwstrFile, len);
+    ret = PrivateExtractIconsW(lpwstrFile, nIndex, sizeX, sizeY, phicon, piconid, nIcons, flags);
+
+    HeapFree(GetProcessHeap(), 0, lpwstrFile);
+    return ret;
 }
 
 /***********************************************************************
Index: include/winuser.h
===================================================================
RCS file: /home/wine/wine/include/winuser.h,v
retrieving revision 1.153
diff -u -r1.153 winuser.h
--- include/winuser.h	18 Nov 2002 19:46:34 -0000	1.153
+++ include/winuser.h	3 Dec 2002 09:10:59 -0000
@@ -4465,8 +4465,8 @@
 /* NOTE: This is SYSTEM.3, not USER.182, which is also named KillSystemTimer */
 WORD        WINAPI SYSTEM_KillSystemTimer( WORD );
 
-HRESULT     WINAPI PrivateExtractIconsA(LPCSTR,INT,DWORD,DWORD,HICON*,DWORD,UINT,DWORD);
-HRESULT     WINAPI PrivateExtractIconsW(LPCWSTR,INT,DWORD,DWORD,HICON*,DWORD,UINT,DWORD);
+UINT     WINAPI PrivateExtractIconsA(LPCSTR,int,int,int,HICON*,UINT*,UINT,UINT);
+UINT     WINAPI PrivateExtractIconsW(LPCWSTR,int,int,int,HICON*,UINT*,UINT,UINT);
 
 #ifdef __cplusplus
 }

Index: dlls/user/user32.spec
===================================================================
RCS file: /home/wine/wine/dlls/user/user32.spec,v
retrieving revision 1.63
diff -u -r1.63 user32.spec
--- dlls/user/user32.spec	6 Nov 2002 20:02:59 -0000	1.63
+++ dlls/user/user32.spec	2 Dec 2002 23:29:09 -0000
@@ -621,8 +621,8 @@
 @ stdcall EnumDisplayMonitors(long ptr ptr long) EnumDisplayMonitors
 @ stdcall PrivateExtractIconExA (long long long long long) PrivateExtractIconExA
 @ stdcall PrivateExtractIconExW (long long long long long) PrivateExtractIconExW
-@ stdcall PrivateExtractIconsA (long long long long long long long long) PrivateExtractIconsA
-@ stdcall PrivateExtractIconsW (long long long long long long long long) PrivateExtractIconsW
+@ stdcall PrivateExtractIconsA (str long long long ptr ptr long long) PrivateExtractIconsA
+@ stdcall PrivateExtractIconsW (wstr long long long ptr ptr long long) PrivateExtractIconsW
 @ stdcall RegisterShellHookWindow (long) RegisterShellHookWindow
 @ stdcall DeregisterShellHookWindow (long) DeregisterShellHookWindow
 @ stdcall SetShellWindowEx (long long) SetShellWindowEx




More information about the wine-patches mailing list