Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3515 lines
91 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. icons.c
  5. Abstract:
  6. Implements a set of routines for handling icons in ICO, PE and NE files
  7. Author:
  8. Calin Negreanu (calinn) 16-Jum-2000
  9. Revision History:
  10. --*/
  11. //
  12. // Includes
  13. //
  14. #include "pch.h"
  15. //
  16. // Debug constants
  17. //
  18. #define DBG_ICONS "Icons"
  19. //
  20. // Strings
  21. //
  22. // None
  23. //
  24. // Constants
  25. //
  26. // None
  27. //
  28. // Macros
  29. //
  30. // None
  31. //
  32. // Types
  33. //
  34. // None
  35. //
  36. // Globals
  37. //
  38. // None
  39. //
  40. // Macro expansion list
  41. //
  42. // None
  43. //
  44. // Private function prototypes
  45. //
  46. // None
  47. //
  48. // Macro expansion definition
  49. //
  50. // None
  51. //
  52. // Code
  53. //
  54. VOID
  55. IcoReleaseResourceIdA (
  56. PCSTR ResourceId
  57. )
  58. /*++
  59. Routine Description:
  60. IcoReleaseResourceId will either do nothing if the resource ID has the high WORD 0 or will
  61. release the string from the paths pool.
  62. Arguments:
  63. ResourceId - Specifies the resource ID to be released.
  64. Return value:
  65. None
  66. --*/
  67. {
  68. if ((ULONG_PTR) ResourceId > 0xffff) {
  69. FreePathStringA (ResourceId);
  70. }
  71. }
  72. VOID
  73. IcoReleaseResourceIdW (
  74. PCWSTR ResourceId
  75. )
  76. /*++
  77. Routine Description:
  78. IcoReleaseResourceId will either do nothing if the resource ID has the high WORD 0 or will
  79. release the string from the paths pool.
  80. Arguments:
  81. ResourceId - Specifies the resource ID to be released.
  82. Return value:
  83. None
  84. --*/
  85. {
  86. if ((ULONG_PTR) ResourceId > 0xffff) {
  87. FreePathStringW (ResourceId);
  88. }
  89. }
  90. VOID
  91. IcoReleaseIconGroup (
  92. IN PICON_GROUP IconGroup
  93. )
  94. /*++
  95. Routine Description:
  96. IcoReleaseIconGroup releases a previously allocated icon group.
  97. Arguments:
  98. IconGroup - Specifies the icon group to be released.
  99. Return value:
  100. None
  101. --*/
  102. {
  103. if (IconGroup && IconGroup->Pool) {
  104. PmEmptyPool (IconGroup->Pool);
  105. PmDestroyPool (IconGroup->Pool);
  106. }
  107. }
  108. VOID
  109. IcoReleaseIconSGroup (
  110. IN OUT PICON_SGROUP IconSGroup
  111. )
  112. /*++
  113. Routine Description:
  114. IcoReleaseIconSGroup releases a previously allocated serialized icon group.
  115. Arguments:
  116. IconSGroup - Specifies the serialized icon group to be released.
  117. Return value:
  118. None
  119. --*/
  120. {
  121. if (IconSGroup->DataSize && IconSGroup->Data) {
  122. MemFree (g_hHeap, 0, IconSGroup->Data);
  123. }
  124. ZeroMemory (IconSGroup, sizeof (ICON_SGROUP));
  125. }
  126. BOOL
  127. IcoSerializeIconGroup (
  128. IN PICON_GROUP IconGroup,
  129. OUT PICON_SGROUP IconSGroup
  130. )
  131. /*++
  132. Routine Description:
  133. IcoSerializeIconGroup transforms a ICON_GROUP structure into a ICON_SGROUP structure.
  134. Arguments:
  135. IconGroup - Specifies the icon group to be serialized.
  136. Return value:
  137. None
  138. --*/
  139. {
  140. GROWBUFFER buffer = INIT_GROWBUFFER;
  141. DWORD iconsCount;
  142. DWORD index;
  143. DWORD size;
  144. PICON_IMAGE iconImage;
  145. if (IconGroup == NULL) {
  146. return FALSE;
  147. }
  148. if (IconSGroup == NULL) {
  149. return FALSE;
  150. }
  151. iconsCount = IconGroup->IconsCount;
  152. GbAppendDword (&buffer, iconsCount);
  153. size = sizeof (ICON_IMAGE) - sizeof (PBYTE);
  154. index = 0;
  155. while (index < iconsCount) {
  156. iconImage = IconGroup->Icons[index];
  157. CopyMemory (GbGrow (&buffer, size), iconImage, size);
  158. CopyMemory (GbGrow (&buffer, iconImage->Size), iconImage->Image, iconImage->Size);
  159. index ++;
  160. }
  161. MYASSERT (buffer.End);
  162. IconSGroup->DataSize = buffer.End;
  163. IconSGroup->Data = MemAlloc (g_hHeap, 0, buffer.End);
  164. CopyMemory (IconSGroup->Data, buffer.Buf, buffer.End);
  165. GbFree (&buffer);
  166. return TRUE;
  167. }
  168. PICON_GROUP
  169. IcoDeSerializeIconGroup (
  170. IN PICON_SGROUP IconSGroup
  171. )
  172. /*++
  173. Routine Description:
  174. IcoDeSerializeIconGroup transforms a ICON_SGROUP structure into a ICON_GROUP structure.
  175. Arguments:
  176. IconSGroup - Specifies the icon sgroup to be transformed.
  177. Return value:
  178. None
  179. --*/
  180. {
  181. PMHANDLE iconPool = NULL;
  182. PICON_GROUP iconGroup = NULL;
  183. DWORD iconGroupSize = 0;
  184. PICON_IMAGE iconImage = NULL;
  185. PICON_IMAGE iconSImage = NULL;
  186. PDWORD iconsCount;
  187. PBYTE currPtr = NULL;
  188. DWORD i;
  189. if (IconSGroup == NULL) {
  190. return NULL;
  191. }
  192. currPtr = IconSGroup->Data;
  193. iconsCount = (PDWORD) currPtr;
  194. currPtr += sizeof (DWORD);
  195. iconPool = PmCreateNamedPool ("Icon");
  196. if (!iconPool) {
  197. return NULL;
  198. }
  199. iconGroupSize = sizeof (ICON_GROUP) + *iconsCount * sizeof (PICON_IMAGE);
  200. iconGroup = (PICON_GROUP) PmGetAlignedMemory (iconPool, iconGroupSize);
  201. ZeroMemory (iconGroup, iconGroupSize);
  202. iconGroup->Pool = iconPool;
  203. iconGroup->IconsCount = (WORD) (*iconsCount);
  204. for (i = 0; i < *iconsCount; i ++) {
  205. iconSImage = (PICON_IMAGE) currPtr;
  206. currPtr += (sizeof (ICON_IMAGE) - sizeof (PBYTE));
  207. iconImage = (PICON_IMAGE) PmGetAlignedMemory (iconPool, sizeof (ICON_IMAGE));
  208. ZeroMemory (iconImage, sizeof (ICON_IMAGE));
  209. iconImage->Width = iconSImage->Width;
  210. iconImage->Height = iconSImage->Height;
  211. iconImage->ColorCount = iconSImage->ColorCount;
  212. iconImage->Planes = iconSImage->Planes;
  213. iconImage->BitCount = iconSImage->BitCount;
  214. iconImage->Size = iconSImage->Size;
  215. iconImage->Image = PmGetAlignedMemory (iconPool, iconImage->Size);
  216. CopyMemory (iconImage->Image, currPtr, iconImage->Size);
  217. currPtr += iconImage->Size;
  218. iconGroup->Icons [i] = iconImage;
  219. }
  220. return iconGroup;
  221. }
  222. PICON_GROUP
  223. IcoExtractIconGroupFromIcoFileEx (
  224. IN HANDLE IcoFileHandle
  225. )
  226. /*++
  227. Routine Description:
  228. IcoExtractIconGroupFromIcoFileEx extracts the icon group from an ICO file.
  229. Arguments:
  230. IcoFile - Specifies the name of the ICO file to be processed.
  231. IcoFileHandle - Specifies the handle to the ICO file to be processed.
  232. Return value:
  233. An icon group if successfull, NULL otherwise.
  234. --*/
  235. {
  236. PMHANDLE iconPool = NULL;
  237. PICON_GROUP iconGroup = NULL;
  238. DWORD iconGroupSize = 0;
  239. PICON_IMAGE iconImage = NULL;
  240. LONGLONG fileSize;
  241. DWORD fileOffset;
  242. ICONDIRBASE iconDirBase;
  243. PICONDIR iconDir = NULL;
  244. DWORD iconDirSize = 0;
  245. PICONDIRENTRY iconDirEntry;
  246. DWORD i;
  247. BOOL result = FALSE;
  248. __try {
  249. fileSize = GetFileSize (IcoFileHandle, NULL);
  250. if (!BfSetFilePointer (IcoFileHandle, 0)) {
  251. __leave;
  252. }
  253. if (!BfReadFile (IcoFileHandle, (PBYTE)(&iconDirBase), sizeof (ICONDIRBASE))) {
  254. __leave;
  255. }
  256. if (!BfSetFilePointer (IcoFileHandle, 0)) {
  257. __leave;
  258. }
  259. iconDirSize = sizeof (ICONDIRBASE) + iconDirBase.Count * sizeof (ICONDIRENTRY);
  260. // validation
  261. if (iconDirBase.Count == 0) {
  262. __leave;
  263. }
  264. if (iconDirSize > fileSize) {
  265. __leave;
  266. }
  267. iconDir = (PICONDIR) MemAlloc (g_hHeap, 0, iconDirSize);
  268. if (!BfReadFile (IcoFileHandle, (PBYTE)iconDir, iconDirSize)) {
  269. __leave;
  270. }
  271. // validation
  272. for (i = 0; i < iconDirBase.Count; i ++) {
  273. iconDirEntry = &iconDir->Entries[i];
  274. fileOffset = iconDirEntry->ImageOffset & 0x0fffffff;
  275. if (fileOffset > fileSize) {
  276. __leave;
  277. }
  278. if (iconDirEntry->Width == 0) {
  279. __leave;
  280. }
  281. if (iconDirEntry->Height == 0) {
  282. __leave;
  283. }
  284. if (iconDirEntry->BytesInRes == 0) {
  285. __leave;
  286. }
  287. }
  288. if (iconDirEntry->BytesInRes + fileOffset != fileSize) {
  289. __leave;
  290. }
  291. iconPool = PmCreateNamedPool ("Icon");
  292. if (!iconPool) {
  293. __leave;
  294. }
  295. iconGroupSize = sizeof (ICON_GROUP) + iconDirBase.Count * sizeof (PICON_IMAGE);
  296. iconGroup = (PICON_GROUP) PmGetAlignedMemory (iconPool, iconGroupSize);
  297. ZeroMemory (iconGroup, iconGroupSize);
  298. iconGroup->Pool = iconPool;
  299. iconGroup->IconsCount = iconDirBase.Count;
  300. for (i = 0; i < iconDirBase.Count; i ++) {
  301. iconDirEntry = &iconDir->Entries[i];
  302. fileOffset = iconDirEntry->ImageOffset & 0x0fffffff;
  303. if (!BfSetFilePointer (IcoFileHandle, fileOffset)) {
  304. __leave;
  305. }
  306. iconImage = (PICON_IMAGE) PmGetAlignedMemory (iconPool, sizeof (ICON_IMAGE));
  307. ZeroMemory (iconImage, sizeof (ICON_IMAGE));
  308. iconImage->Width = iconDirEntry->Width;
  309. iconImage->Height = iconDirEntry->Height;
  310. iconImage->ColorCount = iconDirEntry->ColorCount;
  311. iconImage->Planes = iconDirEntry->Planes;
  312. iconImage->BitCount = iconDirEntry->BitCount;
  313. iconImage->Size = iconDirEntry->BytesInRes;
  314. iconImage->Image = PmGetAlignedMemory (iconPool, iconImage->Size);
  315. if (!BfReadFile (IcoFileHandle, iconImage->Image, iconImage->Size)) {
  316. __leave;
  317. }
  318. iconGroup->Icons [i] = iconImage;
  319. }
  320. result = TRUE;
  321. }
  322. __finally {
  323. if (iconDir) {
  324. MemFree (g_hHeap, 0, iconDir);
  325. iconDir = NULL;
  326. }
  327. if (!result) {
  328. if (iconPool) {
  329. PmEmptyPool (iconPool);
  330. PmDestroyPool (iconPool);
  331. iconPool = NULL;
  332. }
  333. iconGroup = NULL;
  334. }
  335. BfSetFilePointer (IcoFileHandle, 0);
  336. }
  337. return iconGroup;
  338. }
  339. PICON_GROUP
  340. IcoExtractIconGroupFromIcoFileA (
  341. IN PCSTR IcoFile
  342. )
  343. /*++
  344. Routine Description:
  345. IcoExtractIconGroupFromIcoFile extracts the icon group from an ICO file.
  346. Arguments:
  347. IcoFile - Specifies the name of the ICO file to be processed.
  348. Return value:
  349. An icon group if successfull, NULL otherwise.
  350. --*/
  351. {
  352. HANDLE icoFileHandle;
  353. PICON_GROUP result = NULL;
  354. icoFileHandle = BfOpenReadFileA (IcoFile);
  355. if (!icoFileHandle) {
  356. return NULL;
  357. }
  358. result = IcoExtractIconGroupFromIcoFileEx (icoFileHandle);
  359. CloseHandle (icoFileHandle);
  360. return result;
  361. }
  362. PICON_GROUP
  363. IcoExtractIconGroupFromIcoFileW (
  364. IN PCWSTR IcoFile
  365. )
  366. /*++
  367. Routine Description:
  368. IcoExtractIconGroupFromIcoFile extracts the icon group from an ICO file.
  369. Arguments:
  370. IcoFile - Specifies the name of the ICO file to be processed.
  371. Return value:
  372. An icon group if successfull, NULL otherwise.
  373. --*/
  374. {
  375. HANDLE icoFileHandle;
  376. PICON_GROUP result = NULL;
  377. icoFileHandle = BfOpenReadFileW (IcoFile);
  378. if (!icoFileHandle) {
  379. return NULL;
  380. }
  381. result = IcoExtractIconGroupFromIcoFileEx (icoFileHandle);
  382. CloseHandle (icoFileHandle);
  383. return result;
  384. }
  385. BOOL
  386. IcoWriteIconGroupToIcoFileEx (
  387. IN HANDLE IcoFileHandle,
  388. IN PICON_GROUP IconGroup
  389. )
  390. /*++
  391. Routine Description:
  392. IcoWriteIconGroupToIcoFileEx writes an icon group to an ICO file. The file has to exist and it's
  393. content will be overwritten.
  394. Arguments:
  395. IcoFileHandle - Specifies the handle of the ICO file to be processed.
  396. IconGroup - Specifies the icon group to be written.
  397. Return value:
  398. TRUE if successfull, FALSE otherwise.
  399. --*/
  400. {
  401. PICONDIR iconDir = NULL;
  402. DWORD iconDirSize = 0;
  403. DWORD elapsedSize = 0;
  404. WORD i;
  405. BOOL result = FALSE;
  406. __try {
  407. if (!BfSetFilePointer (IcoFileHandle, 0)) {
  408. __leave;
  409. }
  410. iconDirSize = sizeof (ICONDIRBASE) + IconGroup->IconsCount * sizeof (ICONDIRENTRY);
  411. iconDir = (PICONDIR) MemAlloc (g_hHeap, 0, iconDirSize);
  412. ZeroMemory (iconDir, iconDirSize);
  413. iconDir->Type = 1;
  414. iconDir->Count = IconGroup->IconsCount;
  415. elapsedSize = iconDirSize;
  416. for (i = 0; i < IconGroup->IconsCount; i ++) {
  417. iconDir->Entries[i].Width = (IconGroup->Icons [i])->Width;
  418. iconDir->Entries[i].Height = (IconGroup->Icons [i])->Height;
  419. iconDir->Entries[i].ColorCount = (IconGroup->Icons [i])->ColorCount;
  420. iconDir->Entries[i].Planes = (IconGroup->Icons [i])->Planes;
  421. iconDir->Entries[i].BitCount = (IconGroup->Icons [i])->BitCount;
  422. iconDir->Entries[i].BytesInRes = (IconGroup->Icons [i])->Size;
  423. iconDir->Entries[i].ImageOffset = elapsedSize;
  424. elapsedSize += (IconGroup->Icons [i])->Size;
  425. }
  426. if (!BfWriteFile (IcoFileHandle, (PBYTE)iconDir, iconDirSize)) {
  427. __leave;
  428. }
  429. for (i = 0; i < IconGroup->IconsCount; i ++) {
  430. if (!BfWriteFile (IcoFileHandle, (IconGroup->Icons [i])->Image, (IconGroup->Icons [i])->Size)) {
  431. __leave;
  432. }
  433. }
  434. result = TRUE;
  435. }
  436. __finally {
  437. }
  438. return result;
  439. }
  440. BOOL
  441. IcoWriteIconGroupToIcoFileA (
  442. IN PCSTR IcoFile,
  443. IN PICON_GROUP IconGroup,
  444. IN BOOL OverwriteExisting
  445. )
  446. /*++
  447. Routine Description:
  448. IcoWriteIconGroupToIcoFile writes an icon group to an ICO file. The file is either created if
  449. does not exist or it is overwritten if OverwriteExisting is TRUE.
  450. Arguments:
  451. IcoFile - Specifies the ICO file to be processed.
  452. IconGroup - Specifies the icon group to be written.
  453. OverwriteExisting - if TRUE and the IcoFile exists, it will be overwritten
  454. Return value:
  455. TRUE if successfull, FALSE otherwise.
  456. --*/
  457. {
  458. HANDLE icoFileHandle;
  459. BOOL result = FALSE;
  460. if (DoesFileExistA (IcoFile)) {
  461. if (!OverwriteExisting) {
  462. return FALSE;
  463. }
  464. }
  465. icoFileHandle = BfCreateFileA (IcoFile);
  466. if (!icoFileHandle) {
  467. return FALSE;
  468. }
  469. result = IcoWriteIconGroupToIcoFileEx (icoFileHandle, IconGroup);
  470. CloseHandle (icoFileHandle);
  471. if (!result) {
  472. DeleteFileA (IcoFile);
  473. }
  474. return result;
  475. }
  476. BOOL
  477. IcoWriteIconGroupToIcoFileW (
  478. IN PCWSTR IcoFile,
  479. IN PICON_GROUP IconGroup,
  480. IN BOOL OverwriteExisting
  481. )
  482. /*++
  483. Routine Description:
  484. IcoWriteIconGroupToIcoFile writes an icon group to an ICO file. The file is either created if
  485. does not exist or it is overwritten if OverwriteExisting is TRUE.
  486. Arguments:
  487. IcoFile - Specifies the ICO file to be processed.
  488. IconGroup - Specifies the icon group to be written.
  489. OverwriteExisting - if TRUE and the IcoFile exists, it will be overwritten
  490. Return value:
  491. TRUE if successfull, FALSE otherwise.
  492. --*/
  493. {
  494. HANDLE icoFileHandle;
  495. BOOL result = FALSE;
  496. if (DoesFileExistW (IcoFile)) {
  497. if (!OverwriteExisting) {
  498. return FALSE;
  499. }
  500. }
  501. icoFileHandle = BfCreateFileW (IcoFile);
  502. if (!icoFileHandle) {
  503. return FALSE;
  504. }
  505. result = IcoWriteIconGroupToIcoFileEx (icoFileHandle, IconGroup);
  506. CloseHandle (icoFileHandle);
  507. if (!result) {
  508. DeleteFileW (IcoFile);
  509. }
  510. return result;
  511. }
  512. BOOL
  513. CALLBACK
  514. pPeEnumIconGroupA (
  515. HANDLE ModuleHandle,
  516. PCSTR Type,
  517. PSTR Name,
  518. LONG_PTR lParam
  519. )
  520. {
  521. PGROWBUFFER Buf;
  522. PCSTR Num;
  523. CHAR NumBuf[32];
  524. Buf = (PGROWBUFFER) lParam;
  525. if ((ULONG_PTR) Name > 0xffff) {
  526. Num = Name;
  527. } else {
  528. Num = NumBuf;
  529. wsprintfA (NumBuf, "#%u", Name);
  530. }
  531. GbMultiSzAppendA (Buf, Num);
  532. return TRUE;
  533. }
  534. BOOL
  535. CALLBACK
  536. pPeEnumIconGroupW (
  537. HANDLE ModuleHandle,
  538. PCWSTR Type,
  539. PWSTR Name,
  540. LONG_PTR lParam
  541. )
  542. {
  543. PGROWBUFFER Buf;
  544. PCWSTR Num;
  545. WCHAR NumBuf[32];
  546. Buf = (PGROWBUFFER) lParam;
  547. if ((ULONG_PTR) Name > 0xffff) {
  548. Num = Name;
  549. } else {
  550. Num = NumBuf;
  551. wsprintfW (NumBuf, L"#%u", Name);
  552. }
  553. GbMultiSzAppendW (Buf, Num);
  554. return TRUE;
  555. }
  556. INT
  557. IcoGetIndexFromPeResourceIdExA (
  558. IN HANDLE ModuleHandle,
  559. IN PCSTR GroupIconId
  560. )
  561. /*++
  562. Routine Description:
  563. IcoGetIndexFromPeResourceIdEx returns the index of an icon group resource given the
  564. resource ID. It knows how to process only PE files.
  565. Arguments:
  566. ModuleHandle - Specifies the handle to the PE file to be processed.
  567. GroupIconId - Specifies the resource ID.
  568. Return value:
  569. The index of GroupIconId resource if existent, -1 if not.
  570. --*/
  571. {
  572. GROWBUFFER buffer = INIT_GROWBUFFER;
  573. MULTISZ_ENUMA multiSzEnum;
  574. CHAR NumBuf[32];
  575. INT index = 0;
  576. BOOL result = FALSE;
  577. if ((ULONG_PTR) GroupIconId < 0x10000) {
  578. wsprintfA (NumBuf, "#%u", GroupIconId);
  579. GroupIconId = NumBuf;
  580. }
  581. if (EnumResourceNamesA (ModuleHandle, (PCSTR) RT_GROUP_ICON, pPeEnumIconGroupA, (LONG_PTR) (&buffer))) {
  582. GbMultiSzAppendA (&buffer, "");
  583. if (EnumFirstMultiSzA (&multiSzEnum, (PCSTR)(buffer.Buf))) {
  584. do {
  585. if (StringIMatchA (multiSzEnum.CurrentString, GroupIconId)) {
  586. result = TRUE;
  587. break;
  588. }
  589. index ++;
  590. } while (EnumNextMultiSzA (&multiSzEnum));
  591. }
  592. }
  593. if (!result) {
  594. index = -1;
  595. }
  596. return index;
  597. }
  598. INT
  599. IcoGetIndexFromPeResourceIdExW (
  600. IN HANDLE ModuleHandle,
  601. IN PCWSTR GroupIconId
  602. )
  603. /*++
  604. Routine Description:
  605. IcoGetIndexFromPeResourceIdEx returns the index of an icon group resource given the
  606. resource ID. It knows how to process only PE files.
  607. Arguments:
  608. ModuleHandle - Specifies the handle to the PE file to be processed.
  609. GroupIconId - Specifies the resource ID.
  610. Return value:
  611. The index of GroupIconId resource if existent, -1 if not.
  612. --*/
  613. {
  614. GROWBUFFER buffer = INIT_GROWBUFFER;
  615. MULTISZ_ENUMW multiSzEnum;
  616. WCHAR NumBuf[32];
  617. INT index = 0;
  618. BOOL result = FALSE;
  619. if ((ULONG_PTR) GroupIconId < 0x10000) {
  620. wsprintfW (NumBuf, L"#%u", GroupIconId);
  621. GroupIconId = NumBuf;
  622. }
  623. if (EnumResourceNamesW (
  624. ModuleHandle,
  625. (PCWSTR) RT_GROUP_ICON,
  626. pPeEnumIconGroupW,
  627. (LONG_PTR) (&buffer)
  628. )) {
  629. GbMultiSzAppendW (&buffer, L"");
  630. if (EnumFirstMultiSzW (&multiSzEnum, (PCWSTR)(buffer.Buf))) {
  631. do {
  632. if (StringIMatchW (multiSzEnum.CurrentString, GroupIconId)) {
  633. result = TRUE;
  634. break;
  635. }
  636. index ++;
  637. } while (EnumNextMultiSzW (&multiSzEnum));
  638. }
  639. }
  640. if (!result) {
  641. index = -1;
  642. }
  643. return index;
  644. }
  645. INT
  646. IcoGetIndexFromPeResourceIdA (
  647. IN PCSTR ModuleName,
  648. IN PCSTR GroupIconId
  649. )
  650. /*++
  651. Routine Description:
  652. IcoGetIndexFromPeResourceId returns the index of an icon group resource given the
  653. resource ID. It knows how to process only PE files.
  654. Arguments:
  655. ModuleName - Specifies the PE file to be processed.
  656. GroupIconId - Specifies the resource ID.
  657. Return value:
  658. The index of GroupIconId resource if existent, -1 if not.
  659. --*/
  660. {
  661. HANDLE moduleHandle;
  662. INT result = -1;
  663. moduleHandle = LoadLibraryExA (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
  664. if (moduleHandle) {
  665. result = IcoGetIndexFromPeResourceIdExA (moduleHandle, GroupIconId);
  666. FreeLibrary (moduleHandle);
  667. }
  668. return result;
  669. }
  670. INT
  671. IcoGetIndexFromPeResourceIdW (
  672. IN PCWSTR ModuleName,
  673. IN PCWSTR GroupIconId
  674. )
  675. /*++
  676. Routine Description:
  677. IcoGetIndexFromPeResourceId returns the index of an icon group resource given the
  678. resource ID. It knows how to process only PE files.
  679. Arguments:
  680. ModuleName - Specifies the PE file to be processed.
  681. GroupIconId - Specifies the resource ID.
  682. Return value:
  683. The index of GroupIconId resource if existent, -1 if not.
  684. --*/
  685. {
  686. HANDLE moduleHandle;
  687. INT result = -1;
  688. moduleHandle = LoadLibraryExW (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
  689. if (moduleHandle) {
  690. result = IcoGetIndexFromPeResourceIdExW (moduleHandle, GroupIconId);
  691. FreeLibrary (moduleHandle);
  692. }
  693. return result;
  694. }
  695. PICON_GROUP
  696. IcoExtractIconGroupFromPeFileExA (
  697. IN HANDLE ModuleHandle,
  698. IN PCSTR GroupIconId,
  699. OUT PINT Index OPTIONAL
  700. )
  701. /*++
  702. Routine Description:
  703. IcoExtractIconGroupFromPeFileEx extracts an icon group from a PE file.
  704. Arguments:
  705. ModuleHandle - Specifies the handle to the PE file to be processed.
  706. GroupIconId - Specifies the resource ID of the icon group to be extracted.
  707. Index - Receives the index of the icon group extracted.
  708. Return value:
  709. An icon group if successfull, NULL otherwise.
  710. --*/
  711. {
  712. PMHANDLE iconPool = NULL;
  713. PICON_GROUP iconGroup = NULL;
  714. DWORD iconGroupSize = 0;
  715. PICON_IMAGE iconImage = NULL;
  716. PGRPICONDIRENTRY iconDirEntry;
  717. HRSRC resourceHandle;
  718. HGLOBAL resourceBlock;
  719. PBYTE resourceData;
  720. DWORD resourceSize;
  721. PGRPICONDIR groupIconDir;
  722. WORD groupIconDirCount;
  723. WORD gap;
  724. WORD i;
  725. BOOL result = FALSE;
  726. __try {
  727. resourceHandle = FindResourceA (ModuleHandle, GroupIconId, (PCSTR) RT_GROUP_ICON);
  728. if (!resourceHandle) {
  729. __leave;
  730. }
  731. resourceBlock = LoadResource (ModuleHandle, resourceHandle);
  732. if (!resourceBlock) {
  733. __leave;
  734. }
  735. groupIconDir = (PGRPICONDIR) LockResource (resourceBlock);
  736. if (!groupIconDir) {
  737. __leave;
  738. }
  739. iconPool = PmCreateNamedPool ("Icon");
  740. if (!iconPool) {
  741. __leave;
  742. }
  743. // First let's do some validation of all the icons from this icon group
  744. groupIconDirCount = groupIconDir->Count;
  745. for (i = 0; i < groupIconDir->Count; i ++) {
  746. resourceHandle = FindResourceA (ModuleHandle, (PCSTR) (groupIconDir->Entries[i].ID), (PCSTR) RT_ICON);
  747. if (!resourceHandle) {
  748. groupIconDirCount --;
  749. continue;
  750. }
  751. resourceBlock = LoadResource (ModuleHandle, resourceHandle);
  752. if (!resourceBlock) {
  753. groupIconDirCount --;
  754. continue;
  755. }
  756. resourceData = (PBYTE) LockResource (resourceBlock);
  757. if (!resourceData) {
  758. FreeResource (resourceBlock);
  759. groupIconDirCount --;
  760. continue;
  761. }
  762. resourceSize = SizeofResource (ModuleHandle, resourceHandle);
  763. if (!resourceSize) {
  764. FreeResource (resourceBlock);
  765. groupIconDirCount --;
  766. continue;
  767. }
  768. }
  769. iconGroupSize = sizeof (ICON_GROUP) + groupIconDirCount * sizeof (PICON_IMAGE);
  770. iconGroup = (PICON_GROUP) PmGetAlignedMemory (iconPool, iconGroupSize);
  771. ZeroMemory (iconGroup, iconGroupSize);
  772. iconGroup->Pool = iconPool;
  773. iconGroup->IconsCount = groupIconDirCount;
  774. gap = 0;
  775. for (i = 0; i < groupIconDir->Count; i ++) {
  776. resourceHandle = FindResourceA (ModuleHandle, (PCSTR) (groupIconDir->Entries[i].ID), (PCSTR) RT_ICON);
  777. if (!resourceHandle) {
  778. gap ++;
  779. continue;
  780. }
  781. resourceBlock = LoadResource (ModuleHandle, resourceHandle);
  782. if (!resourceBlock) {
  783. gap ++;
  784. continue;
  785. }
  786. resourceData = (PBYTE) LockResource (resourceBlock);
  787. if (!resourceData) {
  788. FreeResource (resourceBlock);
  789. gap ++;
  790. continue;
  791. }
  792. resourceSize = SizeofResource (ModuleHandle, resourceHandle);
  793. if (!resourceSize) {
  794. FreeResource (resourceBlock);
  795. gap ++;
  796. continue;
  797. }
  798. iconImage = (PICON_IMAGE) PmGetAlignedMemory (iconPool, sizeof (ICON_IMAGE));
  799. ZeroMemory (iconImage, sizeof (ICON_IMAGE));
  800. iconDirEntry = &groupIconDir->Entries[i];
  801. iconImage->Width = iconDirEntry->Width;
  802. iconImage->Height = iconDirEntry->Height;
  803. iconImage->ColorCount = iconDirEntry->ColorCount;
  804. iconImage->Planes = iconDirEntry->Planes;
  805. iconImage->BitCount = iconDirEntry->BitCount;
  806. iconImage->Size = iconDirEntry->BytesInRes;
  807. if (iconImage->Size > resourceSize) {
  808. iconImage->Size = resourceSize;
  809. }
  810. iconImage->Id = iconDirEntry->ID;
  811. iconImage->Image = PmGetAlignedMemory (iconPool, iconImage->Size);
  812. CopyMemory (iconImage->Image, resourceData, iconImage->Size);
  813. iconGroup->Icons [i - gap] = iconImage;
  814. }
  815. if (Index) {
  816. *Index = IcoGetIndexFromPeResourceIdExA (ModuleHandle, GroupIconId);
  817. }
  818. result = TRUE;
  819. }
  820. __finally {
  821. if (!result) {
  822. if (iconPool) {
  823. PmEmptyPool (iconPool);
  824. PmDestroyPool (iconPool);
  825. iconPool = NULL;
  826. }
  827. iconGroup = NULL;
  828. }
  829. }
  830. return iconGroup;
  831. }
  832. PICON_GROUP
  833. IcoExtractIconGroupFromPeFileExW (
  834. IN HANDLE ModuleHandle,
  835. IN PCWSTR GroupIconId,
  836. OUT PINT Index OPTIONAL
  837. )
  838. /*++
  839. Routine Description:
  840. IcoExtractIconGroupFromPeFileEx extracts an icon group from a PE file.
  841. Arguments:
  842. ModuleHandle - Specifies the handle to the PE file to be processed.
  843. GroupIconId - Specifies the resource ID of the icon group to be extracted.
  844. Index - Receives the index of the icon group extracted.
  845. Return value:
  846. An icon group if successfull, NULL otherwise.
  847. --*/
  848. {
  849. PMHANDLE iconPool = NULL;
  850. PICON_GROUP iconGroup = NULL;
  851. DWORD iconGroupSize = 0;
  852. PICON_IMAGE iconImage = NULL;
  853. PGRPICONDIRENTRY iconDirEntry;
  854. HRSRC resourceHandle;
  855. HGLOBAL resourceBlock;
  856. PBYTE resourceData;
  857. DWORD resourceSize;
  858. PGRPICONDIR groupIconDir;
  859. WORD i;
  860. BOOL result = FALSE;
  861. __try {
  862. resourceHandle = FindResourceW (ModuleHandle, GroupIconId, (PCWSTR) RT_GROUP_ICON);
  863. if (!resourceHandle) {
  864. __leave;
  865. }
  866. resourceBlock = LoadResource (ModuleHandle, resourceHandle);
  867. if (!resourceBlock) {
  868. __leave;
  869. }
  870. groupIconDir = (PGRPICONDIR) LockResource (resourceBlock);
  871. if (!groupIconDir) {
  872. __leave;
  873. }
  874. iconPool = PmCreateNamedPool ("Icon");
  875. if (!iconPool) {
  876. __leave;
  877. }
  878. iconGroupSize = sizeof (ICON_GROUP) + groupIconDir->Count * sizeof (PICON_IMAGE);
  879. iconGroup = (PICON_GROUP) PmGetAlignedMemory (iconPool, iconGroupSize);
  880. ZeroMemory (iconGroup, iconGroupSize);
  881. iconGroup->Pool = iconPool;
  882. iconGroup->IconsCount = groupIconDir->Count;
  883. for (i = 0; i < groupIconDir->Count; i ++) {
  884. resourceHandle = FindResourceW (ModuleHandle, (PCWSTR) (groupIconDir->Entries[i].ID), (PCWSTR) RT_ICON);
  885. if (!resourceHandle) {
  886. __leave;
  887. }
  888. resourceBlock = LoadResource (ModuleHandle, resourceHandle);
  889. if (!resourceBlock) {
  890. __leave;
  891. }
  892. resourceData = (PBYTE) LockResource (resourceBlock);
  893. if (!resourceData) {
  894. __leave;
  895. }
  896. resourceSize = SizeofResource (ModuleHandle, resourceHandle);
  897. if (!resourceSize) {
  898. __leave;
  899. }
  900. iconImage = (PICON_IMAGE) PmGetAlignedMemory (iconPool, sizeof (ICON_IMAGE));
  901. ZeroMemory (iconImage, sizeof (ICON_IMAGE));
  902. iconDirEntry = &groupIconDir->Entries[i];
  903. iconImage->Width = iconDirEntry->Width;
  904. iconImage->Height = iconDirEntry->Height;
  905. iconImage->ColorCount = iconDirEntry->ColorCount;
  906. iconImage->Planes = iconDirEntry->Planes;
  907. iconImage->BitCount = iconDirEntry->BitCount;
  908. iconImage->Size = iconDirEntry->BytesInRes;
  909. if (iconImage->Size > resourceSize) {
  910. iconImage->Size = resourceSize;
  911. }
  912. iconImage->Id = iconDirEntry->ID;
  913. iconImage->Image = PmGetAlignedMemory (iconPool, iconImage->Size);
  914. CopyMemory (iconImage->Image, resourceData, iconImage->Size);
  915. iconGroup->Icons [i] = iconImage;
  916. }
  917. if (Index) {
  918. *Index = IcoGetIndexFromPeResourceIdExW (ModuleHandle, GroupIconId);
  919. }
  920. result = TRUE;
  921. }
  922. __finally {
  923. if (!result) {
  924. if (iconPool) {
  925. PmEmptyPool (iconPool);
  926. PmDestroyPool (iconPool);
  927. iconPool = NULL;
  928. }
  929. iconGroup = NULL;
  930. }
  931. }
  932. return iconGroup;
  933. }
  934. PICON_GROUP
  935. IcoExtractIconGroupFromPeFileA (
  936. IN PCSTR ModuleName,
  937. IN PCSTR GroupIconId,
  938. OUT PINT Index OPTIONAL
  939. )
  940. /*++
  941. Routine Description:
  942. IcoExtractIconGroupFromPeFile extracts an icon group from a PE file.
  943. Arguments:
  944. ModuleName - Specifies the PE file to be processed.
  945. GroupIconId - Specifies the resource ID of the icon group to be extracted.
  946. Index - Receives the index of the icon group extracted.
  947. Return value:
  948. An icon group if successfull, NULL otherwise.
  949. --*/
  950. {
  951. HANDLE moduleHandle;
  952. PICON_GROUP result = NULL;
  953. moduleHandle = LoadLibraryExA (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
  954. if (moduleHandle) {
  955. result = IcoExtractIconGroupFromPeFileExA (moduleHandle, GroupIconId, Index);
  956. FreeLibrary (moduleHandle);
  957. }
  958. return result;
  959. }
  960. PICON_GROUP
  961. IcoExtractIconGroupFromPeFileW (
  962. IN PCWSTR ModuleName,
  963. IN PCWSTR GroupIconId,
  964. OUT PINT Index OPTIONAL
  965. )
  966. /*++
  967. Routine Description:
  968. IcoExtractIconGroupFromPeFile extracts an icon group from a PE file.
  969. Arguments:
  970. ModuleName - Specifies the PE file to be processed.
  971. GroupIconId - Specifies the resource ID of the icon group to be extracted.
  972. Index - Receives the index of the icon group extracted.
  973. Return value:
  974. An icon group if successfull, NULL otherwise.
  975. --*/
  976. {
  977. HANDLE moduleHandle;
  978. PICON_GROUP result = NULL;
  979. moduleHandle = LoadLibraryExW (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
  980. if (moduleHandle) {
  981. result = IcoExtractIconGroupFromPeFileExW (moduleHandle, GroupIconId, Index);
  982. FreeLibrary (moduleHandle);
  983. }
  984. return result;
  985. }
  986. VOID
  987. IcoAbortPeEnumIconGroupA (
  988. IN OUT PICON_ENUMA IconEnum
  989. )
  990. /*++
  991. Routine Description:
  992. IcoAbortPeEnumIconGroup terminates the icon group enumeration from a PE file.
  993. Arguments:
  994. IconEnum - Specifies the icon group enumeration structure. It is emptied during this function.
  995. Return value:
  996. None
  997. --*/
  998. {
  999. GbFree (&IconEnum->Buffer);
  1000. if (IconEnum->FreeHandle && IconEnum->ModuleHandle) {
  1001. FreeLibrary (IconEnum->ModuleHandle);
  1002. }
  1003. if (IconEnum->IconGroup) {
  1004. IcoReleaseIconGroup (IconEnum->IconGroup);
  1005. }
  1006. if (IconEnum->ResourceId) {
  1007. FreePathStringA (IconEnum->ResourceId);
  1008. IconEnum->ResourceId = NULL;
  1009. }
  1010. ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
  1011. }
  1012. VOID
  1013. IcoAbortPeEnumIconGroupW (
  1014. IN OUT PICON_ENUMW IconEnum
  1015. )
  1016. /*++
  1017. Routine Description:
  1018. IcoAbortPeEnumIconGroup terminates the icon group enumeration from a PE file.
  1019. Arguments:
  1020. IconEnum - Specifies the icon group enumeration structure. It is emptied during this function.
  1021. Return value:
  1022. None
  1023. --*/
  1024. {
  1025. GbFree (&IconEnum->Buffer);
  1026. if (IconEnum->FreeHandle && IconEnum->ModuleHandle) {
  1027. FreeLibrary (IconEnum->ModuleHandle);
  1028. }
  1029. if (IconEnum->IconGroup) {
  1030. IcoReleaseIconGroup (IconEnum->IconGroup);
  1031. }
  1032. if (IconEnum->ResourceId) {
  1033. FreePathStringW (IconEnum->ResourceId);
  1034. IconEnum->ResourceId = NULL;
  1035. }
  1036. ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
  1037. }
  1038. BOOL
  1039. pEnumFirstIconGroupInPeFileExA (
  1040. IN OUT PICON_ENUMA IconEnum
  1041. )
  1042. {
  1043. BOOL result = FALSE;
  1044. if (EnumResourceNamesA (
  1045. IconEnum->ModuleHandle,
  1046. (PCSTR) RT_GROUP_ICON,
  1047. pPeEnumIconGroupA,
  1048. (LONG_PTR) (&IconEnum->Buffer)
  1049. )) {
  1050. GbMultiSzAppendA (&IconEnum->Buffer, "");
  1051. if (EnumFirstMultiSzA (&IconEnum->MultiSzEnum, (PCSTR)(IconEnum->Buffer.Buf))) {
  1052. IconEnum->IconGroup = IcoExtractIconGroupFromPeFileExA (IconEnum->ModuleHandle, IconEnum->MultiSzEnum.CurrentString, NULL);
  1053. result = (IconEnum->IconGroup != NULL);
  1054. if (result) {
  1055. IconEnum->ResourceId = DuplicatePathStringA (IconEnum->MultiSzEnum.CurrentString, 0);
  1056. }
  1057. }
  1058. }
  1059. if (!result) {
  1060. IcoAbortPeEnumIconGroupA (IconEnum);
  1061. }
  1062. return result;
  1063. }
  1064. BOOL
  1065. pEnumFirstIconGroupInPeFileExW (
  1066. IN OUT PICON_ENUMW IconEnum
  1067. )
  1068. {
  1069. BOOL result = FALSE;
  1070. if (EnumResourceNamesW (
  1071. IconEnum->ModuleHandle,
  1072. (PCWSTR) RT_GROUP_ICON,
  1073. pPeEnumIconGroupW,
  1074. (LONG_PTR) (&IconEnum->Buffer)
  1075. )) {
  1076. GbMultiSzAppendW (&IconEnum->Buffer, L"");
  1077. if (EnumFirstMultiSzW (&IconEnum->MultiSzEnum, (PCWSTR)(IconEnum->Buffer.Buf))) {
  1078. IconEnum->IconGroup = IcoExtractIconGroupFromPeFileExW (IconEnum->ModuleHandle, IconEnum->MultiSzEnum.CurrentString, NULL);
  1079. result = (IconEnum->IconGroup != NULL);
  1080. if (result) {
  1081. IconEnum->ResourceId = DuplicatePathStringW (IconEnum->MultiSzEnum.CurrentString, 0);
  1082. }
  1083. }
  1084. }
  1085. if (!result) {
  1086. IcoAbortPeEnumIconGroupW (IconEnum);
  1087. }
  1088. return result;
  1089. }
  1090. BOOL
  1091. IcoEnumFirstIconGroupInPeFileExA (
  1092. IN HANDLE ModuleHandle,
  1093. OUT PICON_ENUMA IconEnum
  1094. )
  1095. /*++
  1096. Routine Description:
  1097. IcoEnumFirstIconGroupInPeFileEx starts the icon group enumeration from a PE file.
  1098. Arguments:
  1099. ModuleHandle - Specifies the handle to the PE file to be processed.
  1100. IconEnum - Receives the icon group enumeration structure.
  1101. Return value:
  1102. TRUE if at least one icon group exists, FALSE otherwise.
  1103. --*/
  1104. {
  1105. BOOL result = FALSE;
  1106. ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
  1107. IconEnum->FreeHandle = FALSE;
  1108. IconEnum->ModuleHandle = ModuleHandle;
  1109. if (IconEnum->ModuleHandle) {
  1110. result = pEnumFirstIconGroupInPeFileExA (IconEnum);
  1111. }
  1112. return result;
  1113. }
  1114. BOOL
  1115. IcoEnumFirstIconGroupInPeFileExW (
  1116. IN HANDLE ModuleHandle,
  1117. OUT PICON_ENUMW IconEnum
  1118. )
  1119. /*++
  1120. Routine Description:
  1121. IcoEnumFirstIconGroupInPeFileEx starts the icon group enumeration from a PE file.
  1122. Arguments:
  1123. ModuleHandle - Specifies the handle to the PE file to be processed.
  1124. IconEnum - Receives the icon group enumeration structure.
  1125. Return value:
  1126. TRUE if at least one icon group exists, FALSE otherwise.
  1127. --*/
  1128. {
  1129. BOOL result = FALSE;
  1130. ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
  1131. IconEnum->FreeHandle = FALSE;
  1132. IconEnum->ModuleHandle = ModuleHandle;
  1133. if (IconEnum->ModuleHandle) {
  1134. result = pEnumFirstIconGroupInPeFileExW (IconEnum);
  1135. }
  1136. return result;
  1137. }
  1138. BOOL
  1139. IcoEnumFirstIconGroupInPeFileA (
  1140. IN PCSTR ModuleName,
  1141. OUT PICON_ENUMA IconEnum
  1142. )
  1143. /*++
  1144. Routine Description:
  1145. IcoEnumFirstIconGroupInPeFile starts the icon group enumeration from a PE file.
  1146. Arguments:
  1147. ModuleName - Specifies the PE file to be processed.
  1148. IconEnum - Receives the icon group enumeration structure.
  1149. Return value:
  1150. TRUE if at least one icon group exists, FALSE otherwise.
  1151. --*/
  1152. {
  1153. BOOL result = FALSE;
  1154. ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
  1155. IconEnum->FreeHandle = TRUE;
  1156. IconEnum->ModuleHandle = LoadLibraryExA (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
  1157. if (IconEnum->ModuleHandle) {
  1158. result = pEnumFirstIconGroupInPeFileExA (IconEnum);
  1159. }
  1160. return result;
  1161. }
  1162. BOOL
  1163. IcoEnumFirstIconGroupInPeFileW (
  1164. IN PCWSTR ModuleName,
  1165. OUT PICON_ENUMW IconEnum
  1166. )
  1167. /*++
  1168. Routine Description:
  1169. IcoEnumFirstIconGroupInPeFile starts the icon group enumeration from a PE file.
  1170. Arguments:
  1171. ModuleName - Specifies the PE file to be processed.
  1172. IconEnum - Receives the icon group enumeration structure.
  1173. Return value:
  1174. TRUE if at least one icon group exists, FALSE otherwise.
  1175. --*/
  1176. {
  1177. BOOL result = FALSE;
  1178. ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
  1179. IconEnum->FreeHandle = TRUE;
  1180. IconEnum->ModuleHandle = LoadLibraryExW (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
  1181. if (IconEnum->ModuleHandle) {
  1182. result = pEnumFirstIconGroupInPeFileExW (IconEnum);
  1183. }
  1184. return result;
  1185. }
  1186. BOOL
  1187. IcoEnumNextIconGroupInPeFileA (
  1188. IN OUT PICON_ENUMA IconEnum
  1189. )
  1190. /*++
  1191. Routine Description:
  1192. IcoEnumNextIconGroupInPeFile continues the icon group enumeration from a PE file.
  1193. Arguments:
  1194. IconEnum - Specifies and receives the icon group enumeration structure.
  1195. Return value:
  1196. TRUE if one more icon group exists, FALSE otherwise.
  1197. --*/
  1198. {
  1199. BOOL result = FALSE;
  1200. if (IconEnum->IconGroup) {
  1201. IcoReleaseIconGroup (IconEnum->IconGroup);
  1202. IconEnum->IconGroup = NULL;
  1203. }
  1204. if (IconEnum->ResourceId) {
  1205. FreePathStringA (IconEnum->ResourceId);
  1206. IconEnum->ResourceId = NULL;
  1207. }
  1208. if (EnumNextMultiSzA (&IconEnum->MultiSzEnum)) {
  1209. IconEnum->IconGroup = IcoExtractIconGroupFromPeFileExA (IconEnum->ModuleHandle, IconEnum->MultiSzEnum.CurrentString, NULL);
  1210. result = (IconEnum->IconGroup != NULL);
  1211. if (result) {
  1212. IconEnum->ResourceId = DuplicatePathStringA (IconEnum->MultiSzEnum.CurrentString, 0);
  1213. IconEnum->Index ++;
  1214. }
  1215. }
  1216. if (!result) {
  1217. IcoAbortPeEnumIconGroupA (IconEnum);
  1218. }
  1219. return result;
  1220. }
  1221. BOOL
  1222. IcoEnumNextIconGroupInPeFileW (
  1223. IN OUT PICON_ENUMW IconEnum
  1224. )
  1225. /*++
  1226. Routine Description:
  1227. IcoEnumNextIconGroupInPeFile continues the icon group enumeration from a PE file.
  1228. Arguments:
  1229. IconEnum - Specifies and receives the icon group enumeration structure.
  1230. Return value:
  1231. TRUE if one more icon group exists, FALSE otherwise.
  1232. --*/
  1233. {
  1234. BOOL result = FALSE;
  1235. if (IconEnum->IconGroup) {
  1236. IcoReleaseIconGroup (IconEnum->IconGroup);
  1237. IconEnum->IconGroup = NULL;
  1238. }
  1239. if (IconEnum->ResourceId) {
  1240. FreePathStringW (IconEnum->ResourceId);
  1241. IconEnum->ResourceId = NULL;
  1242. }
  1243. if (EnumNextMultiSzW (&IconEnum->MultiSzEnum)) {
  1244. IconEnum->IconGroup = IcoExtractIconGroupFromPeFileExW (IconEnum->ModuleHandle, IconEnum->MultiSzEnum.CurrentString, NULL);
  1245. result = (IconEnum->IconGroup != NULL);
  1246. if (result) {
  1247. IconEnum->ResourceId = DuplicatePathStringW (IconEnum->MultiSzEnum.CurrentString, 0);
  1248. IconEnum->Index ++;
  1249. }
  1250. }
  1251. if (!result) {
  1252. IcoAbortPeEnumIconGroupW (IconEnum);
  1253. }
  1254. return result;
  1255. }
  1256. PICON_GROUP
  1257. IcoExtractIconGroupByIndexFromPeFileExA (
  1258. IN HANDLE ModuleHandle,
  1259. IN INT Index,
  1260. OUT PCSTR *GroupIconId OPTIONAL
  1261. )
  1262. /*++
  1263. Routine Description:
  1264. IcoExtractIconGroupByIndexFromPeFileEx extracts an icon group from a PE file
  1265. using the Index.
  1266. Arguments:
  1267. ModuleHandle - Specifies the handle to the PE file to be processed.
  1268. Index - Specifies the index of the icon group to be extracted.
  1269. GroupIconId - Receives the resource ID of the icon group extracted.
  1270. Return value:
  1271. An icon group if successfull, NULL otherwise.
  1272. --*/
  1273. {
  1274. ICON_ENUMA iconEnum;
  1275. PICON_GROUP result = NULL;
  1276. if (IcoEnumFirstIconGroupInPeFileExA (ModuleHandle, &iconEnum)) {
  1277. do {
  1278. if (iconEnum.Index == Index) {
  1279. result = iconEnum.IconGroup;
  1280. iconEnum.IconGroup = NULL;
  1281. if (GroupIconId) {
  1282. *GroupIconId = iconEnum.ResourceId;
  1283. iconEnum.ResourceId = NULL;
  1284. }
  1285. break;
  1286. }
  1287. } while (IcoEnumNextIconGroupInPeFileA (&iconEnum));
  1288. IcoAbortPeEnumIconGroupA (&iconEnum);
  1289. }
  1290. return result;
  1291. }
  1292. PICON_GROUP
  1293. IcoExtractIconGroupByIndexFromPeFileExW (
  1294. IN HANDLE ModuleHandle,
  1295. IN INT Index,
  1296. OUT PCWSTR *GroupIconId OPTIONAL
  1297. )
  1298. /*++
  1299. Routine Description:
  1300. IcoExtractIconGroupByIndexFromPeFileEx extracts an icon group from a PE file
  1301. using the Index.
  1302. Arguments:
  1303. ModuleHandle - Specifies the handle to the PE file to be processed.
  1304. Index - Specifies the index of the icon group to be extracted.
  1305. GroupIconId - Receives the resource ID of the icon group extracted.
  1306. Return value:
  1307. An icon group if successfull, NULL otherwise.
  1308. --*/
  1309. {
  1310. ICON_ENUMW iconEnum;
  1311. PICON_GROUP result = NULL;
  1312. if (IcoEnumFirstIconGroupInPeFileExW (ModuleHandle, &iconEnum)) {
  1313. do {
  1314. if (iconEnum.Index == Index) {
  1315. result = iconEnum.IconGroup;
  1316. iconEnum.IconGroup = NULL;
  1317. if (GroupIconId) {
  1318. *GroupIconId = iconEnum.ResourceId;
  1319. iconEnum.ResourceId = NULL;
  1320. }
  1321. break;
  1322. }
  1323. } while (IcoEnumNextIconGroupInPeFileW (&iconEnum));
  1324. IcoAbortPeEnumIconGroupW (&iconEnum);
  1325. }
  1326. return result;
  1327. }
  1328. PICON_GROUP
  1329. IcoExtractIconGroupByIndexFromPeFileA (
  1330. IN PCSTR ModuleName,
  1331. IN INT Index,
  1332. OUT PCSTR *GroupIconId OPTIONAL
  1333. )
  1334. /*++
  1335. Routine Description:
  1336. IcoExtractIconGroupFromPeFile extracts an icon group from a PE file
  1337. using the Index
  1338. Arguments:
  1339. ModuleName - Specifies the PE file to be processed.
  1340. Index - Specifies the index of the icon group to be extracted.
  1341. GroupIconId - Receives the resource ID of the icon group extracted.
  1342. Return value:
  1343. An icon group if successfull, NULL otherwise.
  1344. --*/
  1345. {
  1346. HANDLE moduleHandle;
  1347. PICON_GROUP result = NULL;
  1348. moduleHandle = LoadLibraryExA (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
  1349. if (moduleHandle) {
  1350. result = IcoExtractIconGroupByIndexFromPeFileExA (moduleHandle, Index, GroupIconId);
  1351. FreeLibrary (moduleHandle);
  1352. }
  1353. return result;
  1354. }
  1355. PICON_GROUP
  1356. IcoExtractIconGroupByIndexFromPeFileW (
  1357. IN PCWSTR ModuleName,
  1358. IN INT Index,
  1359. OUT PCWSTR *GroupIconId OPTIONAL
  1360. )
  1361. /*++
  1362. Routine Description:
  1363. IcoExtractIconGroupFromPeFile extracts an icon group from a PE file
  1364. using the Index
  1365. Arguments:
  1366. ModuleName - Specifies the PE file to be processed.
  1367. Index - Specifies the index of the icon group to be extracted.
  1368. GroupIconId - Receives the resource ID of the icon group extracted.
  1369. Return value:
  1370. An icon group if successfull, NULL otherwise.
  1371. --*/
  1372. {
  1373. HANDLE moduleHandle;
  1374. PICON_GROUP result = NULL;
  1375. moduleHandle = LoadLibraryExW (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
  1376. if (moduleHandle) {
  1377. result = IcoExtractIconGroupByIndexFromPeFileExW (moduleHandle, Index, GroupIconId);
  1378. FreeLibrary (moduleHandle);
  1379. }
  1380. return result;
  1381. }
  1382. WORD
  1383. pGetAvailableResourceA (
  1384. IN HANDLE ModuleHandle,
  1385. IN WORD StartIndex,
  1386. IN PCSTR ResourceType
  1387. )
  1388. {
  1389. WORD lastIndex = StartIndex;
  1390. HRSRC resourceHandle;
  1391. BOOL result = FALSE;
  1392. if (lastIndex == 0) {
  1393. lastIndex ++;
  1394. }
  1395. do {
  1396. resourceHandle = FindResourceA (ModuleHandle, MAKEINTRESOURCEA (lastIndex), ResourceType);
  1397. if (!resourceHandle) {
  1398. break;
  1399. }
  1400. lastIndex ++;
  1401. if (lastIndex == 0) {
  1402. break;
  1403. }
  1404. } while (TRUE);
  1405. return lastIndex;
  1406. }
  1407. WORD
  1408. pGetAvailableResourceW (
  1409. IN HANDLE ModuleHandle,
  1410. IN WORD StartIndex,
  1411. IN PCWSTR ResourceType
  1412. )
  1413. {
  1414. WORD lastIndex = StartIndex;
  1415. HRSRC resourceHandle;
  1416. BOOL result = FALSE;
  1417. if (lastIndex == 0) {
  1418. lastIndex ++;
  1419. }
  1420. do {
  1421. resourceHandle = FindResourceW (ModuleHandle, MAKEINTRESOURCEW (lastIndex), ResourceType);
  1422. if (!resourceHandle) {
  1423. break;
  1424. }
  1425. lastIndex ++;
  1426. if (lastIndex == 0) {
  1427. break;
  1428. }
  1429. } while (TRUE);
  1430. return lastIndex;
  1431. }
  1432. BOOL
  1433. IcoWriteIconGroupToPeFileExA (
  1434. IN HANDLE ModuleHandle,
  1435. IN HANDLE UpdateHandle,
  1436. IN PICON_GROUP IconGroup,
  1437. OUT PCSTR *ResourceId OPTIONAL
  1438. )
  1439. /*++
  1440. Routine Description:
  1441. IcoWriteIconGroupToPeFileEx writes an icon group resource to a PE file.
  1442. Arguments:
  1443. ModuleHandle - Specifies the handle to the PE file to be processed.
  1444. UpdateHandle - Specifies the resource update handle (returned by BeginUpdateResource).
  1445. IconGroup - Specifies the icon group to be inserted.
  1446. ResourceId - Receives the resource ID allocated for the newly inserted icon group.
  1447. Return value:
  1448. TRUE if successfull, FALSE otherwise.
  1449. --*/
  1450. {
  1451. WORD lastIndex = 0;
  1452. WORD lastIconIndex = 0;
  1453. PGRPICONDIR groupIconDir = NULL;
  1454. DWORD groupIconDirSize;
  1455. WORD i;
  1456. BOOL result = FALSE;
  1457. __try {
  1458. lastIndex = pGetAvailableResourceA (ModuleHandle, lastIndex, (PCSTR) RT_GROUP_ICON);
  1459. if (lastIndex == 0) {
  1460. // no more room for resources
  1461. __leave;
  1462. }
  1463. groupIconDirSize = sizeof (GRPICONDIRBASE) + IconGroup->IconsCount * sizeof (GRPICONDIRENTRY);
  1464. groupIconDir = MemAlloc (g_hHeap, 0, groupIconDirSize);
  1465. ZeroMemory (groupIconDir, groupIconDirSize);
  1466. groupIconDir->Type = 1;
  1467. groupIconDir->Count = IconGroup->IconsCount;
  1468. for (i = 0; i < groupIconDir->Count; i ++) {
  1469. groupIconDir->Entries[i].Width = IconGroup->Icons[i]->Width;
  1470. groupIconDir->Entries[i].Height = IconGroup->Icons[i]->Height;
  1471. groupIconDir->Entries[i].ColorCount = IconGroup->Icons[i]->ColorCount;
  1472. groupIconDir->Entries[i].Planes = IconGroup->Icons[i]->Planes;
  1473. groupIconDir->Entries[i].BitCount = IconGroup->Icons[i]->BitCount;
  1474. groupIconDir->Entries[i].BytesInRes = IconGroup->Icons[i]->Size;
  1475. lastIconIndex = pGetAvailableResourceA (ModuleHandle, lastIconIndex, (PCSTR) RT_ICON);
  1476. groupIconDir->Entries[i].ID = lastIconIndex;
  1477. lastIconIndex ++;
  1478. }
  1479. for (i = 0; i < groupIconDir->Count; i ++) {
  1480. if (!UpdateResourceA (
  1481. UpdateHandle,
  1482. (PCSTR) RT_ICON,
  1483. MAKEINTRESOURCEA (groupIconDir->Entries[i].ID),
  1484. MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
  1485. IconGroup->Icons[i]->Image,
  1486. IconGroup->Icons[i]->Size
  1487. )) {
  1488. __leave;
  1489. }
  1490. }
  1491. if (!UpdateResourceA (
  1492. UpdateHandle,
  1493. (PCSTR) RT_GROUP_ICON,
  1494. MAKEINTRESOURCEA (lastIndex),
  1495. MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
  1496. groupIconDir,
  1497. groupIconDirSize
  1498. )) {
  1499. __leave;
  1500. }
  1501. if (ResourceId) {
  1502. *ResourceId = MAKEINTRESOURCEA (lastIndex);
  1503. }
  1504. result = TRUE;
  1505. }
  1506. __finally {
  1507. if (groupIconDir) {
  1508. MemFree (g_hHeap, 0, groupIconDir);
  1509. }
  1510. }
  1511. return result;
  1512. }
  1513. BOOL
  1514. IcoWriteIconGroupToPeFileExW (
  1515. IN HANDLE ModuleHandle,
  1516. IN HANDLE UpdateHandle,
  1517. IN PICON_GROUP IconGroup,
  1518. OUT PCWSTR *ResourceId OPTIONAL
  1519. )
  1520. /*++
  1521. Routine Description:
  1522. IcoWriteIconGroupToPeFileEx writes an icon group resource to a PE file.
  1523. Arguments:
  1524. ModuleHandle - Specifies the handle to the PE file to be processed.
  1525. UpdateHandle - Specifies the resource update handle (returned by BeginUpdateResource).
  1526. IconGroup - Specifies the icon group to be inserted.
  1527. ResourceId - Receives the resource ID allocated for the newly inserted icon group.
  1528. Return value:
  1529. TRUE if successfull, FALSE otherwise.
  1530. --*/
  1531. {
  1532. WORD lastIndex = 0;
  1533. WORD lastIconIndex = 0;
  1534. PGRPICONDIR groupIconDir = NULL;
  1535. DWORD groupIconDirSize;
  1536. WORD i;
  1537. BOOL result = FALSE;
  1538. __try {
  1539. lastIndex = pGetAvailableResourceW (ModuleHandle, lastIndex, (PCWSTR) RT_GROUP_ICON);
  1540. if (lastIndex == 0) {
  1541. // no more room for resources
  1542. __leave;
  1543. }
  1544. groupIconDirSize = sizeof (GRPICONDIRBASE) + IconGroup->IconsCount * sizeof (GRPICONDIRENTRY);
  1545. groupIconDir = MemAlloc (g_hHeap, 0, groupIconDirSize);
  1546. ZeroMemory (groupIconDir, groupIconDirSize);
  1547. groupIconDir->Type = 1;
  1548. groupIconDir->Count = IconGroup->IconsCount;
  1549. for (i = 0; i < groupIconDir->Count; i ++) {
  1550. groupIconDir->Entries[i].Width = IconGroup->Icons[i]->Width;
  1551. groupIconDir->Entries[i].Height = IconGroup->Icons[i]->Height;
  1552. groupIconDir->Entries[i].ColorCount = IconGroup->Icons[i]->ColorCount;
  1553. groupIconDir->Entries[i].Planes = IconGroup->Icons[i]->Planes;
  1554. groupIconDir->Entries[i].BitCount = IconGroup->Icons[i]->BitCount;
  1555. groupIconDir->Entries[i].BytesInRes = IconGroup->Icons[i]->Size;
  1556. lastIconIndex = pGetAvailableResourceW (ModuleHandle, lastIconIndex, (PCWSTR) RT_ICON);
  1557. groupIconDir->Entries[i].ID = lastIconIndex;
  1558. lastIconIndex ++;
  1559. }
  1560. for (i = 0; i < groupIconDir->Count; i ++) {
  1561. if (!UpdateResourceW (
  1562. UpdateHandle,
  1563. (PCWSTR) RT_ICON,
  1564. MAKEINTRESOURCEW (groupIconDir->Entries[i].ID),
  1565. MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
  1566. IconGroup->Icons[i]->Image,
  1567. IconGroup->Icons[i]->Size
  1568. )) {
  1569. __leave;
  1570. }
  1571. }
  1572. if (!UpdateResourceW (
  1573. UpdateHandle,
  1574. (PCWSTR) RT_GROUP_ICON,
  1575. MAKEINTRESOURCEW (lastIndex),
  1576. MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
  1577. groupIconDir,
  1578. groupIconDirSize
  1579. )) {
  1580. __leave;
  1581. }
  1582. if (ResourceId) {
  1583. *ResourceId = MAKEINTRESOURCEW (lastIndex);
  1584. }
  1585. result = TRUE;
  1586. }
  1587. __finally {
  1588. if (groupIconDir) {
  1589. MemFree (g_hHeap, 0, groupIconDir);
  1590. }
  1591. }
  1592. return result;
  1593. }
  1594. BOOL
  1595. IcoWriteIconGroupToPeFileA (
  1596. IN PCSTR ModuleName,
  1597. IN PICON_GROUP IconGroup,
  1598. OUT PCSTR *ResourceId, OPTIONAL
  1599. OUT PINT Index OPTIONAL
  1600. )
  1601. /*++
  1602. Routine Description:
  1603. IcoWriteIconGroupToPeFile writes an icon group resource to a PE file.
  1604. Arguments:
  1605. ModuleName - Specifies the PE file to be processed.
  1606. IconGroup - Specifies the icon group to be inserted.
  1607. ResourceId - Receives the resource ID allocated for the newly inserted icon group.
  1608. Index - Receives the index of the newly inserted icon group.
  1609. Return value:
  1610. TRUE if successfull, FALSE otherwise.
  1611. --*/
  1612. {
  1613. HANDLE moduleHandle = NULL;
  1614. HANDLE updateHandle = NULL;
  1615. PCSTR resourceId;
  1616. BOOL result = FALSE;
  1617. updateHandle = BeginUpdateResourceA (ModuleName, FALSE);
  1618. if (updateHandle) {
  1619. //printf ("BeginUpdateResource\n");
  1620. moduleHandle = LoadLibraryExA (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
  1621. if (moduleHandle) {
  1622. //printf ("IcoWriteIconGroupToPeFileExA\n");
  1623. result = IcoWriteIconGroupToPeFileExA (moduleHandle, updateHandle, IconGroup, &resourceId);
  1624. FreeLibrary (moduleHandle);
  1625. }
  1626. if (result) {
  1627. //printf ("EndUpdateResource\n");
  1628. result = EndUpdateResource (updateHandle, FALSE);
  1629. if (result) {
  1630. if (ResourceId) {
  1631. *ResourceId = resourceId;
  1632. } else {
  1633. IcoReleaseResourceIdA (resourceId);
  1634. }
  1635. if (Index) {
  1636. *Index = IcoGetIndexFromPeResourceIdA (ModuleName, resourceId);
  1637. }
  1638. }
  1639. } else {
  1640. EndUpdateResource (updateHandle, TRUE);
  1641. }
  1642. }
  1643. //printf ("return\n");
  1644. return result;
  1645. }
  1646. BOOL
  1647. IcoWriteIconGroupToPeFileW (
  1648. IN PCWSTR ModuleName,
  1649. IN PICON_GROUP IconGroup,
  1650. OUT PCWSTR *ResourceId, OPTIONAL
  1651. OUT PINT Index OPTIONAL
  1652. )
  1653. /*++
  1654. Routine Description:
  1655. IcoWriteIconGroupToPeFile writes an icon group resource to a PE file.
  1656. Arguments:
  1657. ModuleName - Specifies the PE file to be processed.
  1658. IconGroup - Specifies the icon group to be inserted.
  1659. ResourceId - Receives the resource ID allocated for the newly inserted icon group.
  1660. Index - Receives the index of the newly inserted icon group.
  1661. Return value:
  1662. TRUE if successfull, FALSE otherwise.
  1663. --*/
  1664. {
  1665. HANDLE moduleHandle = NULL;
  1666. HANDLE updateHandle = NULL;
  1667. PCWSTR resourceId;
  1668. BOOL result = FALSE;
  1669. updateHandle = BeginUpdateResourceW (ModuleName, FALSE);
  1670. if (updateHandle) {
  1671. moduleHandle = LoadLibraryExW (ModuleName, NULL, LOAD_LIBRARY_AS_DATAFILE);
  1672. if (moduleHandle) {
  1673. result = IcoWriteIconGroupToPeFileExW (moduleHandle, updateHandle, IconGroup, &resourceId);
  1674. FreeLibrary (moduleHandle);
  1675. }
  1676. if (result) {
  1677. result = EndUpdateResource (updateHandle, FALSE);
  1678. if (result) {
  1679. if (ResourceId) {
  1680. *ResourceId = resourceId;
  1681. } else {
  1682. IcoReleaseResourceIdW (resourceId);
  1683. }
  1684. if (Index) {
  1685. *Index = IcoGetIndexFromPeResourceIdW (ModuleName, resourceId);
  1686. }
  1687. }
  1688. } else {
  1689. EndUpdateResource (updateHandle, TRUE);
  1690. }
  1691. }
  1692. return result;
  1693. }
  1694. BOOL
  1695. pNeEnumIconGroupA (
  1696. IN HANDLE Handle,
  1697. IN PCSTR Type,
  1698. IN PCSTR Name,
  1699. IN LPARAM lParam
  1700. )
  1701. {
  1702. PGROWBUFFER Buf;
  1703. PCSTR Num;
  1704. CHAR NumBuf[32];
  1705. Buf = (PGROWBUFFER) lParam;
  1706. if ((ULONG_PTR) Name > 0xffff) {
  1707. Num = Name;
  1708. } else {
  1709. Num = NumBuf;
  1710. wsprintfA (NumBuf, "#%u", Name);
  1711. }
  1712. GbMultiSzAppendA (Buf, Num);
  1713. return TRUE;
  1714. }
  1715. BOOL
  1716. pNeEnumIconGroupW (
  1717. IN HANDLE Handle,
  1718. IN PCWSTR Type,
  1719. IN PCWSTR Name,
  1720. IN LPARAM lParam
  1721. )
  1722. {
  1723. PGROWBUFFER Buf;
  1724. PCWSTR Num;
  1725. WCHAR NumBuf[32];
  1726. Buf = (PGROWBUFFER) lParam;
  1727. if ((ULONG_PTR) Name > 0xffff) {
  1728. Num = Name;
  1729. } else {
  1730. Num = NumBuf;
  1731. wsprintfW (NumBuf, L"#%u", Name);
  1732. }
  1733. GbMultiSzAppendW (Buf, Num);
  1734. return TRUE;
  1735. }
  1736. INT
  1737. IcoGetIndexFromNeResourceIdExA (
  1738. IN HANDLE ModuleHandle,
  1739. IN PCSTR GroupIconId
  1740. )
  1741. /*++
  1742. Routine Description:
  1743. IcoGetIndexFromNeResourceIdEx returns the index of an icon group resource given the
  1744. resource ID. It knows how to process only NE files.
  1745. Arguments:
  1746. ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
  1747. GroupIconId - Specifies the resource ID.
  1748. Return value:
  1749. The index of GroupIconId resource if existent, -1 if not.
  1750. --*/
  1751. {
  1752. GROWBUFFER buffer = INIT_GROWBUFFER;
  1753. MULTISZ_ENUMA multiSzEnum;
  1754. CHAR NumBuf[32];
  1755. INT index = 0;
  1756. BOOL result = FALSE;
  1757. if ((ULONG_PTR) GroupIconId < 0x10000) {
  1758. wsprintfA (NumBuf, "#%u", GroupIconId);
  1759. GroupIconId = NumBuf;
  1760. }
  1761. if (NeEnumResourceNamesA (
  1762. ModuleHandle,
  1763. (PCSTR) RT_GROUP_ICON,
  1764. pNeEnumIconGroupA,
  1765. (LONG_PTR) (&buffer)
  1766. )) {
  1767. GbMultiSzAppendA (&buffer, "");
  1768. if (EnumFirstMultiSzA (&multiSzEnum, (PCSTR)(buffer.Buf))) {
  1769. do {
  1770. if (StringIMatchA (multiSzEnum.CurrentString, GroupIconId)) {
  1771. result = TRUE;
  1772. break;
  1773. }
  1774. index ++;
  1775. } while (EnumNextMultiSzA (&multiSzEnum));
  1776. }
  1777. }
  1778. if (!result) {
  1779. index = -1;
  1780. }
  1781. return index;
  1782. }
  1783. INT
  1784. IcoGetIndexFromNeResourceIdExW (
  1785. IN HANDLE ModuleHandle,
  1786. IN PCWSTR GroupIconId
  1787. )
  1788. /*++
  1789. Routine Description:
  1790. IcoGetIndexFromNeResourceIdEx returns the index of an icon group resource given the
  1791. resource ID. It knows how to process only NE files.
  1792. Arguments:
  1793. ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
  1794. GroupIconId - Specifies the resource ID.
  1795. Return value:
  1796. The index of GroupIconId resource if existent, -1 if not.
  1797. --*/
  1798. {
  1799. GROWBUFFER buffer = INIT_GROWBUFFER;
  1800. MULTISZ_ENUMW multiSzEnum;
  1801. WCHAR NumBuf[32];
  1802. INT index = 0;
  1803. BOOL result = FALSE;
  1804. if ((ULONG_PTR) GroupIconId < 0x10000) {
  1805. wsprintfW (NumBuf, L"#%u", GroupIconId);
  1806. GroupIconId = NumBuf;
  1807. }
  1808. if (NeEnumResourceNamesW (
  1809. ModuleHandle,
  1810. (PCWSTR) RT_GROUP_ICON,
  1811. pNeEnumIconGroupW,
  1812. (LONG_PTR) (&buffer)
  1813. )) {
  1814. GbMultiSzAppendW (&buffer, L"");
  1815. if (EnumFirstMultiSzW (&multiSzEnum, (PCWSTR)(buffer.Buf))) {
  1816. do {
  1817. if (StringIMatchW (multiSzEnum.CurrentString, GroupIconId)) {
  1818. result = TRUE;
  1819. break;
  1820. }
  1821. index ++;
  1822. } while (EnumNextMultiSzW (&multiSzEnum));
  1823. }
  1824. }
  1825. if (!result) {
  1826. index = -1;
  1827. }
  1828. return index;
  1829. }
  1830. INT
  1831. IcoGetIndexFromNeResourceIdA (
  1832. IN PCSTR ModuleName,
  1833. IN PCSTR GroupIconId
  1834. )
  1835. /*++
  1836. Routine Description:
  1837. IcoGetIndexFromNeResourceId returns the index of an icon group resource given the
  1838. resource ID. It knows how to process only NE files.
  1839. Arguments:
  1840. ModuleName - Specifies the NE file to be processed.
  1841. GroupIconId - Specifies the resource ID.
  1842. Return value:
  1843. The index of GroupIconId resource if existent, -1 if not.
  1844. --*/
  1845. {
  1846. HANDLE moduleHandle;
  1847. INT result = -1;
  1848. moduleHandle = NeOpenFileA (ModuleName);
  1849. if (moduleHandle) {
  1850. result = IcoGetIndexFromNeResourceIdExA (moduleHandle, GroupIconId);
  1851. NeCloseFile (moduleHandle);
  1852. }
  1853. return result;
  1854. }
  1855. INT
  1856. IcoGetIndexFromNeResourceIdW (
  1857. IN PCWSTR ModuleName,
  1858. IN PCWSTR GroupIconId
  1859. )
  1860. /*++
  1861. Routine Description:
  1862. IcoGetIndexFromNeResourceId returns the index of an icon group resource given the
  1863. resource ID. It knows how to process only NE files.
  1864. Arguments:
  1865. ModuleName - Specifies the NE file to be processed.
  1866. GroupIconId - Specifies the resource ID.
  1867. Return value:
  1868. The index of GroupIconId resource if existent, -1 if not.
  1869. --*/
  1870. {
  1871. HANDLE moduleHandle;
  1872. INT result = -1;
  1873. moduleHandle = NeOpenFileW (ModuleName);
  1874. if (moduleHandle) {
  1875. result = IcoGetIndexFromNeResourceIdExW (moduleHandle, GroupIconId);
  1876. NeCloseFile (moduleHandle);
  1877. }
  1878. return result;
  1879. }
  1880. PICON_GROUP
  1881. IcoExtractIconGroupFromNeFileExA (
  1882. IN HANDLE ModuleHandle,
  1883. IN PCSTR GroupIconId,
  1884. OUT PINT Index OPTIONAL
  1885. )
  1886. /*++
  1887. Routine Description:
  1888. IcoExtractIconGroupFromNeFileEx extracts an icon group from a NE file.
  1889. Arguments:
  1890. ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
  1891. GroupIconId - Specifies the resource ID of the icon group to be extracted.
  1892. Index - Receives the index of the icon group extracted.
  1893. Return value:
  1894. An icon group if successfull, NULL otherwise.
  1895. --*/
  1896. {
  1897. PMHANDLE iconPool = NULL;
  1898. PICON_GROUP iconGroup = NULL;
  1899. DWORD iconGroupSize = 0;
  1900. PICON_IMAGE iconImage = NULL;
  1901. PGRPICONDIRENTRY iconDirEntry;
  1902. PBYTE resourceData;
  1903. DWORD resourceSize;
  1904. PGRPICONDIR groupIconDir;
  1905. WORD i;
  1906. BOOL result = FALSE;
  1907. __try {
  1908. groupIconDir = (PGRPICONDIR) NeFindResourceExA (ModuleHandle, (PCSTR) RT_GROUP_ICON, GroupIconId);
  1909. if (!groupIconDir) {
  1910. __leave;
  1911. }
  1912. iconPool = PmCreateNamedPool ("Icon");
  1913. if (!iconPool) {
  1914. __leave;
  1915. }
  1916. iconGroupSize = sizeof (ICON_GROUP) + groupIconDir->Count * sizeof (PICON_IMAGE);
  1917. iconGroup = (PICON_GROUP) PmGetAlignedMemory (iconPool, iconGroupSize);
  1918. ZeroMemory (iconGroup, iconGroupSize);
  1919. iconGroup->Pool = iconPool;
  1920. iconGroup->IconsCount = groupIconDir->Count;
  1921. for (i = 0; i < groupIconDir->Count; i ++) {
  1922. resourceData = NeFindResourceExA (
  1923. ModuleHandle,
  1924. (PCSTR) RT_ICON,
  1925. (PCSTR) groupIconDir->Entries[i].ID
  1926. );
  1927. if (!resourceData) {
  1928. __leave;
  1929. }
  1930. resourceSize = NeSizeofResourceA (
  1931. ModuleHandle,
  1932. (PCSTR) RT_ICON,
  1933. (PCSTR) groupIconDir->Entries[i].ID
  1934. );
  1935. if (!resourceSize) {
  1936. __leave;
  1937. }
  1938. iconImage = (PICON_IMAGE) PmGetAlignedMemory (iconPool, sizeof (ICON_IMAGE));
  1939. ZeroMemory (iconImage, sizeof (ICON_IMAGE));
  1940. iconDirEntry = &groupIconDir->Entries[i];
  1941. iconImage->Width = iconDirEntry->Width;
  1942. iconImage->Height = iconDirEntry->Height;
  1943. iconImage->ColorCount = iconDirEntry->ColorCount;
  1944. iconImage->Planes = iconDirEntry->Planes;
  1945. iconImage->BitCount = iconDirEntry->BitCount;
  1946. iconImage->Size = iconDirEntry->BytesInRes;
  1947. if (iconImage->Size > resourceSize) {
  1948. iconImage->Size = resourceSize;
  1949. }
  1950. iconImage->Id = iconDirEntry->ID;
  1951. iconImage->Image = PmGetAlignedMemory (iconPool, iconImage->Size);
  1952. CopyMemory (iconImage->Image, resourceData, iconImage->Size);
  1953. iconGroup->Icons [i] = iconImage;
  1954. }
  1955. if (Index) {
  1956. *Index = IcoGetIndexFromNeResourceIdExA (ModuleHandle, GroupIconId);
  1957. }
  1958. result = TRUE;
  1959. }
  1960. __finally {
  1961. if (!result) {
  1962. if (iconPool) {
  1963. PmEmptyPool (iconPool);
  1964. PmDestroyPool (iconPool);
  1965. iconPool = NULL;
  1966. }
  1967. iconGroup = NULL;
  1968. }
  1969. }
  1970. return iconGroup;
  1971. }
  1972. PICON_GROUP
  1973. IcoExtractIconGroupFromNeFileExW (
  1974. IN HANDLE ModuleHandle,
  1975. IN PCWSTR GroupIconId,
  1976. OUT PINT Index OPTIONAL
  1977. )
  1978. /*++
  1979. Routine Description:
  1980. IcoExtractIconGroupFromNeFileEx extracts an icon group from a NE file.
  1981. Arguments:
  1982. ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
  1983. GroupIconId - Specifies the resource ID of the icon group to be extracted.
  1984. Index - Receives the index of the icon group extracted.
  1985. Return value:
  1986. An icon group if successfull, NULL otherwise.
  1987. --*/
  1988. {
  1989. PMHANDLE iconPool = NULL;
  1990. PICON_GROUP iconGroup = NULL;
  1991. DWORD iconGroupSize = 0;
  1992. PICON_IMAGE iconImage = NULL;
  1993. PGRPICONDIRENTRY iconDirEntry;
  1994. PBYTE resourceData;
  1995. DWORD resourceSize;
  1996. PGRPICONDIR groupIconDir;
  1997. WORD i;
  1998. BOOL result = FALSE;
  1999. __try {
  2000. groupIconDir = (PGRPICONDIR) NeFindResourceExW (ModuleHandle, (PCWSTR) RT_GROUP_ICON, GroupIconId);
  2001. if (!groupIconDir) {
  2002. __leave;
  2003. }
  2004. iconPool = PmCreateNamedPool ("Icon");
  2005. if (!iconPool) {
  2006. __leave;
  2007. }
  2008. iconGroupSize = sizeof (ICON_GROUP) + groupIconDir->Count * sizeof (PICON_IMAGE);
  2009. iconGroup = (PICON_GROUP) PmGetAlignedMemory (iconPool, iconGroupSize);
  2010. ZeroMemory (iconGroup, iconGroupSize);
  2011. iconGroup->Pool = iconPool;
  2012. iconGroup->IconsCount = groupIconDir->Count;
  2013. for (i = 0; i < groupIconDir->Count; i ++) {
  2014. resourceData = NeFindResourceExW (
  2015. ModuleHandle,
  2016. (PCWSTR) RT_ICON,
  2017. (PCWSTR) groupIconDir->Entries[i].ID
  2018. );
  2019. if (!resourceData) {
  2020. __leave;
  2021. }
  2022. resourceSize = NeSizeofResourceW (
  2023. ModuleHandle,
  2024. (PCWSTR) RT_ICON,
  2025. (PCWSTR) groupIconDir->Entries[i].ID
  2026. );
  2027. if (!resourceSize) {
  2028. __leave;
  2029. }
  2030. iconImage = (PICON_IMAGE) PmGetAlignedMemory (iconPool, sizeof (ICON_IMAGE));
  2031. ZeroMemory (iconImage, sizeof (ICON_IMAGE));
  2032. iconDirEntry = &groupIconDir->Entries[i];
  2033. iconImage->Width = iconDirEntry->Width;
  2034. iconImage->Height = iconDirEntry->Height;
  2035. iconImage->ColorCount = iconDirEntry->ColorCount;
  2036. iconImage->Planes = iconDirEntry->Planes;
  2037. iconImage->BitCount = iconDirEntry->BitCount;
  2038. iconImage->Size = iconDirEntry->BytesInRes;
  2039. if (iconImage->Size > resourceSize) {
  2040. iconImage->Size = resourceSize;
  2041. }
  2042. iconImage->Id = iconDirEntry->ID;
  2043. iconImage->Image = PmGetAlignedMemory (iconPool, iconImage->Size);
  2044. CopyMemory (iconImage->Image, resourceData, iconImage->Size);
  2045. iconGroup->Icons [i] = iconImage;
  2046. }
  2047. if (Index) {
  2048. *Index = IcoGetIndexFromNeResourceIdExW (ModuleHandle, GroupIconId);
  2049. }
  2050. result = TRUE;
  2051. }
  2052. __finally {
  2053. if (!result) {
  2054. if (iconPool) {
  2055. PmEmptyPool (iconPool);
  2056. PmDestroyPool (iconPool);
  2057. iconPool = NULL;
  2058. }
  2059. iconGroup = NULL;
  2060. }
  2061. }
  2062. return iconGroup;
  2063. }
  2064. PICON_GROUP
  2065. IcoExtractIconGroupFromNeFileA (
  2066. IN PCSTR ModuleName,
  2067. IN PCSTR GroupIconId,
  2068. OUT PINT Index OPTIONAL
  2069. )
  2070. /*++
  2071. Routine Description:
  2072. IcoExtractIconGroupFromNeFile extracts an icon group from a NE file.
  2073. Arguments:
  2074. ModuleName - Specifies the NE file to be processed.
  2075. GroupIconId - Specifies the resource ID of the icon group to be extracted.
  2076. Index - Receives the index of the icon group extracted.
  2077. Return value:
  2078. An icon group if successfull, NULL otherwise.
  2079. --*/
  2080. {
  2081. HANDLE moduleHandle;
  2082. PICON_GROUP result = NULL;
  2083. moduleHandle = NeOpenFileA (ModuleName);
  2084. if (moduleHandle) {
  2085. result = IcoExtractIconGroupFromNeFileExA (moduleHandle, GroupIconId, Index);
  2086. NeCloseFile (moduleHandle);
  2087. }
  2088. return result;
  2089. }
  2090. PICON_GROUP
  2091. IcoExtractIconGroupFromNeFileW (
  2092. IN PCWSTR ModuleName,
  2093. IN PCWSTR GroupIconId,
  2094. OUT PINT Index OPTIONAL
  2095. )
  2096. /*++
  2097. Routine Description:
  2098. IcoExtractIconGroupFromNeFile extracts an icon group from a NE file.
  2099. Arguments:
  2100. ModuleName - Specifies the NE file to be processed.
  2101. GroupIconId - Specifies the resource ID of the icon group to be extracted.
  2102. Index - Receives the index of the icon group extracted.
  2103. Return value:
  2104. An icon group if successfull, NULL otherwise.
  2105. --*/
  2106. {
  2107. HANDLE moduleHandle;
  2108. PICON_GROUP result = NULL;
  2109. moduleHandle = NeOpenFileW (ModuleName);
  2110. if (moduleHandle) {
  2111. result = IcoExtractIconGroupFromNeFileExW (moduleHandle, GroupIconId, Index);
  2112. NeCloseFile (moduleHandle);
  2113. }
  2114. return result;
  2115. }
  2116. VOID
  2117. IcoAbortNeEnumIconGroupA (
  2118. IN OUT PICON_ENUMA IconEnum
  2119. )
  2120. /*++
  2121. Routine Description:
  2122. IcoAbortNeEnumIconGroup terminates the icon group enumeration from a NE file.
  2123. Arguments:
  2124. IconEnum - Specifies the icon group enumeration structure. It is emptied during this function.
  2125. Return value:
  2126. None
  2127. --*/
  2128. {
  2129. GbFree (&IconEnum->Buffer);
  2130. if (IconEnum->FreeHandle && IconEnum->ModuleHandle) {
  2131. NeCloseFile (IconEnum->ModuleHandle);
  2132. }
  2133. if (IconEnum->IconGroup) {
  2134. IcoReleaseIconGroup (IconEnum->IconGroup);
  2135. }
  2136. if (IconEnum->ResourceId) {
  2137. FreePathStringA (IconEnum->ResourceId);
  2138. IconEnum->ResourceId = NULL;
  2139. }
  2140. ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
  2141. }
  2142. VOID
  2143. IcoAbortNeEnumIconGroupW (
  2144. IN OUT PICON_ENUMW IconEnum
  2145. )
  2146. /*++
  2147. Routine Description:
  2148. IcoAbortNeEnumIconGroup terminates the icon group enumeration from a NE file.
  2149. Arguments:
  2150. IconEnum - Specifies the icon group enumeration structure. It is emptied during this function.
  2151. Return value:
  2152. None
  2153. --*/
  2154. {
  2155. GbFree (&IconEnum->Buffer);
  2156. if (IconEnum->FreeHandle && IconEnum->ModuleHandle) {
  2157. NeCloseFile (IconEnum->ModuleHandle);
  2158. }
  2159. if (IconEnum->IconGroup) {
  2160. IcoReleaseIconGroup (IconEnum->IconGroup);
  2161. }
  2162. if (IconEnum->ResourceId) {
  2163. FreePathStringW (IconEnum->ResourceId);
  2164. IconEnum->ResourceId = NULL;
  2165. }
  2166. ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
  2167. }
  2168. BOOL
  2169. pEnumFirstIconGroupInNeFileExA (
  2170. IN OUT PICON_ENUMA IconEnum
  2171. )
  2172. {
  2173. BOOL result = FALSE;
  2174. if (NeEnumResourceNamesA (
  2175. IconEnum->ModuleHandle,
  2176. (PCSTR) RT_GROUP_ICON,
  2177. pNeEnumIconGroupA,
  2178. (LONG_PTR) (&IconEnum->Buffer)
  2179. )) {
  2180. GbMultiSzAppendA (&IconEnum->Buffer, "");
  2181. if (EnumFirstMultiSzA (&IconEnum->MultiSzEnum, (PCSTR)(IconEnum->Buffer.Buf))) {
  2182. IconEnum->IconGroup = IcoExtractIconGroupFromNeFileExA (
  2183. IconEnum->ModuleHandle,
  2184. IconEnum->MultiSzEnum.CurrentString,
  2185. NULL
  2186. );
  2187. result = (IconEnum->IconGroup != NULL);
  2188. if (result) {
  2189. IconEnum->ResourceId = DuplicatePathStringA (IconEnum->MultiSzEnum.CurrentString, 0);
  2190. }
  2191. }
  2192. }
  2193. if (!result) {
  2194. IcoAbortNeEnumIconGroupA (IconEnum);
  2195. }
  2196. return result;
  2197. }
  2198. BOOL
  2199. pEnumFirstIconGroupInNeFileExW (
  2200. IN OUT PICON_ENUMW IconEnum
  2201. )
  2202. {
  2203. BOOL result = FALSE;
  2204. if (NeEnumResourceNamesW (
  2205. IconEnum->ModuleHandle,
  2206. (PCWSTR) RT_GROUP_ICON,
  2207. pNeEnumIconGroupW,
  2208. (LONG_PTR) (&IconEnum->Buffer)
  2209. )) {
  2210. GbMultiSzAppendW (&IconEnum->Buffer, L"");
  2211. if (EnumFirstMultiSzW (&IconEnum->MultiSzEnum, (PCWSTR)(IconEnum->Buffer.Buf))) {
  2212. IconEnum->IconGroup = IcoExtractIconGroupFromNeFileExW (
  2213. IconEnum->ModuleHandle,
  2214. IconEnum->MultiSzEnum.CurrentString,
  2215. NULL
  2216. );
  2217. result = (IconEnum->IconGroup != NULL);
  2218. if (result) {
  2219. IconEnum->ResourceId = DuplicatePathStringW (IconEnum->MultiSzEnum.CurrentString, 0);
  2220. }
  2221. }
  2222. }
  2223. if (!result) {
  2224. IcoAbortNeEnumIconGroupW (IconEnum);
  2225. }
  2226. return result;
  2227. }
  2228. BOOL
  2229. IcoEnumFirstIconGroupInNeFileExA (
  2230. IN HANDLE ModuleHandle,
  2231. OUT PICON_ENUMA IconEnum
  2232. )
  2233. /*++
  2234. Routine Description:
  2235. IcoEnumFirstIconGroupInNeFileEx starts the icon group enumeration from a NE file.
  2236. Arguments:
  2237. ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
  2238. IconEnum - Receives the icon group enumeration structure.
  2239. Return value:
  2240. TRUE if at least one icon group exists, FALSE otherwise.
  2241. --*/
  2242. {
  2243. BOOL result = FALSE;
  2244. ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
  2245. IconEnum->FreeHandle = FALSE;
  2246. IconEnum->ModuleHandle = ModuleHandle;
  2247. if (IconEnum->ModuleHandle) {
  2248. result = pEnumFirstIconGroupInNeFileExA (IconEnum);
  2249. }
  2250. return result;
  2251. }
  2252. BOOL
  2253. IcoEnumFirstIconGroupInNeFileExW (
  2254. IN HANDLE ModuleHandle,
  2255. OUT PICON_ENUMW IconEnum
  2256. )
  2257. /*++
  2258. Routine Description:
  2259. IcoEnumFirstIconGroupInNeFileEx starts the icon group enumeration from a NE file.
  2260. Arguments:
  2261. ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
  2262. IconEnum - Receives the icon group enumeration structure.
  2263. Return value:
  2264. TRUE if at least one icon group exists, FALSE otherwise.
  2265. --*/
  2266. {
  2267. BOOL result = FALSE;
  2268. ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
  2269. IconEnum->FreeHandle = FALSE;
  2270. IconEnum->ModuleHandle = ModuleHandle;
  2271. if (IconEnum->ModuleHandle) {
  2272. result = pEnumFirstIconGroupInNeFileExW (IconEnum);
  2273. }
  2274. return result;
  2275. }
  2276. BOOL
  2277. IcoEnumFirstIconGroupInNeFileA (
  2278. IN PCSTR ModuleName,
  2279. OUT PICON_ENUMA IconEnum
  2280. )
  2281. /*++
  2282. Routine Description:
  2283. IcoEnumFirstIconGroupInNeFile starts the icon group enumeration from a NE file.
  2284. Arguments:
  2285. ModuleName - Specifies the NE file to be processed.
  2286. IconEnum - Receives the icon group enumeration structure.
  2287. Return value:
  2288. TRUE if at least one icon group exists, FALSE otherwise.
  2289. --*/
  2290. {
  2291. BOOL result = FALSE;
  2292. ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
  2293. IconEnum->FreeHandle = TRUE;
  2294. IconEnum->ModuleHandle = NeOpenFileA (ModuleName);
  2295. if (IconEnum->ModuleHandle) {
  2296. result = pEnumFirstIconGroupInNeFileExA (IconEnum);
  2297. }
  2298. return result;
  2299. }
  2300. BOOL
  2301. IcoEnumFirstIconGroupInNeFileW (
  2302. IN PCWSTR ModuleName,
  2303. OUT PICON_ENUMW IconEnum
  2304. )
  2305. /*++
  2306. Routine Description:
  2307. IcoEnumFirstIconGroupInNeFile starts the icon group enumeration from a NE file.
  2308. Arguments:
  2309. ModuleName - Specifies the NE file to be processed.
  2310. IconEnum - Receives the icon group enumeration structure.
  2311. Return value:
  2312. TRUE if at least one icon group exists, FALSE otherwise.
  2313. --*/
  2314. {
  2315. BOOL result = FALSE;
  2316. ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
  2317. IconEnum->FreeHandle = TRUE;
  2318. IconEnum->ModuleHandle = NeOpenFileW (ModuleName);
  2319. if (IconEnum->ModuleHandle) {
  2320. result = pEnumFirstIconGroupInNeFileExW (IconEnum);
  2321. }
  2322. return result;
  2323. }
  2324. BOOL
  2325. IcoEnumNextIconGroupInNeFileA (
  2326. IN OUT PICON_ENUMA IconEnum
  2327. )
  2328. /*++
  2329. Routine Description:
  2330. IcoEnumNextIconGroupInNeFile continues the icon group enumeration from a NE file.
  2331. Arguments:
  2332. IconEnum - Specifies and receives the icon group enumeration structure.
  2333. Return value:
  2334. TRUE if one more icon group exists, FALSE otherwise.
  2335. --*/
  2336. {
  2337. BOOL result = FALSE;
  2338. if (IconEnum->IconGroup) {
  2339. IcoReleaseIconGroup (IconEnum->IconGroup);
  2340. IconEnum->IconGroup = NULL;
  2341. }
  2342. if (IconEnum->ResourceId) {
  2343. FreePathStringA (IconEnum->ResourceId);
  2344. IconEnum->ResourceId = NULL;
  2345. }
  2346. if (EnumNextMultiSzA (&IconEnum->MultiSzEnum)) {
  2347. IconEnum->IconGroup = IcoExtractIconGroupFromNeFileExA (IconEnum->ModuleHandle, IconEnum->MultiSzEnum.CurrentString, NULL);
  2348. result = (IconEnum->IconGroup != NULL);
  2349. if (result) {
  2350. IconEnum->ResourceId = DuplicatePathStringA (IconEnum->MultiSzEnum.CurrentString, 0);
  2351. IconEnum->Index ++;
  2352. }
  2353. }
  2354. if (!result) {
  2355. IcoAbortNeEnumIconGroupA (IconEnum);
  2356. }
  2357. return result;
  2358. }
  2359. BOOL
  2360. IcoEnumNextIconGroupInNeFileW (
  2361. IN OUT PICON_ENUMW IconEnum
  2362. )
  2363. /*++
  2364. Routine Description:
  2365. IcoEnumNextIconGroupInNeFile continues the icon group enumeration from a NE file.
  2366. Arguments:
  2367. IconEnum - Specifies and receives the icon group enumeration structure.
  2368. Return value:
  2369. TRUE if one more icon group exists, FALSE otherwise.
  2370. --*/
  2371. {
  2372. BOOL result = FALSE;
  2373. if (IconEnum->IconGroup) {
  2374. IcoReleaseIconGroup (IconEnum->IconGroup);
  2375. IconEnum->IconGroup = NULL;
  2376. }
  2377. if (IconEnum->ResourceId) {
  2378. FreePathStringW (IconEnum->ResourceId);
  2379. IconEnum->ResourceId = NULL;
  2380. }
  2381. if (EnumNextMultiSzW (&IconEnum->MultiSzEnum)) {
  2382. IconEnum->IconGroup = IcoExtractIconGroupFromNeFileExW (IconEnum->ModuleHandle, IconEnum->MultiSzEnum.CurrentString, NULL);
  2383. result = (IconEnum->IconGroup != NULL);
  2384. if (result) {
  2385. IconEnum->ResourceId = DuplicatePathStringW (IconEnum->MultiSzEnum.CurrentString, 0);
  2386. IconEnum->Index ++;
  2387. }
  2388. }
  2389. if (!result) {
  2390. IcoAbortNeEnumIconGroupW (IconEnum);
  2391. }
  2392. return result;
  2393. }
  2394. PICON_GROUP
  2395. IcoExtractIconGroupByIndexFromNeFileExA (
  2396. IN HANDLE ModuleHandle,
  2397. IN INT Index,
  2398. OUT PCSTR *GroupIconId OPTIONAL
  2399. )
  2400. /*++
  2401. Routine Description:
  2402. IcoExtractIconGroupByIndexFromNeFileEx extracts an icon group from a NE file
  2403. using the Index.
  2404. Arguments:
  2405. ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
  2406. Index - Specifies the index of the icon group to be extracted.
  2407. GroupIconId - Receives the resource ID of the icon group extracted.
  2408. Return value:
  2409. An icon group if successfull, NULL otherwise.
  2410. --*/
  2411. {
  2412. ICON_ENUMA iconEnum;
  2413. PICON_GROUP result = NULL;
  2414. if (IcoEnumFirstIconGroupInNeFileExA (ModuleHandle, &iconEnum)) {
  2415. do {
  2416. if (iconEnum.Index == Index) {
  2417. result = iconEnum.IconGroup;
  2418. iconEnum.IconGroup = NULL;
  2419. if (GroupIconId) {
  2420. *GroupIconId = iconEnum.ResourceId;
  2421. iconEnum.ResourceId = NULL;
  2422. }
  2423. break;
  2424. }
  2425. } while (IcoEnumNextIconGroupInNeFileA (&iconEnum));
  2426. IcoAbortNeEnumIconGroupA (&iconEnum);
  2427. }
  2428. return result;
  2429. }
  2430. PICON_GROUP
  2431. IcoExtractIconGroupByIndexFromNeFileExW (
  2432. IN HANDLE ModuleHandle,
  2433. IN INT Index,
  2434. OUT PCWSTR *GroupIconId OPTIONAL
  2435. )
  2436. /*++
  2437. Routine Description:
  2438. IcoExtractIconGroupByIndexFromNeFileEx extracts an icon group from a NE file
  2439. using the Index.
  2440. Arguments:
  2441. ModuleHandle - Specifies the handle to the NE file to be processed (use NeOpenFile to get it).
  2442. Index - Specifies the index of the icon group to be extracted.
  2443. GroupIconId - Receives the resource ID of the icon group extracted.
  2444. Return value:
  2445. An icon group if successfull, NULL otherwise.
  2446. --*/
  2447. {
  2448. ICON_ENUMW iconEnum;
  2449. PICON_GROUP result = NULL;
  2450. if (IcoEnumFirstIconGroupInNeFileExW (ModuleHandle, &iconEnum)) {
  2451. do {
  2452. if (iconEnum.Index == Index) {
  2453. result = iconEnum.IconGroup;
  2454. iconEnum.IconGroup = NULL;
  2455. if (GroupIconId) {
  2456. *GroupIconId = iconEnum.ResourceId;
  2457. iconEnum.ResourceId = NULL;
  2458. }
  2459. break;
  2460. }
  2461. } while (IcoEnumNextIconGroupInNeFileW (&iconEnum));
  2462. IcoAbortNeEnumIconGroupW (&iconEnum);
  2463. }
  2464. return result;
  2465. }
  2466. PICON_GROUP
  2467. IcoExtractIconGroupByIndexFromNeFileA (
  2468. IN PCSTR ModuleName,
  2469. IN INT Index,
  2470. OUT PCSTR *GroupIconId OPTIONAL
  2471. )
  2472. /*++
  2473. Routine Description:
  2474. IcoExtractIconGroupFromNeFile extracts an icon group from a NE file
  2475. using the Index.
  2476. Arguments:
  2477. ModuleName - Specifies the NE file to be processed.
  2478. Index - Specifies the index of the icon group to be extracted.
  2479. GroupIconId - Receives the resource ID of the icon group extracted.
  2480. Return value:
  2481. An icon group if successfull, NULL otherwise.
  2482. --*/
  2483. {
  2484. HANDLE moduleHandle;
  2485. PICON_GROUP result = NULL;
  2486. moduleHandle = NeOpenFileA (ModuleName);
  2487. if (moduleHandle) {
  2488. result = IcoExtractIconGroupByIndexFromNeFileExA (moduleHandle, Index, GroupIconId);
  2489. NeCloseFile (moduleHandle);
  2490. }
  2491. return result;
  2492. }
  2493. PICON_GROUP
  2494. IcoExtractIconGroupByIndexFromNeFileW (
  2495. IN PCWSTR ModuleName,
  2496. IN INT Index,
  2497. OUT PCWSTR *GroupIconId OPTIONAL
  2498. )
  2499. /*++
  2500. Routine Description:
  2501. IcoExtractIconGroupFromNeFile extracts an icon group from a NE file
  2502. using the Index.
  2503. Arguments:
  2504. ModuleName - Specifies the NE file to be processed.
  2505. Index - Specifies the index of the icon group to be extracted.
  2506. GroupIconId - Receives the resource ID of the icon group extracted.
  2507. Return value:
  2508. An icon group if successfull, NULL otherwise.
  2509. --*/
  2510. {
  2511. HANDLE moduleHandle;
  2512. PICON_GROUP result = NULL;
  2513. moduleHandle = NeOpenFileW (ModuleName);
  2514. if (moduleHandle) {
  2515. result = IcoExtractIconGroupByIndexFromNeFileExW (moduleHandle, Index, GroupIconId);
  2516. NeCloseFile (moduleHandle);
  2517. }
  2518. return result;
  2519. }
  2520. VOID
  2521. IcoAbortEnumIconGroupA (
  2522. IN OUT PICON_ENUMA IconEnum
  2523. )
  2524. /*++
  2525. Routine Description:
  2526. IcoAbortEnumIconGroup terminates the icon group enumeration from a ICO, PE or NE file.
  2527. Arguments:
  2528. IconEnum - Specifies the icon group enumeration structure. It is emptied during this function.
  2529. Return value:
  2530. None
  2531. --*/
  2532. {
  2533. GbFree (&IconEnum->Buffer);
  2534. if (IconEnum->FreeHandle && IconEnum->ModuleHandle) {
  2535. if (IconEnum->FileType == ICON_PEFILE) {
  2536. FreeLibrary (IconEnum->ModuleHandle);
  2537. }
  2538. if (IconEnum->FileType == ICON_NEFILE) {
  2539. NeCloseFile (IconEnum->ModuleHandle);
  2540. }
  2541. }
  2542. if (IconEnum->IconGroup) {
  2543. IcoReleaseIconGroup (IconEnum->IconGroup);
  2544. }
  2545. if (IconEnum->ResourceId) {
  2546. FreePathStringA (IconEnum->ResourceId);
  2547. IconEnum->ResourceId = NULL;
  2548. }
  2549. ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
  2550. }
  2551. VOID
  2552. IcoAbortEnumIconGroupW (
  2553. IN OUT PICON_ENUMW IconEnum
  2554. )
  2555. /*++
  2556. Routine Description:
  2557. IcoAbortEnumIconGroup terminates the icon group enumeration from a ICO, PE or NE file.
  2558. Arguments:
  2559. IconEnum - Specifies the icon group enumeration structure. It is emptied during this function.
  2560. Return value:
  2561. None
  2562. --*/
  2563. {
  2564. GbFree (&IconEnum->Buffer);
  2565. if (IconEnum->FreeHandle && IconEnum->ModuleHandle) {
  2566. if (IconEnum->FileType == ICON_PEFILE) {
  2567. FreeLibrary (IconEnum->ModuleHandle);
  2568. }
  2569. if (IconEnum->FileType == ICON_NEFILE) {
  2570. NeCloseFile (IconEnum->ModuleHandle);
  2571. }
  2572. }
  2573. if (IconEnum->IconGroup) {
  2574. IcoReleaseIconGroup (IconEnum->IconGroup);
  2575. }
  2576. if (IconEnum->ResourceId) {
  2577. FreePathStringW (IconEnum->ResourceId);
  2578. IconEnum->ResourceId = NULL;
  2579. }
  2580. ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
  2581. }
  2582. BOOL
  2583. IcoEnumFirstIconGroupInFileA (
  2584. IN PCSTR FileName,
  2585. OUT PICON_ENUMA IconEnum
  2586. )
  2587. /*++
  2588. Routine Description:
  2589. IcoEnumFirstIconGroupInFile starts the icon group enumeration from a ICO, PE or NE file.
  2590. Arguments:
  2591. ModuleName - Specifies the ICO, PE or NE file to be processed.
  2592. IconEnum - Receives the icon group enumeration structure.
  2593. Return value:
  2594. TRUE if at least one icon group exists, FALSE otherwise.
  2595. --*/
  2596. {
  2597. ZeroMemory (IconEnum, sizeof (ICON_ENUMA));
  2598. if (IcoEnumFirstIconGroupInPeFileA (FileName, IconEnum)) {
  2599. IconEnum->FileType = ICON_PEFILE;
  2600. return TRUE;
  2601. }
  2602. if (IcoEnumFirstIconGroupInNeFileA (FileName, IconEnum)) {
  2603. IconEnum->FileType = ICON_NEFILE;
  2604. return TRUE;
  2605. }
  2606. IconEnum->IconGroup = IcoExtractIconGroupFromIcoFileA (FileName);
  2607. if (IconEnum->IconGroup) {
  2608. IconEnum->FileType = ICON_ICOFILE;
  2609. return TRUE;
  2610. }
  2611. return FALSE;
  2612. }
  2613. BOOL
  2614. IcoEnumFirstIconGroupInFileW (
  2615. IN PCWSTR FileName,
  2616. OUT PICON_ENUMW IconEnum
  2617. )
  2618. /*++
  2619. Routine Description:
  2620. IcoEnumFirstIconGroupInFile starts the icon group enumeration from a ICO, PE or NE file.
  2621. Arguments:
  2622. ModuleName - Specifies the ICO, PE or NE file to be processed.
  2623. IconEnum - Receives the icon group enumeration structure.
  2624. Return value:
  2625. TRUE if at least one icon group exists, FALSE otherwise.
  2626. --*/
  2627. {
  2628. ZeroMemory (IconEnum, sizeof (ICON_ENUMW));
  2629. if (IcoEnumFirstIconGroupInPeFileW (FileName, IconEnum)) {
  2630. IconEnum->FileType = ICON_PEFILE;
  2631. return TRUE;
  2632. }
  2633. if (IcoEnumFirstIconGroupInNeFileW (FileName, IconEnum)) {
  2634. IconEnum->FileType = ICON_NEFILE;
  2635. return TRUE;
  2636. }
  2637. IconEnum->IconGroup = IcoExtractIconGroupFromIcoFileW (FileName);
  2638. if (IconEnum->IconGroup) {
  2639. IconEnum->FileType = ICON_ICOFILE;
  2640. return TRUE;
  2641. }
  2642. return FALSE;
  2643. }
  2644. BOOL
  2645. IcoEnumNextIconGroupInFileA (
  2646. IN OUT PICON_ENUMA IconEnum
  2647. )
  2648. /*++
  2649. Routine Description:
  2650. IcoEnumNextIconGroupInFile continues the icon group enumeration from a ICO, PE or NE file.
  2651. Arguments:
  2652. IconEnum - Specifies and receives the icon group enumeration structure.
  2653. Return value:
  2654. TRUE if one more icon group exists, FALSE otherwise.
  2655. --*/
  2656. {
  2657. if (IconEnum->FileType == ICON_ICOFILE) {
  2658. IcoAbortEnumIconGroupA (IconEnum);
  2659. return FALSE;
  2660. }
  2661. if (IconEnum->FileType == ICON_PEFILE) {
  2662. return IcoEnumNextIconGroupInPeFileA (IconEnum);
  2663. }
  2664. if (IconEnum->FileType == ICON_NEFILE) {
  2665. return IcoEnumNextIconGroupInNeFileA (IconEnum);
  2666. }
  2667. return FALSE;
  2668. }
  2669. BOOL
  2670. IcoEnumNextIconGroupInFileW (
  2671. IN OUT PICON_ENUMW IconEnum
  2672. )
  2673. /*++
  2674. Routine Description:
  2675. IcoEnumNextIconGroupInFile continues the icon group enumeration from a ICO, PE or NE file.
  2676. Arguments:
  2677. IconEnum - Specifies and receives the icon group enumeration structure.
  2678. Return value:
  2679. TRUE if one more icon group exists, FALSE otherwise.
  2680. --*/
  2681. {
  2682. if (IconEnum->FileType == ICON_ICOFILE) {
  2683. IcoAbortEnumIconGroupW (IconEnum);
  2684. return FALSE;
  2685. }
  2686. if (IconEnum->FileType == ICON_PEFILE) {
  2687. return IcoEnumNextIconGroupInPeFileW (IconEnum);
  2688. }
  2689. if (IconEnum->FileType == ICON_NEFILE) {
  2690. return IcoEnumNextIconGroupInNeFileW (IconEnum);
  2691. }
  2692. return FALSE;
  2693. }
  2694. PICON_GROUP
  2695. IcoExtractIconGroupFromFileA (
  2696. IN PCSTR ModuleName,
  2697. IN PCSTR GroupIconId,
  2698. OUT PINT Index OPTIONAL
  2699. )
  2700. /*++
  2701. Routine Description:
  2702. IcoExtractIconGroupFromFile extracts an icon group from a ICO, PE or NE file.
  2703. Arguments:
  2704. ModuleName - Specifies the file to be processed.
  2705. GroupIconId - Specifies the resource ID of the icon group to be extracted.
  2706. Index - Receives the index of the icon group extracted.
  2707. Return value:
  2708. An icon group if successfull, NULL otherwise.
  2709. --*/
  2710. {
  2711. PICON_GROUP result = NULL;
  2712. // assume that this is a PE file
  2713. result = IcoExtractIconGroupFromPeFileA (ModuleName, GroupIconId, Index);
  2714. if (result) {
  2715. return result;
  2716. }
  2717. // assume that this is a NE file
  2718. result = IcoExtractIconGroupFromNeFileA (ModuleName, GroupIconId, Index);
  2719. if (result) {
  2720. return result;
  2721. }
  2722. // finally, assume that this is a ICO file, verify that
  2723. // the GroupIconId is zero
  2724. if (GroupIconId == NULL) {
  2725. result = IcoExtractIconGroupFromIcoFileA (ModuleName);
  2726. if (result && Index) {
  2727. *Index = 0;
  2728. }
  2729. }
  2730. return result;
  2731. }
  2732. PICON_GROUP
  2733. IcoExtractIconGroupFromFileW (
  2734. IN PCWSTR ModuleName,
  2735. IN PCWSTR GroupIconId,
  2736. OUT PINT Index OPTIONAL
  2737. )
  2738. /*++
  2739. Routine Description:
  2740. IcoExtractIconGroupFromFile extracts an icon group from a ICO, PE or NE file.
  2741. Arguments:
  2742. ModuleName - Specifies the file to be processed.
  2743. GroupIconId - Specifies the resource ID of the icon group to be extracted.
  2744. Index - Receives the index of the icon group extracted.
  2745. Return value:
  2746. An icon group if successfull, NULL otherwise.
  2747. --*/
  2748. {
  2749. PICON_GROUP result = NULL;
  2750. // assume that this is a PE file
  2751. result = IcoExtractIconGroupFromPeFileW (ModuleName, GroupIconId, Index);
  2752. if (result) {
  2753. return result;
  2754. }
  2755. // assume that this is a NE file
  2756. result = IcoExtractIconGroupFromNeFileW (ModuleName, GroupIconId, Index);
  2757. if (result) {
  2758. return result;
  2759. }
  2760. // finally, assume that this is a ICO file, verify that
  2761. // the GroupIconId is zero
  2762. if (GroupIconId == NULL) {
  2763. result = IcoExtractIconGroupFromIcoFileW (ModuleName);
  2764. if (result && Index) {
  2765. *Index = 0;
  2766. }
  2767. return result;
  2768. }
  2769. return result;
  2770. }
  2771. PICON_GROUP
  2772. IcoExtractIconGroupByIndexFromFileA (
  2773. IN PCSTR ModuleName,
  2774. IN INT Index,
  2775. OUT PCSTR *GroupIconId
  2776. )
  2777. /*++
  2778. Routine Description:
  2779. IcoExtractIconGroupByIndexFromFile extracts an icon group from a ICO, PE or NE file
  2780. using the Index.
  2781. Arguments:
  2782. ModuleName - Specifies the file to be processed.
  2783. Index - Specifies the index of the icon groupto be extracted.
  2784. GroupIconId - Receives the resource ID of the icon group extracted.
  2785. Return value:
  2786. An icon group if successfull, NULL otherwise.
  2787. --*/
  2788. {
  2789. PICON_GROUP result = NULL;
  2790. // assume that this is a PE file
  2791. result = IcoExtractIconGroupByIndexFromPeFileA (ModuleName, Index, GroupIconId);
  2792. if (result) {
  2793. return result;
  2794. }
  2795. // assume that this is a NE file
  2796. result = IcoExtractIconGroupByIndexFromNeFileA (ModuleName, Index, GroupIconId);
  2797. if (result) {
  2798. return result;
  2799. }
  2800. // finally, assume that this is a ICO file, verify that
  2801. // the Index is zero
  2802. if (Index == 0) {
  2803. result = IcoExtractIconGroupFromIcoFileA (ModuleName);
  2804. if (result && GroupIconId) {
  2805. *GroupIconId = NULL;
  2806. }
  2807. return result;
  2808. }
  2809. return result;
  2810. }
  2811. PICON_GROUP
  2812. IcoExtractIconGroupByIndexFromFileW (
  2813. IN PCWSTR ModuleName,
  2814. IN INT Index,
  2815. OUT PCWSTR *GroupIconId
  2816. )
  2817. /*++
  2818. Routine Description:
  2819. IcoExtractIconGroupByIndexFromFile extracts an icon group from a ICO, PE or NE file
  2820. using the Index.
  2821. Arguments:
  2822. ModuleName - Specifies the file to be processed.
  2823. Index - Specifies the index of the icon groupto be extracted.
  2824. GroupIconId - Receives the resource ID of the icon group extracted.
  2825. Return value:
  2826. An icon group if successfull, NULL otherwise.
  2827. --*/
  2828. {
  2829. PICON_GROUP result = NULL;
  2830. // assume that this is a PE file
  2831. result = IcoExtractIconGroupByIndexFromPeFileW (ModuleName, Index, GroupIconId);
  2832. if (result) {
  2833. return result;
  2834. }
  2835. // assume that this is a NE file
  2836. result = IcoExtractIconGroupByIndexFromNeFileW (ModuleName, Index, GroupIconId);
  2837. if (result) {
  2838. return result;
  2839. }
  2840. // finally, assume that this is a ICO file, verify that
  2841. // the Index is zero
  2842. if (Index == 0) {
  2843. result = IcoExtractIconGroupFromIcoFileW (ModuleName);
  2844. if (result && GroupIconId) {
  2845. *GroupIconId = NULL;
  2846. }
  2847. return result;
  2848. }
  2849. return result;
  2850. }