88
99#include "precomp.h"
1010#include <stdio.h>
11+ #include <versionhelpers.h>
12+
13+ BOOL IsValidIcon (HICON hIco )
14+ {
15+ ICONINFO info = { 0 };
16+
17+ if (!hIco || !GetIconInfo (hIco , & info ))
18+ return FALSE;
19+
20+ DeleteObject (info .hbmMask );
21+ if (info .hbmColor )
22+ DeleteObject (info .hbmColor );
23+ return TRUE;
24+ }
1125
1226BOOL FileExists (PCWSTR FileName )
1327{
@@ -110,11 +124,14 @@ static struct
110124 {L"%temp%\\cpimg2e.exe" , IDR_EXE_NORMAL }
111125};
112126
127+ void TestPairExtraction (void );
128+
113129START_TEST (PrivateExtractIcons )
114130{
115131 HICON ahIcon ;
116132 UINT i , aIconId , cIcons , cIcoTotal ;
117133 WCHAR PathBuffer [MAX_PATH ];
134+ UINT Shell32WinIcoCount = IsWindowsVistaOrGreater () ? 326 : 239 ; /* 239 on W2K3SP2, 326 on Win10 */
118135
119136 /* Extract icons */
120137 for (i = 0 ; i < _countof (IconFiles ); ++ i )
@@ -125,14 +142,16 @@ START_TEST(PrivateExtractIcons)
125142 goto Cleanup ;
126143 }
127144
145+ TestPairExtraction ();
146+
128147 for (i = 0 ; i < _countof (IconTests ); ++ i )
129148 {
130149 /* Get total number of icon groups in file.
131150 * None of the hard numbers in the function matter since we have
132151 * two NULLs for the Icon Handle and Count to be set. */
133152 cIcoTotal = PrivateExtractIconsW (IconTests [i ].FilePath , 0 , 16 , 16 , NULL , NULL , 0 , 0 );
134153 ok ((i == 3 ?
135- cIcoTotal > 232 && cIcoTotal < 240 : /* shell32 case: ROS has 233, W2K2SP2 has 239 icon groups. */
154+ cIcoTotal > 232 && cIcoTotal <= Shell32WinIcoCount : /* shell32 case: ROS has 233, Windows has >= 239 icon groups. */
136155 cIcoTotal == IconTests [i ].cTotalIcons ),
137156 "PrivateExtractIconsW(%u): "
138157 "got %u, expected %u\n" , i , cIcoTotal , IconTests [i ].cTotalIcons );
@@ -167,3 +186,67 @@ START_TEST(PrivateExtractIcons)
167186 DeleteFileW (PathBuffer );
168187 }
169188}
189+
190+ static const struct tagPAIRSTESTS
191+ {
192+ BYTE InCount ;
193+ BYTE UseHigh ; // Extract a pair (high and low word sizes)
194+ BYTE Library ;
195+ BYTE ReturnNT5 ;
196+ BYTE CountNT5 ;
197+ BYTE ReturnNT6 ;
198+ BYTE CountNT6 ;
199+ } g_pairs [] =
200+ {
201+ { 0 , 0 , 0 , 1 , 1 , 1 , 1 },
202+ { 0 , 0 , 1 , 0 , 0 , 0 , 0 },
203+ { 0 , 1 , 0 , 1 , 2 , 1 , 2 },
204+ { 0 , 1 , 1 , 0 , 0 , 0 , 0 },
205+ { 1 , 0 , 0 , 1 , 1 , 1 , 1 },
206+ { 1 , 0 , 1 , 1 , 1 , 1 , 1 },
207+ { 1 , 1 , 0 , 1 , 2 , 1 , 2 },
208+ { 1 , 1 , 1 , 2 , 2 , 0 , 0 },
209+ { 2 , 0 , 0 , 1 , 1 , 1 , 1 },
210+ { 2 , 0 , 1 , 2 , 2 , 2 , 2 },
211+ { 2 , 1 , 0 , 1 , 2 , 1 , 2 },
212+ { 2 , 1 , 1 , 2 , 2 , 2 , 2 }, // This is the only way to extract a pair from a PE on NT6!
213+ { 3 , 0 , 0 , 1 , 1 , 1 , 1 },
214+ { 3 , 0 , 1 , 3 , 3 , 3 , 3 },
215+ { 3 , 1 , 0 , 1 , 2 , 1 , 2 },
216+ { 3 , 1 , 1 , 4 , 4 , 0 , 0 },
217+ { 4 , 0 , 0 , 1 , 1 , 1 , 1 },
218+ { 4 , 0 , 1 , 4 , 4 , 4 , 4 },
219+ { 4 , 1 , 0 , 1 , 2 , 1 , 2 },
220+ { 4 , 1 , 1 , 4 , 4 , 4 , 4 }
221+ };
222+
223+ void TestPairExtraction (void )
224+ {
225+ const HICON hInvalidIcon = (HICON )(INT_PTR )- 2 ;
226+ const BOOL IsNT6 = IsWindowsVistaOrGreater ();
227+ for (UINT i = 0 ; i < _countof (g_pairs ); ++ i )
228+ {
229+ UINT j , Count , ExpectedCount ;
230+ int RetVal , ExpectedRet ;
231+ UINT IcoSize = MAKELONG (32 , g_pairs [i ].UseHigh ? 16 : 0 );
232+ PCWSTR pszPath = g_pairs [i ].Library ? L"%SystemRoot%\\system32\\shell32.dll" : L"%temp%\\sysicon.ico" ;
233+ HICON hIcons [8 ];
234+ for (j = 0 ; j < _countof (hIcons ); ++ j )
235+ hIcons [j ] = hInvalidIcon ;
236+
237+ RetVal = PrivateExtractIconsW (pszPath , 0 , IcoSize , IcoSize , hIcons , NULL , g_pairs [i ].InCount , 0 );
238+ for (j = 0 , Count = 0 ; j < _countof (hIcons ); ++ j )
239+ {
240+ if (hIcons [j ] != hInvalidIcon && IsValidIcon (hIcons [j ]))
241+ {
242+ DestroyIcon (hIcons [j ]);
243+ ++ Count ;
244+ }
245+ }
246+
247+ ExpectedRet = !IsNT6 ? g_pairs [i ].ReturnNT5 : g_pairs [i ].ReturnNT6 ;
248+ ExpectedCount = !IsNT6 ? g_pairs [i ].CountNT5 : g_pairs [i ].CountNT6 ;
249+ ok (RetVal == ExpectedRet , "Test %u: RetVal must be %d but got %d\n" , i , ExpectedRet , RetVal );
250+ ok (Count == ExpectedCount , "Test %u: Count must be %u but got %u\n" , i , ExpectedCount , Count );
251+ }
252+ }
0 commit comments