// Copyright (c) 1998-1999 Microsoft Corporation /****************************************************************************** * * ACSR.C * * Application Compatibility Search and Replace Helper Program * * *******************************************************************************/ #include "precomp.h" #pragma hdrstop #define MAXLEN 512 char Temp[MAXLEN+1]; char Temp1[MAXLEN+1]; char Srch[MAXLEN+1]; char Repl[2*MAXLEN+2]; char *InFN; char *OutFN; //*------------------------------------------------------------*// //* Local function prototypes *// //*------------------------------------------------------------*// BOOL ReadString( HANDLE hFile, LPVOID * lpVoid, BOOL bUnicode ); void ReadLnkCommandFile(HANDLE hFile); /******************************************************************************* * * main * ******************************************************************************/ int __cdecl main(INT argc, CHAR **argv) { DWORD retval; int CurArg = 1; FILE *InFP; FILE *OutFP; int SrchLen, ReplLen; char *ptr, *Loc; HANDLE hFile; DWORD dwMaxLen = MAXLEN; DWORD dwLen; char* pTemp = Temp; BOOL fAlloc = FALSE; if (argc != 5) return(1); // //331012 Unbounded strcpy in termsrv\appcmpt\acsr\acsr.c //check for argv[] length and alloc if needed // dwLen = strlen(argv[CurArg]); if (dwLen > dwMaxLen) { dwMaxLen = dwLen; pTemp = (LPSTR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (dwMaxLen+1)*sizeof(char) ); if (NULL == pTemp) return(1); fAlloc = TRUE; } if (argv[CurArg][0] == '"') { strcpy(pTemp, &argv[CurArg][1]); if (pTemp[strlen(pTemp)-1] == '"') pTemp[strlen(pTemp)-1] = 0; else return(1); } else strcpy(pTemp, argv[CurArg]); retval = ExpandEnvironmentStringsA(pTemp, Srch, dwMaxLen); if ((retval == 0) || (retval > dwMaxLen)) return(1); SrchLen = strlen(Srch); if (SrchLen < 1) return(1); CurArg++; // //331012 Unbounded strcpy in termsrv\appcmpt\acsr\acsr.c //check for argv[] length and realloc if needed // dwLen = strlen(argv[CurArg]); if (dwLen > dwMaxLen) { dwMaxLen = dwLen; // //check if we allocated for pTemp above, if so, free it first // if (fAlloc) { HeapFree(GetProcessHeap(), 0, pTemp); } pTemp = (LPSTR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (dwMaxLen+1)*sizeof(char) ); if (NULL == pTemp) return(1); fAlloc = TRUE; } if (argv[CurArg][0] == '"') { strcpy(pTemp, &argv[CurArg][1]); if (pTemp[strlen(pTemp)-1] == '"') pTemp[strlen(pTemp)-1] = 0; else return(1); } else strcpy(pTemp, argv[CurArg]); retval = ExpandEnvironmentStringsA(pTemp, Repl, dwMaxLen); if ((retval == 0) || (retval > dwMaxLen)) return(1); ReplLen = strlen(Repl); if (ReplLen < 1) return(1); CurArg++; InFN = argv[CurArg]; CurArg++; OutFN = argv[CurArg]; #ifdef ACSR_DEBUG printf("Srch <%s>\n",Srch); printf("Repl <%s>\n",Repl); printf("InFN <%s>\n",InFN); printf("OutFN <%s>\n",OutFN); #endif if (strstr(Repl,".lnk") || strstr(Repl, ".LNK")) { hFile = CreateFileA( Repl, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hFile != INVALID_HANDLE_VALUE) { ReadLnkCommandFile(hFile); #ifdef ACSR_DEBUG printf("This is a .lnk file. Substitue with the real cmd %s\n", Repl); #endif } } InFP = fopen(InFN, "r"); if (InFP == NULL) return(1); OutFP = fopen(OutFN, "w"); if (OutFP == NULL) { fclose(InFP); return(1); } while (1) { if (fgets(pTemp, MAXLEN, InFP) == NULL) break; ptr = pTemp; Temp1[0] = 0; // Empty String while (1) { Loc = strstr(ptr, Srch); if (Loc == NULL) // Search Term Not Found break; // Append part of string before search term Loc[0] = 0; if (strlen(Temp1) + strlen(ptr) < MAXLEN) strcat(Temp1, ptr); // Append Replacement term if (strlen(Temp1) + ReplLen < MAXLEN) strcat(Temp1, Repl); // Point to location past search term ptr = Loc + SrchLen; } // Append remainder of string strcat(Temp1, ptr); fputs(Temp1, OutFP); } fclose(InFP); fclose(OutFP); if (fAlloc) { HeapFree(GetProcessHeap(), 0, pTemp); } return(0); } //*-------------------------------------------------------------*// //* ReadLinkCommandFile *// //* This routine is to read a .lnk file and put the linked *// //* file name and args to the Repl[] global variable *// //* The logic to read the .lnk file is copied from *// //* lnkdump.exe utility private\windows\shell\tools\lnkdump *// //* ------------------------------------------------------------*// void ReadLnkCommandFile(HANDLE hFile //.lnk file handle ) { CShellLink csl; CShellLink * this = &csl; DWORD cbSize, cbTotal, cbToRead, dwBytesRead; SYSTEMTIME st; LPSTR pTemp = NULL; CHAR szPath[ MAXLEN + 1]; CHAR szArgs[ MAXLEN + 1]; this->pidl = 0; this->pli = NULL; memset( this, 0, sizeof(CShellLink) ); szPath[0] = 0; szArgs[0] = 0; // Now, read out data... if(!ReadFile( hFile, (LPVOID)&this->sld, sizeof(this->sld), &dwBytesRead, NULL )) { return; } // read all of the members if (this->sld.dwFlags & SLDF_HAS_ID_LIST) { // Read the size of the IDLIST cbSize = 0; // need to zero out to get HIWORD 0 'cause USHORT is only 2 bytes if(!ReadFile( hFile, (LPVOID)&cbSize, sizeof(USHORT), &dwBytesRead, NULL )) { return; } if (cbSize) { SetFilePointer(hFile,cbSize,NULL,FILE_CURRENT); } else { #ifdef ACSR_DEBUG printf( "Error readling PIDL out of link!\n" ); #endif } } if (this->sld.dwFlags & (SLDF_HAS_LINK_INFO)) { LPVOID pli; if(!ReadFile( hFile, (LPVOID)&cbSize, sizeof(cbSize), &dwBytesRead, NULL )) { return; } if (cbSize >= sizeof(cbSize)) { cbSize -= sizeof(cbSize); SetFilePointer(hFile,cbSize,NULL,FILE_CURRENT); } } if (this->sld.dwFlags & SLDF_HAS_NAME) { if(!ReadString( hFile, &this->pszName, this->sld.dwFlags & SLDF_UNICODE)) { goto cleanup; } } if (this->sld.dwFlags & SLDF_HAS_RELPATH) { if(!ReadString( hFile, &this->pszRelPath, this->sld.dwFlags & SLDF_UNICODE)) { goto cleanup; } } if (this->sld.dwFlags & SLDF_HAS_WORKINGDIR) { if(!ReadString( hFile, &this->pszWorkingDir, this->sld.dwFlags & SLDF_UNICODE)) { goto cleanup; } } if (this->sld.dwFlags & SLDF_HAS_ARGS) { if(!ReadString( hFile, &this->pszArgs, this->sld.dwFlags & SLDF_UNICODE)) { goto cleanup; } } if (this->pszRelPath) { if (this->sld.dwFlags & SLDF_UNICODE) { WideCharToMultiByte( CP_ACP, 0, (LPWSTR)this->pszRelPath, -1, szPath, 256, NULL, NULL ); } else { strcpy(szPath, (LPSTR)this->pszRelPath); } } if (this->pszArgs) { if (this->sld.dwFlags & SLDF_UNICODE) { WideCharToMultiByte( CP_ACP, 0, (LPWSTR)this->pszArgs, -1, szArgs, 256, NULL, NULL ); } else { strcpy(szArgs, (LPSTR)this->pszArgs); } } // Construct the command if(szPath) { strcpy(Repl, szPath); strcat(Repl, " "); strcat(Repl, szArgs); } cleanup: if (this->pidl) LocalFree( (HLOCAL)this->pidl ); if (this->pli) LocalFree( this->pli ); if (this->pszName) HeapFree( GetProcessHeap(), 0, this->pszName ); if (this->pszRelPath) HeapFree( GetProcessHeap(), 0, this->pszRelPath ); if (this->pszWorkingDir) HeapFree( GetProcessHeap(), 0, this->pszWorkingDir ); if (this->pszArgs) HeapFree( GetProcessHeap(), 0, this->pszArgs ); if (this->pszIconLocation) HeapFree( GetProcessHeap(), 0, this->pszIconLocation ); } //*------------------------------------------------------------*// //* This routine is copied from lnkdump.exe utility *// //* (private\windows\shell\tools\lnkdump\lnkdump.c) *// //* It reads a string from an opened .lnk file *// //* -----------------------------------------------------------*// BOOL ReadString( HANDLE hFile, LPVOID * lpVoid, BOOL bUnicode ) { USHORT cch; DWORD dwBytesRead; *lpVoid = NULL; if(!ReadFile( hFile, (LPVOID)&cch, sizeof(cch), &dwBytesRead, NULL )) { return FALSE; } if (bUnicode) { LPWSTR lpWStr = NULL; lpWStr = (LPWSTR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (cch+1)*sizeof(WCHAR) ); if (lpWStr) { if(!ReadFile( hFile, (LPVOID)lpWStr, cch*sizeof(WCHAR), &dwBytesRead, NULL )) { HeapFree( GetProcessHeap(), 0, lpWStr ); return FALSE; } lpWStr[cch] = L'\0'; } *(PDWORD_PTR)lpVoid = (DWORD_PTR)lpWStr; } else { LPSTR lpStr = NULL; lpStr = (LPSTR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (cch+1) ); if (lpStr) { if(!ReadFile( hFile, (LPVOID)lpStr, cch, &dwBytesRead, NULL )) { HeapFree( GetProcessHeap(), 0, lpStr ); return FALSE; } lpStr[cch] = '\0'; } *(PDWORD_PTR)lpVoid = (DWORD_PTR)lpStr; } return TRUE; }