00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include "precomp.h"
00013
#pragma hdrstop
00014
#include "newexe.h"
00015
00016
00017
00018
00019 #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
00020
00021 #define ICON_MAGIC 0
00022 #define ICO_MAGIC1 1
00023 #define CUR_MAGIC1 2
00024 #define BMP_MAGIC ((WORD)'B'+((WORD)'M'<<8))
00025 #define ANI_MAGIC ((WORD)'R'+((WORD)'I'<<8))
00026 #define ANI_MAGIC1 ((WORD)'F'+((WORD)'F'<<8))
00027 #define ANI_MAGIC4 ((WORD)'A'+((WORD)'C'<<8))
00028 #define ANI_MAGIC5 ((WORD)'O'+((WORD)'N'<<8))
00029 #define MZMAGIC ((WORD)'M'+((WORD)'Z'<<8))
00030 #define PEMAGIC ((WORD)'P'+((WORD)'E'<<8))
00031 #define LEMAGIC ((WORD)'L'+((WORD)'E'<<8))
00032
00033 typedef struct new_exe NEWEXE, *
LPNEWEXE;
00034 typedef struct exe_hdr EXEHDR, *
LPEXEHDR;
00035 typedef struct rsrc_nameinfo RESNAMEINFO, *
LPRESNAMEINFO;
00036 typedef struct rsrc_typeinfo RESTYPEINFO, *
LPRESTYPEINFO;
00037 typedef struct rsrc_typeinfo UNALIGNED *
ULPRESTYPEINFO;
00038 typedef struct new_rsrc RESTABLE, *
LPRESTABLE;
00039
00040 #define RESOURCE_VA(x) ((x)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress)
00041 #define RESOURCE_SIZE(x) ((x)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size)
00042 #define NUMBER_OF_SECTIONS(x) ((x)->FileHeader.NumberOfSections)
00043
00044 #define FCC(c0,c1,c2,c3) ((DWORD)(c0)|((DWORD)(c1)<<8)|((DWORD)(c2)<<16)|((DWORD)(c3)<<24))
00045
00046 #define COM_FILE FCC('.', 'c', 'o', 'm')
00047 #define BAT_FILE FCC('.', 'b', 'a', 't')
00048 #define CMD_FILE FCC('.', 'c', 'm', 'd')
00049 #define PIF_FILE FCC('.', 'p', 'i', 'f')
00050 #define LNK_FILE FCC('.', 'l', 'n', 'k')
00051 #define ICO_FILE FCC('.', 'i', 'c', 'o')
00052 #define EXE_FILE FCC('.', 'e', 'x', 'e')
00053
00054
00055 #define WIN32VER30 0x00030000 // for CreateIconFromResource()
00056
00057 #define GET_COUNT 424242
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 __inline
BOOL PathIsUNC(
00069 LPWSTR psz)
00070 {
00071
return (psz[0] ==
L'\\' && psz[1] ==
L'\\');
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 BOOL ReadAByte(
00083 LPCVOID pMem)
00084 {
00085
return ((*(
PBYTE)pMem) == 0);
00086 }
00087
00088
00089
00090
00091
00092
00093
00094 LPVOID RVAtoP(
00095 LPVOID pBase,
00096 DWORD rva)
00097 {
00098
LPEXEHDR pmz;
00099 IMAGE_NT_HEADERS *ppe;
00100 IMAGE_SECTION_HEADER *pSection;
00101
int i;
00102
DWORD size;
00103
00104 pmz = (
LPEXEHDR)pBase;
00105 ppe = (IMAGE_NT_HEADERS*)((
BYTE*)pBase + pmz->e_lfanew);
00106
00107
00108
00109
00110 pSection = IMAGE_FIRST_SECTION(ppe);
00111
00112
for (i = 0; i <
NUMBER_OF_SECTIONS(ppe); i++) {
00113
00114 size = pSection[i].Misc.VirtualSize ?
00115 pSection[i].Misc.VirtualSize : pSection[i].SizeOfRawData;
00116
00117
if (rva >= pSection[i].VirtualAddress &&
00118 rva < pSection[i].VirtualAddress + size) {
00119
00120
return (LPBYTE)pBase + pSection[i].PointerToRawData + (rva - pSection[i].VirtualAddress);
00121 }
00122 }
00123
00124
return NULL;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133 LPVOID GetResourceTablePE(
00134 LPVOID pBase)
00135 {
00136
LPEXEHDR pmz;
00137 IMAGE_NT_HEADERS *ppe;
00138
00139 pmz = (
LPEXEHDR)pBase;
00140 ppe = (IMAGE_NT_HEADERS*)((
BYTE*)pBase + pmz->e_lfanew);
00141
00142
if (pmz->e_magic !=
MZMAGIC)
00143
return 0;
00144
00145
if (ppe->Signature != IMAGE_NT_SIGNATURE)
00146
return 0;
00147
00148
if (ppe->FileHeader.SizeOfOptionalHeader < IMAGE_SIZEOF_NT_OPTIONAL_HEADER)
00149
return 0;
00150
00151
return RVAtoP(pBase,
RESOURCE_VA(ppe));
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 LPVOID FindResourcePE(
00166 LPVOID pBase,
00167 LPVOID prt,
00168
int iResIndex,
00169
int ResType,
00170 DWORD *pcb)
00171 {
00172
int i;
00173
int cnt;
00174 IMAGE_RESOURCE_DIRECTORY *pdir;
00175 IMAGE_RESOURCE_DIRECTORY_ENTRY *pres;
00176 IMAGE_RESOURCE_DATA_ENTRY *pent;
00177
00178 pdir = (IMAGE_RESOURCE_DIRECTORY *)prt;
00179
00180
00181
00182
00183 cnt = pdir->NumberOfIdEntries + pdir->NumberOfNamedEntries;
00184 pres = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(pdir+1);
00185
00186
for (i = 0; i < cnt; i++) {
00187
00188
if (pres[i].Name == (
DWORD)ResType)
00189
break;
00190 }
00191
00192
if (i==cnt)
00193
return 0;
00194
00195
00196
00197
00198
00199 pdir = (IMAGE_RESOURCE_DIRECTORY*)((LPBYTE)prt +
00200 (pres[i].OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY));
00201
00202 cnt = pdir->NumberOfIdEntries + pdir->NumberOfNamedEntries;
00203 pres = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(pdir+1);
00204
00205
00206
00207
00208
if (iResIndex ==
GET_COUNT)
00209
return (
LPVOID)UIntToPtr( cnt );
00210
00211
00212
00213
00214
if (iResIndex < 0) {
00215
00216
for (i = 0; i < cnt; i++)
00217
if (pres[i].Name == (
DWORD)(-iResIndex))
00218
break;
00219 }
else {
00220 i = iResIndex;
00221 }
00222
00223
00224
00225
00226
if (i >= cnt)
00227
return 0;
00228
00229
00230
00231
00232
00233
00234
if (pres[i].OffsetToData & IMAGE_RESOURCE_DATA_IS_DIRECTORY) {
00235
00236 pdir = (IMAGE_RESOURCE_DIRECTORY*)((LPBYTE)prt +
00237 (pres[i].OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY));
00238 pres = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(pdir+1);
00239 i = 0;
00240 }
00241
00242
00243
00244
00245
if (pres[i].OffsetToData & IMAGE_RESOURCE_DATA_IS_DIRECTORY)
00246
return 0;
00247
00248 pent = (IMAGE_RESOURCE_DATA_ENTRY*)((LPBYTE)prt + pres[i].OffsetToData);
00249
00250
00251
00252
00253
00254
00255
00256 *pcb = pent->Size;
00257
return RVAtoP(pBase, pent->OffsetToData);
00258 }
00259
00260
00261
00262
00263
00264
00265
00266 LPVOID GetResourceTableNE(
00267 LPVOID pBase)
00268 {
00269
LPNEWEXE pne;
00270
LPEXEHDR pmz;
00271
00272 pmz = (
LPEXEHDR)pBase;
00273 pne = (
LPNEWEXE)((LPBYTE)pBase + pmz->e_lfanew);
00274
00275
if (pmz->e_magic !=
MZMAGIC)
00276
return 0;
00277
00278
if (pne->ne_magic != NEMAGIC)
00279
return 0;
00280
00281
if (pne->ne_exetyp != NE_WINDOWS &&
00282 pne->ne_exetyp != NE_DEV386)
00283
return 0;
00284
00285
if (pne->ne_expver < 0x0300)
00286
return 0;
00287
00288
if (pne->ne_rsrctab == pne->ne_restab)
00289
return 0;
00290
00291
return (LPBYTE)pne + pne->ne_rsrctab;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 LPVOID FindResourceNE(
00311 LPVOID lpBase,
00312 LPVOID prt,
00313
int iResIndex,
00314
int iResType,
00315 DWORD *pcb)
00316 {
00317
LPRESTABLE lpResTable;
00318
ULPRESTYPEINFO ulpResTypeInfo;
00319
LPRESNAMEINFO lpResNameInfo;
00320
int i;
00321
00322 lpResTable = (
LPRESTABLE)prt;
00323
00324 ulpResTypeInfo = (
ULPRESTYPEINFO)((LPBYTE)lpResTable + 2);
00325
00326
while (ulpResTypeInfo->rt_id) {
00327
00328
if (ulpResTypeInfo->rt_id == (iResType | RSORDID)) {
00329
00330 lpResNameInfo = (
LPRESNAMEINFO)(ulpResTypeInfo + 1);
00331
00332
if (iResIndex ==
GET_COUNT)
00333
return (
LPVOID)ulpResTypeInfo->rt_nres;
00334
00335
if (iResIndex < 0) {
00336
00337
for (i=0; i < (
int)ulpResTypeInfo->rt_nres; i++) {
00338
00339
if (lpResNameInfo[i].rn_id == ((-iResIndex) | RSORDID))
00340
break;
00341 }
00342
00343 iResIndex = i;
00344 }
00345
00346
if (iResIndex >= (
int)ulpResTypeInfo->rt_nres)
00347
return NULL;
00348
00349 *pcb = ((
DWORD)lpResNameInfo[iResIndex].rn_length) << lpResTable->rs_align;
00350
return (LPBYTE)lpBase + ((
long)lpResNameInfo[iResIndex].rn_offset << lpResTable->rs_align);
00351 }
00352
00353 ulpResTypeInfo =
00354 (
ULPRESTYPEINFO)((
LPRESNAMEINFO)(ulpResTypeInfo + 1) +
00355 ulpResTypeInfo->rt_nres);
00356 }
00357
00358 *pcb = 0;
00359
return NULL;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368 UINT ExtractIconFromICO(
00369 LPTSTR szFile,
00370
int nIconIndex,
00371
int cxIcon,
00372
int cyIcon,
00373 HICON *phicon,
00374 UINT flags)
00375 {
00376 HICON hicon;
00377
00378
if (nIconIndex >= 1)
00379
return 0;
00380
00381 flags |= LR_LOADFROMFILE;
00382
00383 again:
00384
00385 hicon = LoadImage(
NULL,
00386
szFile,
00387 IMAGE_ICON,
00388 LOWORD(cxIcon),
00389 LOWORD(cyIcon),
00390 flags);
00391
00392
if (hicon ==
NULL)
00393
return 0;
00394
00395
00396
00397
00398
if (phicon ==
NULL)
00399
DestroyCursor((HCURSOR)hicon);
00400
else
00401 *phicon = hicon;
00402
00403
00404
00405
00406
if (HIWORD(cxIcon)) {
00407
00408 cxIcon = HIWORD(cxIcon);
00409 cyIcon = HIWORD(cyIcon);
00410 phicon++;
00411
00412
goto again;
00413 }
00414
00415
return 1;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424 #define ROP_DSna 0x00220326
00425
00426 UINT ExtractIconFromBMP(
00427 LPTSTR szFile,
00428
int nIconIndex,
00429
int cxIcon,
00430
int cyIcon,
00431 HICON *phicon,
00432 UINT flags)
00433 {
00434 HICON hicon;
00435 HBITMAP hbm;
00436 HBITMAP hbmMask;
00437 HDC hdc;
00438 HDC hdcMask;
00439 ICONINFO ii;
00440
00441
if (nIconIndex >= 1)
00442
return 0;
00443
00444
00445
00446
00447
00448 flags |= LR_LOADFROMFILE;
00449
00450 again:
00451
00452 hbm = (HBITMAP)LoadImage(
NULL,
00453
szFile,
00454 IMAGE_BITMAP,
00455 LOWORD(cxIcon),
00456 LOWORD(cyIcon),
00457 flags);
00458
00459
if (hbm ==
NULL)
00460
return 0;
00461
00462
00463
00464
00465
if (phicon ==
NULL) {
00466 DeleteObject(hbm);
00467
return 1;
00468 }
00469
00470 hbmMask = CreateBitmap(LOWORD(cxIcon), LOWORD(cyIcon), 1, 1,
NULL);
00471
00472 hdc = CreateCompatibleDC(
NULL);
00473 SelectObject(hdc, hbm);
00474
00475 hdcMask = CreateCompatibleDC(
NULL);
00476 SelectObject(hdcMask, hbmMask);
00477
00478 SetBkColor(hdc, GetPixel(hdc, 0, 0));
00479
00480 BitBlt(hdcMask, 0, 0, LOWORD(cxIcon), LOWORD(cyIcon), hdc, 0, 0, SRCCOPY);
00481 BitBlt(hdc, 0, 0, LOWORD(cxIcon), LOWORD(cyIcon), hdcMask, 0, 0,
ROP_DSna);
00482
00483 ii.fIcon =
TRUE;
00484 ii.xHotspot = 0;
00485 ii.yHotspot = 0;
00486 ii.hbmColor = hbm;
00487 ii.hbmMask = hbmMask;
00488 hicon =
CreateIconIndirect(&ii);
00489
00490 DeleteObject(hdc);
00491 DeleteObject(hbm);
00492 DeleteObject(hdcMask);
00493 DeleteObject(hbmMask);
00494
00495 *phicon = hicon;
00496
00497
00498
00499
00500
if (HIWORD(cxIcon)) {
00501 cxIcon = HIWORD(cxIcon);
00502 cyIcon = HIWORD(cyIcon);
00503 phicon++;
00504
00505
goto again;
00506 }
00507
00508
return 1;
00509 }
00510
00511
00512
00513
00514
00515
00516
00517 UINT ExtractIconFromEXE(
00518 HANDLE hFile,
00519
int nIconIndex,
00520
int cxIconSize,
00521
int cyIconSize,
00522 HICON *phicon,
00523 UINT *piconid,
00524 UINT nIcons,
00525 UINT flags)
00526 {
00527 HANDLE hFileMap =
INVALID_HANDLE_VALUE;
00528
LPVOID lpFile =
NULL;
00529 EXEHDR *pmz;
00530 NEWEXE UNALIGNED *pne;
00531
LPVOID pBase;
00532
LPVOID pres =
NULL;
00533
UINT result = 0;
00534 LONG FileLength;
00535
DWORD cbSize;
00536
int cxIcon;
00537
int cyIcon;
00538
00539
LPVOID (*FindResourceX)(
LPVOID pBase,
00540
LPVOID prt,
00541
int iResIndex,
00542
int iResType,
00543
DWORD *pcb);
00544
00545 FileLength = (LONG)GetFileSize(hFile,
NULL);
00546
00547 hFileMap = CreateFileMapping(hFile,
NULL, PAGE_READONLY, 0, 0,
NULL);
00548
if (hFileMap ==
NULL)
00549
goto exit;
00550
00551 lpFile = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
00552
if (lpFile ==
NULL)
00553
goto exit;
00554
00555 pBase = (
LPVOID)lpFile;
00556 pmz = (
struct exe_hdr *)pBase;
00557
00558 _try {
00559
00560
if (pmz->e_magic !=
MZMAGIC)
00561
goto exit;
00562
00563
if (pmz->e_lfanew <= 0)
00564
goto exit;
00565
00566
if (pmz->e_lfanew >= FileLength)
00567
goto exit;
00568
00569 pne = (NEWEXE UNALIGNED *)((
BYTE*)pmz + pmz->e_lfanew);
00570
00571
switch (pne->ne_magic) {
00572
case NEMAGIC:
00573 pres =
GetResourceTableNE(pBase);
00574 FindResourceX =
FindResourceNE;
00575
break;
00576
00577
case PEMAGIC:
00578 pres =
GetResourceTablePE(pBase);
00579 FindResourceX =
FindResourcePE;
00580
break;
00581 }
00582
00583
00584
00585
00586
if (pres ==
NULL)
00587
goto exit;
00588
00589
00590
00591
00592
if (phicon ==
NULL) {
00593 result = PtrToUlong(FindResourceX(pBase,
00594 pres,
00595
GET_COUNT,
00596 (LONG_PTR)RT_GROUP_ICON,
00597 &cbSize));
00598
goto exit;
00599 }
00600
00601
while (result < nIcons) {
00602
00603
LPVOID lpIconDir;
00604
LPVOID lpIcon;
00605
int idIcon;
00606
00607 cxIcon = cxIconSize;
00608 cyIcon = cyIconSize;
00609
00610
00611
00612
00613 lpIconDir = FindResourceX(pBase,
00614 pres,
00615 nIconIndex,
00616 (LONG_PTR)RT_GROUP_ICON,
00617 &cbSize);
00618
00619
if (lpIconDir ==
NULL)
00620
goto exit;
00621
00622
if ((((LPNEWHEADER)lpIconDir)->Reserved != 0) ||
00623 (((LPNEWHEADER)lpIconDir)->ResType != FT_ICON)) {
00624
00625
goto exit;
00626 }
00627 again:
00628 idIcon =
LookupIconIdFromDirectoryEx((LPBYTE)lpIconDir,
00629
TRUE,
00630 LOWORD(cxIcon),
00631 LOWORD(cyIcon),
00632 flags);
00633 lpIcon = FindResourceX(pBase,
00634 pres,
00635 -idIcon,
00636 (LONG_PTR)RT_ICON,
00637 &cbSize);
00638
00639
if (lpIcon ==
NULL)
00640
goto exit;
00641
00642
if ((((
UPBITMAPINFOHEADER)lpIcon)->biSize !=
sizeof(BITMAPINFOHEADER)) &&
00643 (((
UPBITMAPINFOHEADER)lpIcon)->biSize !=
sizeof(BITMAPCOREHEADER))) {
00644
00645
goto exit;
00646 }
00647
00648
#ifndef WINNT
00649
00650
00651
00652
00653
ReadAByte(((
BYTE *)lpIcon) + cbSize - 1);
00654
#endif
00655
00656
if (piconid)
00657 piconid[result] = idIcon;
00658
00659 phicon[result++] =
CreateIconFromResourceEx((LPBYTE)lpIcon,
00660 cbSize,
00661
TRUE,
00662
WIN32VER30,
00663 LOWORD(cxIcon),
00664 LOWORD(cyIcon),
00665 flags);
00666
00667
00668
00669
00670
if (HIWORD(cxIcon)) {
00671
00672 cxIcon = HIWORD(cxIcon);
00673 cyIcon = HIWORD(cyIcon);
00674
00675
goto again;
00676 }
00677
00678 nIconIndex++;
00679 }
00680
00681 } _except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00682 result = 0;
00683 }
00684
00685
exit:
00686
00687
if (lpFile)
00688 UnmapViewOfFile(lpFile);
00689
00690
if (hFileMap !=
INVALID_HANDLE_VALUE)
00691 CloseHandle(hFileMap);
00692
00693
return result;
00694 }
00695
00696
00697
00698
00699
00700
00701
00702 LPWSTR
PathFindExtension(
00703 LPWSTR pszPath)
00704 {
00705 LPWSTR pszDot;
00706
00707
for (pszDot =
NULL; *pszPath; pszPath = CharNext(pszPath)) {
00708
00709
switch (*pszPath) {
00710
case L'.':
00711 pszDot = pszPath;
00712
break;
00713
00714
case L'\\':
00715
case L' ':
00716 pszDot =
NULL;
00717
break;
00718 }
00719 }
00720
00721
00722
00723
00724
00725
return pszDot ? (LPWSTR)pszDot : (LPWSTR)pszPath;
00726 }
00727
00728
00729
00730
00731
00732
00733
00734
00735 WINUSERAPI
UINT PrivateExtractIconExA(
00736 LPCSTR szFileName,
00737
int nIconIndex,
00738 HICON *phiconLarge,
00739 HICON *phiconSmall,
00740 UINT nIcons)
00741 {
00742 LPWSTR szFileNameW;
00743
UINT uRet;
00744
00745
if (!MBToWCS(szFileName, -1, &szFileNameW, -1,
TRUE))
00746
return 0;
00747
00748 uRet =
PrivateExtractIconExW(szFileNameW,
00749 nIconIndex,
00750 phiconLarge,
00751 phiconSmall,
00752 nIcons);
00753
00754
UserLocalFree(szFileNameW);
00755
00756
return uRet;
00757 }
00758
00759
00760
00761
00762
00763
00764
00765 DWORD HasExtension(
00766 LPWSTR pszPath)
00767 {
00768 LPWSTR p =
PathFindExtension(pszPath);
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
if (*p ==
L'.') {
00779
00780 WCHAR szExt[5];
00781
00782 lstrcpynW(szExt, p, 5);
00783
00784
if (lstrcmpiW(szExt,TEXT(
".com")) == 0)
return COM_FILE;
00785
if (lstrcmpiW(szExt,TEXT(
".bat")) == 0)
return BAT_FILE;
00786
if (lstrcmpiW(szExt,TEXT(
".cmd")) == 0)
return CMD_FILE;
00787
if (lstrcmpiW(szExt,TEXT(
".pif")) == 0)
return PIF_FILE;
00788
if (lstrcmpiW(szExt,TEXT(
".lnk")) == 0)
return LNK_FILE;
00789
if (lstrcmpiW(szExt,TEXT(
".ico")) == 0)
return ICO_FILE;
00790
if (lstrcmpiW(szExt,TEXT(
".exe")) == 0)
return EXE_FILE;
00791 }
00792
00793
return 0;
00794 }
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830 WINUSERAPI
UINT WINAPI
PrivateExtractIconsW(
00831 LPCWSTR szFileName,
00832
int nIconIndex,
00833
int cxIcon,
00834
int cyIcon,
00835 HICON *phicon,
00836 UINT *piconid,
00837 UINT nIcons,
00838 UINT flags)
00839 {
00840 HANDLE hFile = (HANDLE)
INVALID_HANDLE_VALUE;
00841
UINT result = 0;
00842 WORD magic[6];
00843 WCHAR achFileName[
MAX_PATH];
00844 FILETIME ftAccess;
00845 WCHAR szExpFileName[
MAX_PATH];
00846
DWORD dwBytesRead;
00847
00848
00849
00850
00851
if (phicon)
00852 *phicon =
NULL;
00853
00854
00855
00856
00857
switch (
HasExtension((LPWSTR)szFileName)) {
00858
case COM_FILE:
00859
case BAT_FILE:
00860
case CMD_FILE:
00861
case PIF_FILE:
00862
case LNK_FILE:
00863
goto exit;
00864
00865
default:
00866
break;
00867 }
00868
00869
00870
00871
00872 ExpandEnvironmentStrings(szFileName, szExpFileName,
MAX_PATH);
00873 szExpFileName[
MAX_PATH-1 ] = (WCHAR)0;
00874
00875
00876
00877
00878
00879
if (
PathIsUNC(szExpFileName)) {
00880
00881 lstrcpynW(achFileName, szExpFileName,
ARRAYSIZE(achFileName));
00882
00883 }
else {
00884
00885
if (SearchPath(
NULL,
00886 szExpFileName,
00887
NULL,
00888
ARRAYSIZE(achFileName),
00889 achFileName,
NULL) == 0) {
00890
00891
goto error_file;
00892 }
00893 }
00894
00895 hFile = CreateFile(achFileName,
00896 GENERIC_READ|FILE_WRITE_ATTRIBUTES,
00897 FILE_SHARE_WRITE | FILE_SHARE_READ,
00898
NULL,
00899
OPEN_EXISTING,
00900 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
00901 0);
00902
00903
if (hFile ==
INVALID_HANDLE_VALUE) {
00904
00905 hFile = CreateFile(achFileName, GENERIC_READ,
00906 FILE_SHARE_READ,
00907
NULL,
00908
OPEN_EXISTING,
00909 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
00910 0);
00911
00912
if (hFile ==
INVALID_HANDLE_VALUE)
00913
goto error_file;
00914
00915 }
else {
00916
00917
00918
00919
00920
if (GetFileTime(hFile,
NULL, &ftAccess,
NULL))
00921 SetFileTime(hFile,
NULL, &ftAccess,
NULL);
00922 }
00923
00924
00925 ReadFile(hFile, &magic,
sizeof(magic), &dwBytesRead,
NULL);
00926
if (dwBytesRead !=
sizeof(magic))
00927
goto exit;
00928
00929
if (piconid)
00930 *piconid = (
UINT)-1;
00931
00932
switch (magic[0]) {
00933
case MZMAGIC:
00934 result =
ExtractIconFromEXE(hFile,
00935 nIconIndex,
00936 cxIcon,
00937 cyIcon,
00938 phicon,
00939 piconid,
00940 nIcons,
00941 flags);
00942
break;
00943
00944
case ANI_MAGIC:
00945
00946
00947
00948
00949
if (magic[1] ==
ANI_MAGIC1 && magic[4] ==
ANI_MAGIC4 &&
00950 magic[5] ==
ANI_MAGIC5) {
00951
00952 result =
ExtractIconFromICO(achFileName,
00953 nIconIndex,
00954 cxIcon,
00955 cyIcon,
00956 phicon,
00957 flags);
00958 }
00959
break;
00960
00961
case BMP_MAGIC:
00962 result =
ExtractIconFromBMP(achFileName,
00963 nIconIndex,
00964 cxIcon,
00965 cyIcon,
00966 phicon,
00967 flags);
00968
break;
00969
00970
case ICON_MAGIC:
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
if ((magic[1] ==
ICO_MAGIC1 || magic[1] ==
CUR_MAGIC1) &&
00982 magic[2] >= 1 && magic[2] <= 10) {
00983
00984 result =
ExtractIconFromICO(achFileName,
00985 nIconIndex,
00986 cxIcon,
00987 cyIcon,
00988 phicon,
00989 flags);
00990 }
00991
break;
00992 }
00993
00994
exit:
00995
00996
if (hFile!=
INVALID_HANDLE_VALUE)
00997 CloseHandle(hFile);
00998
00999
return result;
01000
01001
01002
01003
01004
01005
01006 error_file:
01007
01008 result = (phicon ? (
UINT)-1 : 0);
01009
01010
goto exit;
01011 }
01012
01013
01014
01015
01016
01017
01018
01019 WINUSERAPI
UINT WINAPI
PrivateExtractIconsA(
01020 LPCSTR szFileName,
01021
int nIconIndex,
01022
int cxIcon,
01023
int cyIcon,
01024 HICON *phicon,
01025 UINT *piconid,
01026 UINT nIcons,
01027 UINT flags)
01028 {
01029 LPWSTR szFileNameW;
01030
UINT uRet;
01031
01032
if (!MBToWCS(szFileName, -1, &szFileNameW, -1,
TRUE))
01033
return 0;
01034
01035 uRet =
PrivateExtractIconsW(szFileNameW,
01036 nIconIndex,
01037 cxIcon,
01038 cyIcon,
01039 phicon,
01040 piconid,
01041 nIcons,
01042 flags);
01043
01044
UserLocalFree(szFileNameW);
01045
01046
return uRet;
01047 }
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072 WINUSERAPI
UINT PrivateExtractIconExW(
01073 LPCWSTR szFileName,
01074
int nIconIndex,
01075 HICON *phiconLarge,
01076 HICON *phiconSmall,
01077 UINT nIcons)
01078 {
01079
UINT result = 0;
01080
01081
if ((nIconIndex == -1) || ((phiconLarge ==
NULL) && (phiconSmall ==
NULL)))
01082
return PrivateExtractIconsW(szFileName, 0, 0, 0,
NULL,
NULL, 0, 0);
01083
01084
if (phiconLarge && phiconSmall && (nIcons == 1)) {
01085
01086 HICON ahicon[2];
01087
01088 ahicon[0] =
NULL;
01089 ahicon[1] =
NULL;
01090
01091 result =
PrivateExtractIconsW(szFileName,
01092 nIconIndex,
01093 MAKELONG(
GetSystemMetrics(SM_CXICON),
01094
GetSystemMetrics(SM_CXSMICON)),
01095 MAKELONG(
GetSystemMetrics(SM_CYICON),
01096
GetSystemMetrics(SM_CYSMICON)),
01097 ahicon,
01098
NULL,
01099 2,
01100 0);
01101
01102 *phiconLarge = ahicon[0];
01103 *phiconSmall = ahicon[1];
01104
01105 }
else {
01106
01107
if (phiconLarge)
01108 result =
PrivateExtractIconsW(szFileName,
01109 nIconIndex,
01110
GetSystemMetrics(SM_CXICON),
01111
GetSystemMetrics(SM_CYICON),
01112 phiconLarge,
01113
NULL,
01114 nIcons,
01115 0);
01116
01117
if (phiconSmall)
01118 result =
PrivateExtractIconsW(szFileName,
01119 nIconIndex,
01120
GetSystemMetrics(SM_CXSMICON),
01121
GetSystemMetrics(SM_CYSMICON),
01122 phiconSmall,
01123
NULL,
01124 nIcons,
01125 0);
01126 }
01127
01128
return result;
01129 }