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.

297 lines
12 KiB

  1. //***************************************************************************
  2. //* Copyright (c) Microsoft Corporation 1995. All rights reserved. *
  3. //***************************************************************************
  4. //* *
  5. //* UPDFILE.C *
  6. //* *
  7. //***************************************************************************
  8. //***************************************************************************
  9. //* INCLUDE FILES *
  10. //***************************************************************************
  11. #include <stdio.h>
  12. //#include <stdlib.h>
  13. #include <wtypes.h>
  14. #include "resource.h"
  15. #include "updfile.h"
  16. #include "updres.h"
  17. //***************************************************************************
  18. //* GLOBAL VARIABLES *
  19. //***************************************************************************
  20. //***************************************************************************
  21. //* *
  22. //* NAME: main *
  23. //* *
  24. //* SYNOPSIS: Main entry point for the program. *
  25. //* *
  26. //* REQUIRES: *
  27. //* *
  28. //* RETURNS: int: Always 0 *
  29. //* *
  30. //***************************************************************************
  31. INT _cdecl main( INT argc, CHAR *argv[] )
  32. {
  33. // ARGV[1] == Name of package
  34. // ARGV[2] == Name of file to add to package
  35. HANDLE hUpdateRes = NULL;
  36. HANDLE hFile = INVALID_HANDLE_VALUE;
  37. DWORD dwFileSize = 0;
  38. PSTR pszFileContents = NULL;
  39. DWORD dwBytes;
  40. HMODULE hModule;
  41. TCHAR szResName[20];
  42. DWORD dwResNum;
  43. TCHAR szFileToAdd[MAX_PATH];
  44. PSTR pszFileToAddFilename = NULL;
  45. TCHAR szPackage[MAX_PATH];
  46. PSTR pszPackageFilename = NULL;
  47. DWORD dwHeaderSize = 0;
  48. PSTR pszTemp = NULL;
  49. DWORD dwReturnCode = 0;
  50. PDWORD pdwTemp = NULL;
  51. static const TCHAR c_szResNameTemplate[] = "UPDFILE%lu";
  52. if ( argc != 3 ) {
  53. MsgBox( IDS_ERR_INVALID_ARGS );
  54. dwReturnCode = 1;
  55. goto done;
  56. }
  57. dwFileSize = GetFullPathName( argv[1], sizeof(szPackage), szPackage, &pszPackageFilename );
  58. if ( (dwFileSize+1) > sizeof(szPackage) || dwFileSize == 0 ) {
  59. MsgBox1Param( IDS_ERR_GET_FULL_PATH, argv[1] );
  60. dwReturnCode = 1;
  61. goto done;
  62. }
  63. if ( ! FileExists( szPackage ) ) {
  64. MsgBox1Param( IDS_ERR_FILE_NOT_EXIST, argv[1] );
  65. dwReturnCode = 1;
  66. goto done;
  67. }
  68. dwFileSize = GetFullPathName( argv[2], sizeof(szFileToAdd), szFileToAdd, &pszFileToAddFilename );
  69. if ( (dwFileSize+1) > sizeof(szFileToAdd) || dwFileSize == 0 ) {
  70. MsgBox1Param( IDS_ERR_GET_FULL_PATH, argv[2] );
  71. dwReturnCode = 1;
  72. goto done;
  73. }
  74. if ( ! FileExists( szFileToAdd ) ) {
  75. MsgBox1Param( IDS_ERR_FILE_NOT_EXIST, argv[2] );
  76. dwReturnCode = 1;
  77. goto done;
  78. }
  79. // make sure the target file is not read-only file
  80. SetFileAttributes( szPackage, FILE_ATTRIBUTE_NORMAL );
  81. hModule = LoadLibraryEx( szPackage, NULL, LOAD_LIBRARY_AS_DATAFILE |
  82. DONT_RESOLVE_DLL_REFERENCES );
  83. if ( hModule == NULL ) {
  84. MsgBox1Param( IDS_ERR_LOAD_EXE, argv[1] );
  85. dwReturnCode = 1;
  86. goto done;
  87. }
  88. for ( dwResNum = 0; ; dwResNum += 1 ) {
  89. wsprintf( szResName, c_szResNameTemplate, dwResNum );
  90. if ( FindResource( hModule, szResName, RT_RCDATA ) == NULL ) {
  91. break;
  92. }
  93. }
  94. FreeLibrary( hModule );
  95. hFile = CreateFile( szFileToAdd, GENERIC_READ, 0, NULL,
  96. OPEN_EXISTING, 0, NULL );
  97. if ( hFile == INVALID_HANDLE_VALUE ) {
  98. MsgBox1Param( IDS_ERR_OPEN_INPUT_FILE, argv[2] );
  99. dwReturnCode = 1;
  100. goto done;
  101. }
  102. dwFileSize = GetFileSize( hFile, NULL );
  103. dwHeaderSize = sizeof(DWORD) + sizeof(DWORD) + lstrlen(pszFileToAddFilename) + 1;
  104. // File Size + reserved DWORD + Filename\0 + File Contents
  105. pszFileContents = (PSTR) LocalAlloc( LPTR, dwHeaderSize + dwFileSize );
  106. if ( ! pszFileContents ) {
  107. MsgBox( IDS_ERR_NO_MEMORY );
  108. dwReturnCode = 1;
  109. goto done;
  110. }
  111. pdwTemp = (PDWORD) pszFileContents;
  112. *pdwTemp = dwFileSize;
  113. pdwTemp = (PDWORD) (pszFileContents + sizeof(DWORD));
  114. *pdwTemp = MAXDWORD;
  115. pszTemp = pszFileContents + sizeof(DWORD) + sizeof(DWORD);
  116. lstrcpy( pszTemp, pszFileToAddFilename );
  117. pszTemp = pszFileContents + dwHeaderSize;
  118. if ( ! ReadFile( hFile, pszTemp, dwFileSize, &dwBytes, NULL ) )
  119. {
  120. MsgBox1Param( IDS_ERR_READ_INPUT_FILE, argv[2] );
  121. dwReturnCode = 1;
  122. goto done;
  123. }
  124. CloseHandle( hFile );
  125. hFile = INVALID_HANDLE_VALUE ;
  126. // Initialize the EXE file for resource editing
  127. hUpdateRes = LocalBeginUpdateResource( szPackage, FALSE );
  128. if ( hUpdateRes == NULL ) {
  129. MsgBox1Param( IDS_ERR_BEGIN_UPD_RES, argv[1] );
  130. dwReturnCode = 1;
  131. goto done;
  132. }
  133. if ( LocalUpdateResource( hUpdateRes, RT_RCDATA,
  134. szResName, MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
  135. pszFileContents, dwHeaderSize + dwFileSize )
  136. == FALSE )
  137. {
  138. MsgBox1Param( IDS_ERR_UPDATE_RES, argv[1] );
  139. dwReturnCode = 1;
  140. goto done;
  141. }
  142. done:
  143. if ( hUpdateRes ) {
  144. // Write out modified EXE if success ((returncode = 0, means pass
  145. // in FALSE to update file (i.e., don't discard changes)
  146. if ( LocalEndUpdateResource( hUpdateRes, (dwReturnCode == 1) ) == FALSE ) {
  147. MsgBox1Param( IDS_ERR_END_UPD_RES, argv[1] );
  148. dwReturnCode = 1;
  149. }
  150. }
  151. if ( pszFileContents ) {
  152. LocalFree( pszFileContents );
  153. }
  154. if (hFile != INVALID_HANDLE_VALUE) {
  155. CloseHandle( hFile ) ;
  156. }
  157. if (dwReturnCode == 0)
  158. MsgBox2Param( IDS_SUCCESS, argv[2], argv[1] );
  159. return dwReturnCode;
  160. }
  161. //***************************************************************************
  162. //* *
  163. //* NAME: FileExists *
  164. //* *
  165. //* SYNOPSIS: Checks if a file exists. *
  166. //* *
  167. //* REQUIRES: pszFilename *
  168. //* *
  169. //* RETURNS: BOOL: TRUE if it exists, FALSE otherwise *
  170. //* *
  171. //***************************************************************************
  172. BOOL FileExists( PCSTR pszFilename )
  173. {
  174. HANDLE hFile;
  175. hFile = CreateFile( pszFilename, GENERIC_READ, FILE_SHARE_READ |
  176. FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
  177. FILE_ATTRIBUTE_NORMAL, NULL );
  178. if ( hFile == INVALID_HANDLE_VALUE ) {
  179. return( FALSE );
  180. }
  181. CloseHandle( hFile );
  182. return( TRUE );
  183. }
  184. //***************************************************************************
  185. //* *
  186. //* NAME: MsgBox2Param *
  187. //* *
  188. //* SYNOPSIS: Displays a message box with the specified string ID using *
  189. //* 2 string parameters. *
  190. //* *
  191. //* REQUIRES: hWnd: Parent window *
  192. //* nMsgID: String resource ID *
  193. //* szParam1: Parameter 1 (or NULL) *
  194. //* szParam2: Parameter 2 (or NULL) *
  195. //* uIcon: Icon to display (or 0) *
  196. //* uButtons: Buttons to display *
  197. //* *
  198. //* RETURNS: INT: ID of button pressed *
  199. //* *
  200. //* NOTES: Macros are provided for displaying 1 parameter or 0 *
  201. //* parameter message boxes. Also see ErrorMsg() macros. *
  202. //* *
  203. //***************************************************************************
  204. VOID MsgBox2Param( UINT nMsgID, PCSTR c_pszParam1, PCSTR c_pszParam2 )
  205. {
  206. TCHAR szMsgBuf[512];
  207. PSTR pszMessage = NULL;
  208. static const TCHAR c_szError[] = "Unexpected Error. Could not load resource.";
  209. PSTR apszParams[2];
  210. apszParams[0] = (PSTR) c_pszParam1;
  211. apszParams[1] = (PSTR) c_pszParam2;
  212. LoadSz( nMsgID, szMsgBuf, sizeof(szMsgBuf) );
  213. if ( (*szMsgBuf) == '\0' ) {
  214. lstrcpy( szMsgBuf, c_szError );
  215. }
  216. if ( FormatMessage( FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY
  217. | FORMAT_MESSAGE_ALLOCATE_BUFFER, szMsgBuf, 0, 0, (PSTR) (&pszMessage),
  218. 0, (va_list *)apszParams ) )
  219. {
  220. printf( "\n%s\n\n", pszMessage );
  221. LocalFree( pszMessage );
  222. }
  223. }
  224. //***************************************************************************
  225. //* *
  226. //* NAME: LoadSz *
  227. //* *
  228. //* SYNOPSIS: Loads specified string resource into buffer. *
  229. //* *
  230. //* REQUIRES: idString: *
  231. //* lpszBuf: *
  232. //* cbBuf: *
  233. //* *
  234. //* RETURNS: LPSTR: Pointer to the passed-in buffer. *
  235. //* *
  236. //* NOTES: If this function fails (most likely due to low memory), the *
  237. //* returned buffer will have a leading NULL so it is generally *
  238. //* safe to use this without checking for failure. *
  239. //* *
  240. //***************************************************************************
  241. PSTR LoadSz( UINT idString, PSTR pszBuf, UINT cbBuf )
  242. {
  243. // Clear the buffer and load the string
  244. if ( pszBuf ) {
  245. *pszBuf = '\0';
  246. LoadString( NULL, idString, pszBuf, cbBuf );
  247. }
  248. return pszBuf;
  249. }