util.Win32.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /* Utilities - Win32 utilities (Windows NT and Windows '95)
  2. Copyright (C) 1994, 1995, 1996 the Free Software Foundation.
  3. Written 1996 by Juan Grigera<grigera@isis.unlp.edu.ar>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #include <config.h>
  17. #include <windows.h>
  18. #include "util.win32.h"
  19. #include "util.debug.h"
  20. /* int win32_GetPlatform ()
  21. Checks in which OS Midnight Commander is running.
  22. Returns:
  23. OS_WinNT - Windows NT 3.x
  24. OS_Win95 - Windows 4.x
  25. Note: GetVersionEx (Win32API) is called only once.
  26. */
  27. int win32_GetPlatform ()
  28. {
  29. static int platform = 0;
  30. return (platform ? platform : (platform = win32_GetVersionEx()) );
  31. }
  32. /* int win32_GetVersionEx ()
  33. intended for use by win32_GetPlatform only
  34. */
  35. int win32_GetVersionEx ()
  36. {
  37. OSVERSIONINFO ovi;
  38. ovi.dwOSVersionInfoSize = sizeof(ovi);
  39. win32APICALL( GetVersionEx(&ovi) );
  40. return ovi.dwPlatformId;
  41. }
  42. /* int win32_GetEXEType (const char* filename)
  43. Determines whether filename (an Executable) is
  44. a Console application (CUI) or a Graphical application(GUI).
  45. filename - Name of executable file to check
  46. Returns: EXE_win16 - Windows 3.x archive or OS/2
  47. EXE_win32CUI - NT or Chicago Console API, also OS/2
  48. EXE_win32GUI - NT or Chicago GUI API
  49. EXE_otherCUI - DOS COM, MZ, ZM, Phar Lap
  50. EXE_Unknown - Unknown
  51. EXE_Error - Couldn't read file/EXE image
  52. TODO: better management of OS/2 images
  53. EXE_CompressedArchive can be easily implemented
  54. Notes: This function parses the executable header (the only ugly way
  55. to do it). If header is not found or not understood,
  56. 0 is returned.
  57. Information on NE, LE, LX and MZ taken from Ralf Brown's interrupt
  58. list, under INT 21-function 4B ("EXEC" - LOAD AND/OR EXECUTE PROGRAM),
  59. Tables 0806 - 836.
  60. Parsing of PE header (Win32 signature, "Portable Executable")
  61. taken from MSKBase article Number: Q90493.
  62. */
  63. /* ---- Executable Signatures ---- */
  64. /* Alternative DOS signagure */
  65. #define IMAGE_DOS_SIGNATURE_ALTERNATIVE 0x4D5A /* ZM */
  66. /* Phar Lap .EXP files */
  67. #define IMAGE_OLDPHARLAP_SIGNATURE 0x504D /* MP */
  68. #define IMAGE_NEWPHARLAP_286_SIGNATURE 0x3250 /* P2 */
  69. #define IMAGE_NEWPHARLAP_386_SIGNATURE 0x3350 /* P3 */
  70. /* New Executables */
  71. #define IMAGE_LX_SIGNATURE 0x584C /* LX */
  72. #define IMAGE_PE_SIGNATURE 0x4550 /* PE */
  73. int win32_GetEXEType (const char* a_szFileName)
  74. {
  75. HANDLE hImage;
  76. DWORD dwDumm;
  77. DWORD SectionOffset;
  78. DWORD CoffHeaderOffset;
  79. WORD wSignature;
  80. /* DWORD MoreDosHeader[16]; */
  81. IMAGE_DOS_HEADER image_dos_header;
  82. IMAGE_FILE_HEADER image_file_header;
  83. IMAGE_OPTIONAL_HEADER image_optional_header;
  84. /* IMAGE_SECTION_HEADER image_section_header; */
  85. /* Open the EXE file - Use Native API for SHARE compatibility */
  86. hImage = CreateFile(a_szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
  87. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  88. if (hImage == INVALID_HANDLE_VALUE) {
  89. win32Trace (("win32_GetEXEType: Could not open file %s. API Error %d.", a_szFileName, GetLastError()));
  90. return EXE_Error;
  91. }
  92. /* Read the MZ (DOS) image header. */
  93. win32APICALL( ReadFile (hImage, (LPVOID)&image_dos_header, sizeof(IMAGE_DOS_HEADER), &dwDumm, NULL) );
  94. switch (image_dos_header.e_magic) {
  95. case IMAGE_DOS_SIGNATURE: /* MZ or ZM */
  96. case IMAGE_DOS_SIGNATURE_ALTERNATIVE:
  97. break;
  98. case IMAGE_OLDPHARLAP_SIGNATURE: /* MP, P2, P3: Phar Lap executables */
  99. case IMAGE_NEWPHARLAP_286_SIGNATURE:
  100. case IMAGE_NEWPHARLAP_386_SIGNATURE:
  101. return EXE_otherCUI;
  102. default:
  103. return EXE_otherCUI; /* Probably .COM? */
  104. }
  105. /* Read more MS-DOS header. */
  106. /* win32APICALL( ReadFile (hImage, MoreDosHeader, sizeof(MoreDosHeader)); */
  107. /* Get new executable header */
  108. CoffHeaderOffset = SetFilePointer(hImage, image_dos_header.e_lfanew, NULL, FILE_BEGIN);
  109. /* + sizeof(ULONG); */
  110. win32APICALL( ReadFile (hImage, (LPVOID) &wSignature, sizeof(WORD), &dwDumm, NULL) );
  111. switch (wSignature) {
  112. case IMAGE_PE_SIGNATURE: /* PE - Portable Executable */
  113. break;
  114. case IMAGE_OS2_SIGNATURE: /* NE - New Executable OS/2 and Windows 3.x */
  115. case IMAGE_OS2_SIGNATURE_LE: /* LE - Linear Execuable (Windows 3.x) */
  116. case IMAGE_LX_SIGNATURE: /* LX - Linear Execuable (OS/2) */
  117. return EXE_win16;
  118. default:
  119. return EXE_Unknown; /* unknown New Executable or bad pointer */
  120. }
  121. /* Continue parsing PE (COFF-like) */
  122. SectionOffset = CoffHeaderOffset + IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_NT_OPTIONAL_HEADER;
  123. win32APICALL( ReadFile(hImage, (LPVOID) &image_file_header, IMAGE_SIZEOF_FILE_HEADER, &dwDumm, NULL) );
  124. /* Read optional header. */
  125. win32APICALL( ReadFile(hImage, (LPVOID) &image_optional_header, IMAGE_SIZEOF_NT_OPTIONAL_HEADER, &dwDumm, NULL) );
  126. switch (image_optional_header.Subsystem) {
  127. case IMAGE_SUBSYSTEM_WINDOWS_GUI:
  128. return EXE_win32GUI;
  129. case IMAGE_SUBSYSTEM_WINDOWS_CUI:
  130. case IMAGE_SUBSYSTEM_OS2_CUI:
  131. case IMAGE_SUBSYSTEM_POSIX_CUI:
  132. return EXE_win32CUI;
  133. case IMAGE_SUBSYSTEM_UNKNOWN:
  134. case IMAGE_SUBSYSTEM_NATIVE:
  135. return EXE_Unknown; /* FIXME: what is "NATIVE??" */
  136. default:
  137. win32Trace(("Unknown type %u.\n", image_optional_header.Subsystem));
  138. return EXE_Unknown;
  139. }
  140. }