Source code of Windows XP (NT5)
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.

382 lines
9.3 KiB

  1. /****************************************************************************/
  2. /* */
  3. /* resonexe.C - */
  4. /* */
  5. /* Windows DOS Version 3.2 add resource onto executable */
  6. /* (C) Copyright Microsoft Corporation 1988-1992 */
  7. /* */
  8. /* */
  9. /****************************************************************************/
  10. #include <windows.h>
  11. #include <fcntl.h>
  12. #include <io.h>
  13. #include <stdlib.h>
  14. #include "ntverp.h"
  15. #include "rc.h"
  16. #include "resonexe.h"
  17. #define BUFSIZE 4096
  18. //
  19. // Globals
  20. //
  21. PUCHAR szInFile=NULL;
  22. BOOL fDebug = FALSE;
  23. BOOL fVerbose = FALSE;
  24. BOOL fReplace = FALSE;
  25. BOOL fDelete = FALSE;
  26. int fhBin = -1;
  27. UCHAR szType[256];
  28. UCHAR szName[256];
  29. int idLang;
  30. int idType=0;
  31. int idName=0;
  32. void
  33. usage ( int rc );
  34. void
  35. usage ( int rc )
  36. {
  37. #if DBG
  38. printf("Microsoft (R) Windows RESONEXE Version %s\n", VER_PRODUCTVERSION_STR);
  39. #else
  40. printf("Microsoft (R) Windows RESONEXE Version %s.%d\n", VER_PRODUCTVERSION_STR, VER_PRODUCTBUILD);
  41. #endif /* dbg */
  42. printf("Copyright (C) Microsoft Corp. 1991-1992. All rights reserved.\n\n");
  43. printf( "usage: resonexe [-v] [-r|-x resspec] [-fo outfile] <input file> [<exe file>]\n");
  44. printf( " where input file is an WIN32 .RES file\n");
  45. printf( " -v verbose - print info\n");
  46. printf( " -d debug - print debug info\n");
  47. printf( " -r replace - delete all resource from input file before adding new resources.\n");
  48. printf( " -x delete - delete specified resource from input file.\n");
  49. printf( " resspec is of the form: typeid,nameid,langid\n");
  50. printf( " typeid is a string or decimal number\n");
  51. printf( " nameid is a string or decimal number\n");
  52. printf( " langid is a hexadecimal number\n");
  53. printf( " outfile is the desired output file name.\n");
  54. printf( " outfile defaults to filespec.exe.\n");
  55. printf( " exe file is the exe file to attach resources to.\n");
  56. exit(rc);
  57. }
  58. void
  59. __cdecl main(
  60. IN int argc,
  61. IN char *argv[]
  62. )
  63. /*++
  64. Routine Description:
  65. Determines options
  66. locates and opens input files
  67. reads input files
  68. writes output files
  69. exits
  70. Exit Value:
  71. 0 on success
  72. 1 if error
  73. --*/
  74. {
  75. int i;
  76. UCHAR *s1;
  77. UCHAR *szOutFile=NULL;
  78. UCHAR *szExeFile=NULL;
  79. long lbytes;
  80. BOOL result;
  81. HANDLE hupd;
  82. if (argc == 1) {
  83. usage(0);
  84. }
  85. for (i=1; i<argc; i++) {
  86. s1 = argv[i];
  87. if (*s1 == '/' || *s1 == '-') {
  88. s1++;
  89. if (!_stricmp(s1, "fo")) {
  90. szOutFile = argv[++i];
  91. }
  92. else if (!_stricmp(s1, "d")) {
  93. fDebug = TRUE;
  94. }
  95. else if (!_stricmp(s1, "v")) {
  96. fVerbose = TRUE;
  97. }
  98. else if (!_stricmp(s1, "r")) {
  99. fReplace = TRUE;
  100. }
  101. else if (!_stricmp(s1, "x")) {
  102. fDelete = TRUE;
  103. if (i+1 == argc)
  104. usage(1);
  105. s1 = argv[++i];
  106. if (sscanf(s1, "%d,%d,%x", &idType, &idName, &idLang) == 3)
  107. continue;
  108. idType = 0;
  109. idName = 0;
  110. if (sscanf(s1, "%d,%[^,],%x", &idType, szName, &idLang) == 3)
  111. continue;
  112. idType = 0;
  113. idName = 0;
  114. if (sscanf(s1, "%[^,],%d,%x", szType, &idName, &idLang) == 3)
  115. continue;
  116. idType = 0;
  117. idName = 0;
  118. if (sscanf(s1, "%[^,],%[^,],%x", szType, szName, &idLang) == 3)
  119. continue;
  120. printf("Unrecognized type,name,lang triplet <%s>\n", s1);
  121. usage(1);
  122. }
  123. else if (!_stricmp(s1, "h")) {
  124. usage(1);
  125. }
  126. else if (!_stricmp(s1, "?")) {
  127. usage(1);
  128. }
  129. else {
  130. usage(1);
  131. }
  132. }
  133. else if (szInFile == NULL) {
  134. szInFile = s1;
  135. }
  136. else {
  137. szExeFile = s1;
  138. }
  139. }
  140. //
  141. // Make sure that we actually got a file
  142. //
  143. if (fDelete) {
  144. if (fReplace) {
  145. printf("usage error: Can't do both Replace and Delete\n");
  146. usage(1);
  147. }
  148. if (!szInFile) {
  149. printf("usage error: Missing exe file spec\n");
  150. usage(1);
  151. }
  152. if (szInFile && !szExeFile) {
  153. szExeFile = szInFile;
  154. if (!szOutFile)
  155. szOutFile = _strdup(szInFile);
  156. szInFile = NULL;
  157. if (idType == 0)
  158. _strupr(szType);
  159. if (idName == 0)
  160. _strupr(szName);
  161. }
  162. }
  163. else if (!szInFile) {
  164. printf("usage error: Must have file spec\n");
  165. usage(1);
  166. }
  167. if (fVerbose || fDebug) {
  168. #if DBG
  169. printf("Microsoft (R) Windows RESONEXE Version %s\n", VER_PRODUCTVERSION_STR);
  170. #else
  171. printf("Microsoft (R) Windows RESONEXE Version %s.%d\n", VER_PRODUCTVERSION_STR, VER_PRODUCTBUILD);
  172. #endif /* dbg */
  173. printf("Copyright (C) Microsoft Corp. 1991-1992. All rights reserved.\n\n");
  174. }
  175. if (szInFile && (fhBin = _open( szInFile, O_RDONLY|O_BINARY )) == -1) {
  176. /*
  177. * try adding a .RES extension.
  178. */
  179. s1 = MyAlloc(strlen(szInFile) + 4 + 1);
  180. strcpy(s1, szInFile);
  181. szInFile = s1;
  182. strcat(szInFile, ".RES");
  183. if ((fhBin = _open( szInFile, O_RDONLY|O_BINARY )) == -1) {
  184. pehdr();
  185. printf("Cannot open %s for reading.\n", szInFile);
  186. exit(1);
  187. }
  188. #if DBG
  189. printf("Reading %s\n", szInFile);
  190. #endif /* DBG */
  191. }
  192. if (fhBin != -1) {
  193. lbytes = MySeek(fhBin, 0L, SEEK_END);
  194. MySeek(fhBin, 0L, SEEK_SET);
  195. }
  196. if (szExeFile == NULL) {
  197. /*
  198. * Make exefile = infile.exe
  199. */
  200. szExeFile = MyAlloc(strlen(szInFile) + 4 + 1);
  201. strcpy(szExeFile, szInFile);
  202. s1 = &szExeFile[strlen(szExeFile) - 4];
  203. if (s1 < szExeFile)
  204. s1 = szExeFile;
  205. while (*s1) {
  206. if (*s1 == '.')
  207. break;
  208. s1++;
  209. }
  210. strcpy(s1, ".exe");
  211. }
  212. if (szOutFile == NULL) {
  213. /*
  214. * Make outfile = infile.exe
  215. */
  216. szOutFile = MyAlloc(strlen(szInFile) + 4 + 1);
  217. strcpy(szOutFile, szInFile);
  218. s1 = &szOutFile[strlen(szOutFile) - 4];
  219. if (s1 < szOutFile)
  220. s1 = szOutFile;
  221. while (*s1) {
  222. if (*s1 == '.')
  223. break;
  224. s1++;
  225. }
  226. strcpy(s1, ".exe");
  227. }
  228. else {
  229. /*
  230. * Make outfile = copyof(exefile)
  231. */
  232. if (CopyFile(szExeFile, szOutFile, FALSE) == FALSE) {
  233. pehdr();
  234. printf("RW1001: copy of %s to %s failed", szExeFile, szOutFile);
  235. _close(fhBin);
  236. exit(1);
  237. }
  238. SetFileAttributes(szOutFile, FILE_ATTRIBUTE_NORMAL);
  239. }
  240. #if DBG
  241. printf("Writing %s\n", szOutFile);
  242. #endif /* DBG */
  243. hupd = BeginUpdateResourceA(szOutFile, fReplace);
  244. if (hupd == NULL) {
  245. pehdr();
  246. printf("RW1001: unable to load %s\n", szOutFile);
  247. _close(fhBin);
  248. exit(1);
  249. }
  250. if (fDelete) {
  251. result = UpdateResourceA(hupd,
  252. idType!=0?(PCHAR)idType:szType,
  253. idName!=0?(PCHAR)idName:szName,
  254. idLang, NULL, 0);
  255. if (result == 0) {
  256. pehdr();
  257. if (idType) {
  258. if (idName)
  259. printf("RW1004: unable to delete resource %d,%d,%x from %s, status:%d\n", idType, idName, idLang, szExeFile, GetLastError());
  260. else
  261. printf("RW1004: unable to delete resource %d,%s,%x from %s, status:%d\n", idType, szName, idLang, szExeFile, GetLastError());
  262. }
  263. else {
  264. if (idName)
  265. printf("RW1004: unable to delete resource %s,%d,%x from %s, status:%d\n", szType, idName, idLang, szExeFile, GetLastError());
  266. else
  267. printf("RW1004: unable to delete resource %s,%s,%x from %s, status:%d\n", szType, szName, idLang, szExeFile, GetLastError());
  268. }
  269. _close(fhBin);
  270. exit(1);
  271. }
  272. }
  273. else {
  274. result = ReadRes(fhBin, lbytes, hupd);
  275. if (result == 0) {
  276. pehdr();
  277. printf("RW1002: unable to read resources from %s, status:%d\n", szInFile, GetLastError());
  278. _close(fhBin);
  279. exit(1);
  280. }
  281. }
  282. result = EndUpdateResourceW(hupd, FALSE);
  283. if (result == 0) {
  284. pehdr();
  285. printf("RW1003: unable to write resources to %s, status:%d\n", szOutFile, GetLastError());
  286. }
  287. _close( fhBin );
  288. exit(result ? 0 : 1);
  289. }
  290. UCHAR*
  291. MyAlloc(ULONG nbytes )
  292. {
  293. UCHAR *s;
  294. if ((s = (UCHAR*)calloc( 1, nbytes )) != NULL)
  295. return s;
  296. else {
  297. pehdr();
  298. printf( "Memory allocation, needed %u bytes\n", nbytes );
  299. exit(1);
  300. }
  301. }
  302. ULONG
  303. MyRead(int fh, UCHAR*p, ULONG n )
  304. {
  305. USHORT n1;
  306. if ((n1 = _read( fh, p, n )) != n) {
  307. eprintf( "a file read error occured" );
  308. exit(1);
  309. }
  310. else
  311. return 0;
  312. }
  313. LONG
  314. MySeek( int fh, long pos, int cmd )
  315. {
  316. if ((pos = _lseek( fh, pos, cmd )) == -1) {
  317. eprintf( "seek error" );
  318. exit(1);
  319. }
  320. return pos;
  321. }
  322. ULONG
  323. MoveFilePos( int fh, ULONG pos )
  324. {
  325. return MySeek( fh, pos, SEEK_SET );
  326. }
  327. void
  328. eprintf(
  329. UCHAR *s
  330. )
  331. {
  332. pehdr();
  333. printf("%s.\n", s);
  334. }
  335. void
  336. pehdr(
  337. )
  338. {
  339. printf("RESONEXE: error - ");
  340. }