|
|
// 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; }
|