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.

361 lines
12 KiB

  1. #include "hdspPCH.h"
  2. #include "resource.h"
  3. #include "rescopy.h"
  4. static char *g_szMonths[] =
  5. {
  6. "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  7. };
  8. BOOL CALLBACK RezNamesCallback( HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LPARAM lParam )
  9. {
  10. PResCallbackData pData = (PResCallbackData)lParam;
  11. DWORD cResourceBytes = 0;
  12. CHAR szDataPath[MAX_PATH];
  13. HRSRC hrsrc = NULL;
  14. HGLOBAL hglbResource = NULL;
  15. LPVOID pDataFile = NULL;
  16. HANDLE hFileWrite = INVALID_HANDLE_VALUE;
  17. DWORD cBytesWritten = 0;
  18. BOOL fEndSlash = FALSE;
  19. LPCSTR pszEndSlash = NULL;
  20. PLyraExeHeader pHeader = NULL;
  21. LyraExeHeader HeaderComp;
  22. BOOL fPerformVersionCheck = TRUE;
  23. BOOL fOKToCopy = TRUE;
  24. UINT idxMonth = 0;
  25. if( NULL == pData )
  26. {
  27. return( FALSE );
  28. }
  29. pszEndSlash = pData->pszDirectory;
  30. while( pszEndSlash && *pszEndSlash )
  31. {
  32. fEndSlash = ( *pszEndSlash == '\\' );
  33. pszEndSlash = CharNextA(pszEndSlash);
  34. }
  35. if( 0 > _snprintf( szDataPath,
  36. sizeof(szDataPath)/sizeof(szDataPath[0]),
  37. fEndSlash ? "%s%s" : "%s\\%s",
  38. pData->pszDirectory,
  39. lpszName ) )
  40. {
  41. pData->hr = E_OUTOFMEMORY;
  42. return( FALSE );
  43. }
  44. hrsrc = FindResourceA( hModule, lpszName, lpszType );
  45. if( NULL == hrsrc )
  46. {
  47. pData->hr = HRESULT_FROM_WIN32( GetLastError() );
  48. return( FALSE );
  49. }
  50. cResourceBytes = SizeofResource( hModule, hrsrc );
  51. if( 0 == cResourceBytes )
  52. {
  53. pData->hr = E_UNEXPECTED;
  54. return( FALSE );
  55. }
  56. hglbResource = LoadResource(hModule, hrsrc );
  57. if( NULL == hrsrc )
  58. {
  59. pData->hr = HRESULT_FROM_WIN32( GetLastError() );
  60. return( FALSE );
  61. }
  62. //
  63. // Note: Win32 Claims that you do NOT have to Free/Unlock resource after calling lock
  64. //
  65. pDataFile = LockResource( hglbResource );
  66. if( NULL == pDataFile )
  67. {
  68. pData->hr = HRESULT_FROM_WIN32( GetLastError() );
  69. return( FALSE );
  70. }
  71. pszEndSlash = strrchr( lpszName, '.' );
  72. if( NULL != pszEndSlash &&
  73. 0 == stricmp(pszEndSlash, ".exe") &&
  74. cResourceBytes > sizeof(LyraExeHeader) )
  75. {
  76. pHeader = (PLyraExeHeader)pDataFile;
  77. //
  78. // If our files don't have "LYRA" in them, then there is no
  79. // version check to perform (ughhhh!!!)
  80. //
  81. if( strncmp((char *)pHeader->szLyra, "LYRA", sizeof(pHeader->szLyra) ) )
  82. {
  83. fPerformVersionCheck = FALSE;
  84. }
  85. }
  86. else
  87. {
  88. fPerformVersionCheck = FALSE;
  89. }
  90. hFileWrite = CreateFileA( szDataPath,
  91. GENERIC_WRITE | GENERIC_READ,
  92. 0,
  93. NULL,
  94. OPEN_ALWAYS,
  95. FILE_ATTRIBUTE_NORMAL,
  96. NULL );
  97. if( INVALID_HANDLE_VALUE == hFileWrite )
  98. {
  99. pData->hr = HRESULT_FROM_WIN32( GetLastError() );
  100. return( FALSE );
  101. }
  102. if( fPerformVersionCheck )
  103. {
  104. if( !ReadFile( hFileWrite,
  105. &HeaderComp,
  106. sizeof(HeaderComp),
  107. &cBytesWritten,
  108. NULL ) )
  109. {
  110. fPerformVersionCheck = FALSE;
  111. }
  112. //
  113. // Make sure we got the number of bytes we need for our version header,
  114. // if not, then just copy the file!
  115. //
  116. if( cBytesWritten != sizeof(HeaderComp) )
  117. {
  118. fPerformVersionCheck = FALSE;
  119. }
  120. }
  121. if( fPerformVersionCheck )
  122. {
  123. //
  124. // If we ARE going to perform a version check, then this MUST be set to false intially because
  125. // if we fail on the version check, we DONT want to copy the file!
  126. //
  127. fOKToCopy = FALSE;
  128. //
  129. // At this point, we know we have version stuff in our .exe in our resource,
  130. // and we know that we have 36 bytes of what "should" be a header, now
  131. // compare them, if they don't match, it's okay to copy
  132. //
  133. if( strncmp( (char *)pHeader->szLyra, (char *)HeaderComp.szLyra, sizeof(HeaderComp.szLyra) ) )
  134. {
  135. fOKToCopy = TRUE;
  136. }
  137. else
  138. {
  139. //
  140. // Okay, we have version information, check the revision number
  141. //
  142. if( pHeader->szRevision[0] >= HeaderComp.szRevision[0] )
  143. {
  144. if( pHeader->szRevision[0] == HeaderComp.szRevision[0] )
  145. {
  146. if( pHeader->szRevision[2] >= HeaderComp.szRevision[2] )
  147. {
  148. if( pHeader->szRevision[2] > HeaderComp.szRevision[2] )
  149. {
  150. fOKToCopy = TRUE;
  151. }
  152. else
  153. {
  154. SYSTEMTIME sysTimeFile;
  155. SYSTEMTIME sysTimeResource;
  156. FILETIME ftFile;
  157. FILETIME ftRes;
  158. ZeroMemory( &sysTimeFile, sizeof(sysTimeFile) );
  159. ZeroMemory( &sysTimeResource, sizeof(sysTimeResource) );
  160. for( idxMonth = 0; idxMonth < 12; idxMonth++ )
  161. {
  162. if( !_strnicmp( (char*)pHeader->szMonth, g_szMonths[idxMonth], sizeof(pHeader->szMonth) ) )
  163. {
  164. sysTimeResource.wMonth = idxMonth + 1;
  165. }
  166. if( !_strnicmp( (char*)HeaderComp.szMonth, g_szMonths[idxMonth], sizeof(HeaderComp.szMonth) ) )
  167. {
  168. sysTimeFile.wMonth = idxMonth + 1;
  169. }
  170. }
  171. sysTimeResource.wDay = ( pHeader->szDay[0] - '0' ) * 10 +
  172. ( pHeader->szDay[1] - '0' );
  173. sysTimeFile.wDay = ( HeaderComp.szDay[0] - '0' ) * 10 +
  174. ( HeaderComp.szDay[1] - '0' );
  175. sysTimeResource.wYear= ( pHeader->szYear[0] - '0' ) * 1000 +
  176. ( pHeader->szYear[1] - '0' ) * 100 +
  177. ( pHeader->szYear[2] - '0' ) * 10 +
  178. ( pHeader->szYear[3] - '0' );
  179. sysTimeFile.wYear= ( HeaderComp.szYear[0] - '0' ) * 1000 +
  180. ( HeaderComp.szYear[1] - '0' ) * 100 +
  181. ( HeaderComp.szYear[2] - '0' ) * 10 +
  182. ( HeaderComp.szYear[3] - '0' );
  183. sysTimeResource.wHour = ( pHeader->szTime[0] - '0' ) * 10 +
  184. ( pHeader->szTime[1] - '0' );
  185. sysTimeFile.wHour = ( HeaderComp.szTime[0] - '0' ) * 10 +
  186. ( HeaderComp.szTime[1] - '0' );
  187. sysTimeResource.wMinute = ( pHeader->szTime[0] - '0' ) * 10 +
  188. ( pHeader->szTime[1] - '0' );
  189. sysTimeFile.wMinute = ( HeaderComp.szTime[3] - '0' ) * 10 +
  190. ( HeaderComp.szTime[4] - '0' );
  191. SystemTimeToFileTime( &sysTimeResource, &ftRes );
  192. SystemTimeToFileTime( &sysTimeFile, &ftFile );
  193. fOKToCopy = ( CompareFileTime( &ftRes, &ftFile ) > 0 );
  194. }
  195. }
  196. }
  197. else
  198. {
  199. fOKToCopy = TRUE;
  200. }
  201. }
  202. }
  203. }
  204. if( fOKToCopy )
  205. {
  206. SetFilePointer( hFileWrite, 0, NULL, FILE_BEGIN );
  207. SetEndOfFile( hFileWrite );
  208. if( !WriteFile( hFileWrite,
  209. pDataFile,
  210. cResourceBytes,
  211. &cBytesWritten,
  212. NULL ) )
  213. {
  214. pData->hr = HRESULT_FROM_WIN32( GetLastError() );
  215. }
  216. }
  217. CloseHandle( hFileWrite );
  218. return( TRUE );
  219. }
  220. HRESULT CopyFileResToDirectory( HINSTANCE hInstance, LPCSTR pszDestDir )
  221. {
  222. HRESULT hr = S_OK;
  223. RezCallbackData data;
  224. DWORD dwAttributes;
  225. CHAR szCreatePath[MAX_PATH];
  226. LPCSTR pszCreateDir = NULL;
  227. if( NULL == hInstance ||
  228. NULL == pszDestDir )
  229. {
  230. return( E_INVALIDARG );
  231. }
  232. dwAttributes = GetFileAttributesA( pszDestDir );
  233. if( -1 != dwAttributes &&
  234. (!(FILE_ATTRIBUTE_DIRECTORY & dwAttributes )) )
  235. {
  236. return( E_INVALIDARG );
  237. }
  238. if( -1 == dwAttributes )
  239. {
  240. pszCreateDir = pszDestDir;
  241. while( *pszCreateDir &&
  242. SUCCEEDED( hr ) )
  243. {
  244. if( *pszCreateDir == '\\' )
  245. {
  246. if( ( (LPBYTE)pszCreateDir - (LPBYTE)pszDestDir ) > sizeof(szCreatePath) )
  247. {
  248. hr = E_INVALIDARG;
  249. continue;
  250. }
  251. else
  252. {
  253. pszCreateDir = CharNextA( pszCreateDir );
  254. memcpy( szCreatePath, pszDestDir, (LPBYTE)pszCreateDir-(LPBYTE)pszDestDir );
  255. ((LPBYTE)szCreatePath)[ (LPBYTE)pszCreateDir - (LPBYTE)pszDestDir] = '\0';
  256. if( strlen(szCreatePath) != 3 && // 3 indicates the drive path
  257. !CreateDirectoryA( szCreatePath, NULL ) )
  258. {
  259. hr = HRESULT_FROM_WIN32( GetLastError() );
  260. if( HRESULT_FROM_WIN32( ERROR_ALREADY_EXISTS ) == hr )
  261. {
  262. hr = S_OK;
  263. }
  264. }
  265. continue;
  266. }
  267. }
  268. pszCreateDir = CharNextA( pszCreateDir );
  269. }
  270. if( SUCCEEDED( hr ) )
  271. {
  272. if( strlen(pszDestDir) != 3 && // 3 indicates the drive path
  273. !CreateDirectoryA( pszDestDir, NULL ) )
  274. {
  275. hr = HRESULT_FROM_WIN32( GetLastError() );
  276. if( HRESULT_FROM_WIN32( ERROR_ALREADY_EXISTS ) == hr )
  277. {
  278. hr = S_OK;
  279. }
  280. }
  281. }
  282. }
  283. #ifdef LYRA_HANDLES_HIDDEN
  284. if( SUCCEEDED( hr ) )
  285. {
  286. dwAttributes = GetFileAttributesA( pszDestDir );
  287. if( (DWORD)-1 != dwAttributes )
  288. {
  289. SetFileAttributesA( pszDestDir, dwAttributes | FILE_ATTRIBUTE_HIDDEN );
  290. }
  291. }
  292. #endif
  293. if( SUCCEEDED( hr ) )
  294. {
  295. data.pszDirectory = pszDestDir;
  296. if( !EnumResourceNamesA( hInstance, "File", (ENUMRESNAMEPROC)RezNamesCallback, (LPARAM) &data) )
  297. {
  298. hr = HRESULT_FROM_WIN32( GetLastError() );
  299. }
  300. }
  301. if( SUCCEEDED( hr ) )
  302. {
  303. hr = data.hr;
  304. }
  305. return( hr );
  306. }