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.

419 lines
10 KiB

  1. // Copyright (c) 1998-1999 Microsoft Corporation
  2. /******************************************************************************
  3. *
  4. * ACSR.C
  5. *
  6. * Application Compatibility Search and Replace Helper Program
  7. *
  8. *
  9. *******************************************************************************/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. #define MAXLEN 512
  13. char Temp[MAXLEN+1];
  14. char Temp1[MAXLEN+1];
  15. char Srch[MAXLEN+1];
  16. char Repl[2*MAXLEN+2];
  17. char *InFN;
  18. char *OutFN;
  19. //*------------------------------------------------------------*//
  20. //* Local function prototypes *//
  21. //*------------------------------------------------------------*//
  22. BOOL ReadString( HANDLE hFile, LPVOID * lpVoid, BOOL bUnicode );
  23. void ReadLnkCommandFile(HANDLE hFile);
  24. /*******************************************************************************
  25. *
  26. * main
  27. *
  28. ******************************************************************************/
  29. int __cdecl main(INT argc, CHAR **argv)
  30. {
  31. DWORD retval;
  32. int CurArg = 1;
  33. FILE *InFP;
  34. FILE *OutFP;
  35. int SrchLen, ReplLen;
  36. char *ptr, *Loc;
  37. HANDLE hFile;
  38. DWORD dwMaxLen = MAXLEN;
  39. DWORD dwLen;
  40. char* pTemp = Temp;
  41. BOOL fAlloc = FALSE;
  42. if (argc != 5)
  43. return(1);
  44. //
  45. //331012 Unbounded strcpy in termsrv\appcmpt\acsr\acsr.c
  46. //check for argv[] length and alloc if needed
  47. //
  48. dwLen = strlen(argv[CurArg]);
  49. if (dwLen > dwMaxLen) {
  50. dwMaxLen = dwLen;
  51. pTemp = (LPSTR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (dwMaxLen+1)*sizeof(char) );
  52. if (NULL == pTemp)
  53. return(1);
  54. fAlloc = TRUE;
  55. }
  56. if (argv[CurArg][0] == '"')
  57. {
  58. strcpy(pTemp, &argv[CurArg][1]);
  59. if (pTemp[strlen(pTemp)-1] == '"')
  60. pTemp[strlen(pTemp)-1] = 0;
  61. else
  62. return(1);
  63. }
  64. else
  65. strcpy(pTemp, argv[CurArg]);
  66. retval = ExpandEnvironmentStringsA(pTemp, Srch, dwMaxLen);
  67. if ((retval == 0) || (retval > dwMaxLen))
  68. return(1);
  69. SrchLen = strlen(Srch);
  70. if (SrchLen < 1)
  71. return(1);
  72. CurArg++;
  73. //
  74. //331012 Unbounded strcpy in termsrv\appcmpt\acsr\acsr.c
  75. //check for argv[] length and realloc if needed
  76. //
  77. dwLen = strlen(argv[CurArg]);
  78. if (dwLen > dwMaxLen) {
  79. dwMaxLen = dwLen;
  80. //
  81. //check if we allocated for pTemp above, if so, free it first
  82. //
  83. if (fAlloc) {
  84. HeapFree(GetProcessHeap(), 0, pTemp);
  85. }
  86. pTemp = (LPSTR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (dwMaxLen+1)*sizeof(char) );
  87. if (NULL == pTemp)
  88. return(1);
  89. fAlloc = TRUE;
  90. }
  91. if (argv[CurArg][0] == '"')
  92. {
  93. strcpy(pTemp, &argv[CurArg][1]);
  94. if (pTemp[strlen(pTemp)-1] == '"')
  95. pTemp[strlen(pTemp)-1] = 0;
  96. else
  97. return(1);
  98. }
  99. else
  100. strcpy(pTemp, argv[CurArg]);
  101. retval = ExpandEnvironmentStringsA(pTemp, Repl, dwMaxLen);
  102. if ((retval == 0) || (retval > dwMaxLen))
  103. return(1);
  104. ReplLen = strlen(Repl);
  105. if (ReplLen < 1)
  106. return(1);
  107. CurArg++;
  108. InFN = argv[CurArg];
  109. CurArg++;
  110. OutFN = argv[CurArg];
  111. #ifdef ACSR_DEBUG
  112. printf("Srch <%s>\n",Srch);
  113. printf("Repl <%s>\n",Repl);
  114. printf("InFN <%s>\n",InFN);
  115. printf("OutFN <%s>\n",OutFN);
  116. #endif
  117. if (strstr(Repl,".lnk") || strstr(Repl, ".LNK")) {
  118. hFile = CreateFileA( Repl,
  119. GENERIC_READ,
  120. FILE_SHARE_READ,
  121. NULL,
  122. OPEN_EXISTING,
  123. FILE_ATTRIBUTE_NORMAL,
  124. NULL
  125. );
  126. if (hFile != INVALID_HANDLE_VALUE) {
  127. ReadLnkCommandFile(hFile);
  128. #ifdef ACSR_DEBUG
  129. printf("This is a .lnk file. Substitue with the real cmd %s\n", Repl);
  130. #endif
  131. }
  132. }
  133. InFP = fopen(InFN, "r");
  134. if (InFP == NULL)
  135. return(1);
  136. OutFP = fopen(OutFN, "w");
  137. if (OutFP == NULL)
  138. {
  139. fclose(InFP);
  140. return(1);
  141. }
  142. while (1)
  143. {
  144. if (fgets(pTemp, MAXLEN, InFP) == NULL)
  145. break;
  146. ptr = pTemp;
  147. Temp1[0] = 0; // Empty String
  148. while (1)
  149. {
  150. Loc = strstr(ptr, Srch);
  151. if (Loc == NULL) // Search Term Not Found
  152. break;
  153. // Append part of string before search term
  154. Loc[0] = 0;
  155. if (strlen(Temp1) + strlen(ptr) < MAXLEN)
  156. strcat(Temp1, ptr);
  157. // Append Replacement term
  158. if (strlen(Temp1) + ReplLen < MAXLEN)
  159. strcat(Temp1, Repl);
  160. // Point to location past search term
  161. ptr = Loc + SrchLen;
  162. }
  163. // Append remainder of string
  164. strcat(Temp1, ptr);
  165. fputs(Temp1, OutFP);
  166. }
  167. fclose(InFP);
  168. fclose(OutFP);
  169. if (fAlloc) {
  170. HeapFree(GetProcessHeap(), 0, pTemp);
  171. }
  172. return(0);
  173. }
  174. //*-------------------------------------------------------------*//
  175. //* ReadLinkCommandFile *//
  176. //* This routine is to read a .lnk file and put the linked *//
  177. //* file name and args to the Repl[] global variable *//
  178. //* The logic to read the .lnk file is copied from *//
  179. //* lnkdump.exe utility private\windows\shell\tools\lnkdump *//
  180. //* ------------------------------------------------------------*//
  181. void ReadLnkCommandFile(HANDLE hFile //.lnk file handle
  182. )
  183. {
  184. CShellLink csl;
  185. CShellLink * this = &csl;
  186. DWORD cbSize, cbTotal, cbToRead, dwBytesRead;
  187. SYSTEMTIME st;
  188. LPSTR pTemp = NULL;
  189. CHAR szPath[ MAXLEN + 1];
  190. CHAR szArgs[ MAXLEN + 1];
  191. this->pidl = 0;
  192. this->pli = NULL;
  193. memset( this, 0, sizeof(CShellLink) );
  194. szPath[0] = 0;
  195. szArgs[0] = 0;
  196. // Now, read out data...
  197. if(!ReadFile( hFile, (LPVOID)&this->sld, sizeof(this->sld), &dwBytesRead, NULL )) {
  198. return;
  199. }
  200. // read all of the members
  201. if (this->sld.dwFlags & SLDF_HAS_ID_LIST) {
  202. // Read the size of the IDLIST
  203. cbSize = 0; // need to zero out to get HIWORD 0 'cause USHORT is only 2 bytes
  204. if(!ReadFile( hFile, (LPVOID)&cbSize, sizeof(USHORT), &dwBytesRead, NULL )) {
  205. return;
  206. }
  207. if (cbSize) {
  208. SetFilePointer(hFile,cbSize,NULL,FILE_CURRENT);
  209. } else {
  210. #ifdef ACSR_DEBUG
  211. printf( "Error readling PIDL out of link!\n" );
  212. #endif
  213. }
  214. }
  215. if (this->sld.dwFlags & (SLDF_HAS_LINK_INFO)) {
  216. LPVOID pli;
  217. if(!ReadFile( hFile, (LPVOID)&cbSize, sizeof(cbSize), &dwBytesRead, NULL )) {
  218. return;
  219. }
  220. if (cbSize >= sizeof(cbSize)) {
  221. cbSize -= sizeof(cbSize);
  222. SetFilePointer(hFile,cbSize,NULL,FILE_CURRENT);
  223. }
  224. }
  225. if (this->sld.dwFlags & SLDF_HAS_NAME) {
  226. if(!ReadString( hFile, &this->pszName, this->sld.dwFlags & SLDF_UNICODE)) {
  227. goto cleanup;
  228. }
  229. }
  230. if (this->sld.dwFlags & SLDF_HAS_RELPATH) {
  231. if(!ReadString( hFile, &this->pszRelPath, this->sld.dwFlags & SLDF_UNICODE)) {
  232. goto cleanup;
  233. }
  234. }
  235. if (this->sld.dwFlags & SLDF_HAS_WORKINGDIR) {
  236. if(!ReadString( hFile, &this->pszWorkingDir, this->sld.dwFlags & SLDF_UNICODE)) {
  237. goto cleanup;
  238. }
  239. }
  240. if (this->sld.dwFlags & SLDF_HAS_ARGS) {
  241. if(!ReadString( hFile, &this->pszArgs, this->sld.dwFlags & SLDF_UNICODE)) {
  242. goto cleanup;
  243. }
  244. }
  245. if (this->pszRelPath) {
  246. if (this->sld.dwFlags & SLDF_UNICODE) {
  247. WideCharToMultiByte( CP_ACP, 0,
  248. (LPWSTR)this->pszRelPath,
  249. -1,
  250. szPath,
  251. 256,
  252. NULL,
  253. NULL
  254. );
  255. } else {
  256. strcpy(szPath, (LPSTR)this->pszRelPath);
  257. }
  258. }
  259. if (this->pszArgs) {
  260. if (this->sld.dwFlags & SLDF_UNICODE) {
  261. WideCharToMultiByte( CP_ACP, 0,
  262. (LPWSTR)this->pszArgs,
  263. -1,
  264. szArgs,
  265. 256,
  266. NULL,
  267. NULL
  268. );
  269. } else {
  270. strcpy(szArgs, (LPSTR)this->pszArgs);
  271. }
  272. }
  273. // Construct the command
  274. if(szPath) {
  275. strcpy(Repl, szPath);
  276. strcat(Repl, " ");
  277. strcat(Repl, szArgs);
  278. }
  279. cleanup:
  280. if (this->pidl)
  281. LocalFree( (HLOCAL)this->pidl );
  282. if (this->pli)
  283. LocalFree( this->pli );
  284. if (this->pszName)
  285. HeapFree( GetProcessHeap(), 0, this->pszName );
  286. if (this->pszRelPath)
  287. HeapFree( GetProcessHeap(), 0, this->pszRelPath );
  288. if (this->pszWorkingDir)
  289. HeapFree( GetProcessHeap(), 0, this->pszWorkingDir );
  290. if (this->pszArgs)
  291. HeapFree( GetProcessHeap(), 0, this->pszArgs );
  292. if (this->pszIconLocation)
  293. HeapFree( GetProcessHeap(), 0, this->pszIconLocation );
  294. }
  295. //*------------------------------------------------------------*//
  296. //* This routine is copied from lnkdump.exe utility *//
  297. //* (private\windows\shell\tools\lnkdump\lnkdump.c) *//
  298. //* It reads a string from an opened .lnk file *//
  299. //* -----------------------------------------------------------*//
  300. BOOL ReadString( HANDLE hFile, LPVOID * lpVoid, BOOL bUnicode )
  301. {
  302. USHORT cch;
  303. DWORD dwBytesRead;
  304. *lpVoid = NULL;
  305. if(!ReadFile( hFile, (LPVOID)&cch, sizeof(cch), &dwBytesRead, NULL )) {
  306. return FALSE;
  307. }
  308. if (bUnicode)
  309. {
  310. LPWSTR lpWStr = NULL;
  311. lpWStr = (LPWSTR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (cch+1)*sizeof(WCHAR) );
  312. if (lpWStr) {
  313. if(!ReadFile( hFile, (LPVOID)lpWStr, cch*sizeof(WCHAR), &dwBytesRead, NULL )) {
  314. HeapFree( GetProcessHeap(), 0, lpWStr );
  315. return FALSE;
  316. }
  317. lpWStr[cch] = L'\0';
  318. }
  319. *(PDWORD_PTR)lpVoid = (DWORD_PTR)lpWStr;
  320. }
  321. else
  322. {
  323. LPSTR lpStr = NULL;
  324. lpStr = (LPSTR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (cch+1) );
  325. if (lpStr) {
  326. if(!ReadFile( hFile, (LPVOID)lpStr, cch, &dwBytesRead, NULL )) {
  327. HeapFree( GetProcessHeap(), 0, lpStr );
  328. return FALSE;
  329. }
  330. lpStr[cch] = '\0';
  331. }
  332. *(PDWORD_PTR)lpVoid = (DWORD_PTR)lpStr;
  333. }
  334. return TRUE;
  335. }