joachim99@77
|
1 // uninstallHelper.cpp : Defines the entry point for the console application.
|
joachim99@77
|
2 //
|
joachim99@77
|
3 #define _CRT_SECURE_NO_DEPRECATE
|
joachim99@77
|
4 #include "stdafx.h"
|
joachim99@77
|
5 #include <iostream>
|
joachim99@77
|
6 #include <string>
|
joachim99@77
|
7 #include <vector>
|
joachim99@77
|
8 #include <list>
|
joachim99@77
|
9 #include <windows.h>
|
joachim99@77
|
10 #include <string.h>
|
joachim99@77
|
11 #include <io.h>
|
joachim99@77
|
12
|
joachim99@77
|
13 //#define __stdcall
|
joachim99@77
|
14
|
joachim99@77
|
15 // For compilation download the NSIS source package and modify the following
|
joachim99@77
|
16 // line to point to the exdll.h-file
|
joachim99@77
|
17 #include "C:/Programme/NSIS/Contrib/ExDll/exdll.h"
|
joachim99@77
|
18
|
joachim99@77
|
19 struct ReplacementItem
|
joachim99@77
|
20 { char* fileType; char* operationType; };
|
joachim99@77
|
21
|
joachim99@77
|
22 ReplacementItem g_replacementTable[] = {
|
joachim99@77
|
23 "text_file_delta", "xcompare",
|
joachim99@77
|
24 "text_file_delta", "xmerge",
|
joachim99@77
|
25 "whole_copy", "xcompare",
|
joachim99@77
|
26 "whole_copy", "xmerge",
|
joachim99@77
|
27 "z_text_file_delta", "xcompare",
|
joachim99@77
|
28 "z_text_file_delta", "xmerge",
|
joachim99@77
|
29 "z_whole_copy", "xcompare",
|
joachim99@77
|
30 "z_whole_copy", "xmerge",
|
joachim99@77
|
31 "_xml", "xcompare",
|
joachim99@77
|
32 "_xml", "xmerge",
|
joachim99@77
|
33 "_xml2", "xcompare",
|
joachim99@77
|
34 "_xml2", "xmerge",
|
joachim99@77
|
35 "_rftdef", "xcompare",
|
joachim99@77
|
36 "_rftmap", "xcompare",
|
joachim99@77
|
37 "_rftvp", "xcompare",
|
joachim99@77
|
38 "_xtools", "xcompare",
|
joachim99@77
|
39 0,0
|
joachim99@77
|
40 };
|
joachim99@77
|
41
|
joachim99@77
|
42 struct LineItem
|
joachim99@77
|
43 {
|
joachim99@77
|
44 std::string fileType;
|
joachim99@77
|
45 std::string opType;
|
joachim99@77
|
46 std::string command;
|
joachim99@77
|
47 std::string fileOpPart;
|
joachim99@77
|
48 };
|
joachim99@77
|
49
|
joachim99@77
|
50 // Return true if successful, else false
|
joachim99@77
|
51 bool readAndParseMapFile( const std::string& filename, std::list<LineItem>& lineItemList )
|
joachim99@77
|
52 {
|
joachim99@77
|
53 // Read file
|
joachim99@77
|
54 FILE* pFile = fopen( filename.c_str(), "r" );
|
joachim99@77
|
55 if (pFile)
|
joachim99@77
|
56 {
|
joachim99@77
|
57 fseek(pFile,0,SEEK_END);
|
joachim99@77
|
58 int size = ftell(pFile);
|
joachim99@77
|
59 fseek(pFile,0,SEEK_SET);
|
joachim99@77
|
60 std::vector<char> buf( size );
|
joachim99@77
|
61 fread( &buf[0], 1, size, pFile );
|
joachim99@77
|
62 fclose( pFile );
|
joachim99@77
|
63
|
joachim99@77
|
64 // Replace strings
|
joachim99@77
|
65 int lineStartPos=0;
|
joachim99@77
|
66 int wordInLine = 0;
|
joachim99@77
|
67 LineItem lineItem;
|
joachim99@77
|
68 for( int i=0; i<size; )
|
joachim99@77
|
69 {
|
joachim99@77
|
70 if( buf[i] == '\n' || buf[i] == '\r' )
|
joachim99@77
|
71 {
|
joachim99@77
|
72 ++i;
|
joachim99@77
|
73 wordInLine = 0;
|
joachim99@77
|
74 lineStartPos = i;
|
joachim99@77
|
75 continue;
|
joachim99@77
|
76 }
|
joachim99@77
|
77 if( buf[i] == ' ' || buf[i] == '\t' )
|
joachim99@77
|
78 {
|
joachim99@77
|
79 ++i;
|
joachim99@77
|
80 continue;
|
joachim99@77
|
81 }
|
joachim99@77
|
82 else
|
joachim99@77
|
83 {
|
joachim99@77
|
84 int wordStartPos = i;
|
joachim99@77
|
85 if (wordInLine<2)
|
joachim99@77
|
86 {
|
joachim99@77
|
87 while ( i<size && !( buf[i] == ' ' || buf[i] == '\t' ) )
|
joachim99@77
|
88 ++i;
|
joachim99@77
|
89
|
joachim99@77
|
90 std::string word( &buf[wordStartPos], i-wordStartPos );
|
joachim99@77
|
91 if (wordInLine==0)
|
joachim99@77
|
92 lineItem.fileType = word;
|
joachim99@77
|
93 else
|
joachim99@77
|
94 lineItem.opType = word;
|
joachim99@77
|
95 ++wordInLine;
|
joachim99@77
|
96 }
|
joachim99@77
|
97 else
|
joachim99@77
|
98 {
|
joachim99@77
|
99 lineItem.fileOpPart = std::string( &buf[lineStartPos], i-lineStartPos );
|
joachim99@77
|
100 while ( i<size && !( buf[i] == '\n' || buf[i] == '\r' ) )
|
joachim99@77
|
101 ++i;
|
joachim99@77
|
102
|
joachim99@77
|
103 std::string word( &buf[wordStartPos], i-wordStartPos );
|
joachim99@77
|
104 lineItem.command = word;
|
joachim99@77
|
105 lineItemList.push_back( lineItem );
|
joachim99@77
|
106 }
|
joachim99@77
|
107 }
|
joachim99@77
|
108 }
|
joachim99@77
|
109 }
|
joachim99@77
|
110 else
|
joachim99@77
|
111 {
|
joachim99@77
|
112 return false;
|
joachim99@77
|
113 }
|
joachim99@77
|
114 return true;
|
joachim99@77
|
115 }
|
joachim99@77
|
116
|
joachim99@77
|
117 bool writeMapFile( const std::string& filename, const std::list<LineItem>& lineItemList )
|
joachim99@77
|
118 {
|
joachim99@77
|
119 FILE* pFile = fopen( filename.c_str(), "w" );
|
joachim99@77
|
120 if (pFile)
|
joachim99@77
|
121 {
|
joachim99@77
|
122 std::list<LineItem>::const_iterator i = lineItemList.begin();
|
joachim99@77
|
123 for( ; i!=lineItemList.end(); ++i )
|
joachim99@77
|
124 {
|
joachim99@77
|
125 const LineItem& li = *i;
|
joachim99@77
|
126 fprintf( pFile, "%s%s\n", li.fileOpPart.c_str(), li.command.c_str() );
|
joachim99@77
|
127 }
|
joachim99@77
|
128 fclose( pFile );
|
joachim99@77
|
129 }
|
joachim99@77
|
130 else
|
joachim99@77
|
131 {
|
joachim99@77
|
132 return false;
|
joachim99@77
|
133 }
|
joachim99@77
|
134 return true;
|
joachim99@77
|
135 }
|
joachim99@77
|
136
|
joachim99@77
|
137 std::string toUpper( const std::string& s )
|
joachim99@77
|
138 {
|
joachim99@77
|
139 std::string s2 = s;
|
joachim99@77
|
140
|
joachim99@77
|
141 for( unsigned int i=0; i<s.length(); ++i )
|
joachim99@77
|
142 {
|
joachim99@77
|
143 s2[i] = toupper( s2[i] );
|
joachim99@77
|
144 }
|
joachim99@77
|
145 return s2;
|
joachim99@77
|
146 }
|
joachim99@77
|
147
|
joachim99@77
|
148 int install( const _TCHAR* subCommand, const _TCHAR* kdiff3CommandPath )
|
joachim99@77
|
149 {
|
joachim99@77
|
150 std::string installCommand = subCommand; // "install" or "uninstall"
|
joachim99@77
|
151 std::string kdiff3Command = kdiff3CommandPath;
|
joachim99@77
|
152
|
joachim99@77
|
153 /*
|
joachim99@77
|
154 std::wstring installCommand = subCommand; // "install" or "uninstall"
|
joachim99@77
|
155 std::wstring wKDiff3Command = kdiff3CommandPath;
|
joachim99@77
|
156 std::string kdiff3Command;
|
joachim99@77
|
157 kdiff3Command.reserve( wKDiff3Command.length()+1 );
|
joachim99@77
|
158 kdiff3Command.resize( wKDiff3Command.length() );
|
joachim99@77
|
159 BOOL bUsedDefaultChar = FALSE;
|
joachim99@77
|
160 int successLen = WideCharToMultiByte( CP_ACP, 0,
|
joachim99@77
|
161 wKDiff3Command.c_str(), int(wKDiff3Command.length()),
|
joachim99@77
|
162 &kdiff3Command[0], int(kdiff3Command.length()), 0, &bUsedDefaultChar );
|
joachim99@77
|
163
|
joachim99@77
|
164 if ( successLen != kdiff3Command.length() || bUsedDefaultChar )
|
joachim99@77
|
165 {
|
joachim99@77
|
166 std::cerr << "KDiff3 command contains characters that don't map to ansi code page.\n"
|
joachim99@77
|
167 "Aborting clearcase installation.\n"
|
joachim99@77
|
168 "Try to install KDiff3 in another path that doesn't require special characters.\n";
|
joachim99@77
|
169 return -1;
|
joachim99@77
|
170 }
|
joachim99@77
|
171 */
|
joachim99@77
|
172
|
joachim99@77
|
173 // Try to locate cleartool, the clearcase tool in the path
|
joachim99@77
|
174 char buffer[1000];
|
joachim99@77
|
175 char* pLastPart = 0;
|
joachim99@77
|
176 int len = SearchPathA(0, "cleartool.exe", 0, sizeof(buffer)/sizeof(buffer[0]),
|
joachim99@77
|
177 buffer, &pLastPart );
|
joachim99@77
|
178 if ( len+1<int(sizeof(buffer)/sizeof(buffer[0])) && pLastPart )
|
joachim99@77
|
179 {
|
joachim99@77
|
180 pLastPart[-1] = 0;
|
joachim99@77
|
181 pLastPart = strchr( buffer, '\\' ); // cd up (because cleartool.exe is in bin subdir)
|
joachim99@77
|
182 if ( pLastPart )
|
joachim99@77
|
183 pLastPart[1]=0;
|
joachim99@77
|
184
|
joachim99@77
|
185 std::string path( buffer );
|
joachim99@77
|
186 path += _T("lib\\mgrs\\map");
|
joachim99@77
|
187 std::string bakName = path + _T(".preKDiff3Install");
|
joachim99@77
|
188
|
joachim99@77
|
189 if ( installCommand == _T("install") )
|
joachim99@77
|
190 {
|
joachim99@77
|
191 std::list<LineItem> lineItemList;
|
joachim99@77
|
192 bool bSuccess = readAndParseMapFile( path, lineItemList );
|
joachim99@77
|
193 if ( !bSuccess )
|
joachim99@77
|
194 {
|
joachim99@77
|
195 std::cerr << "Error reading original map file.\n";
|
joachim99@77
|
196 return -1;
|
joachim99@77
|
197 }
|
joachim99@77
|
198
|
joachim99@77
|
199 // Create backup
|
joachim99@77
|
200 if ( access( bakName.c_str(), 0 )!=0 ) // Create backup only if not exists yet
|
joachim99@77
|
201 {
|
joachim99@77
|
202 if ( rename( path.c_str(), bakName.c_str() ) )
|
joachim99@77
|
203 {
|
joachim99@77
|
204 std::cerr << "Error renaming original map file.\n";
|
joachim99@77
|
205 return -1;
|
joachim99@77
|
206 }
|
joachim99@77
|
207 }
|
joachim99@77
|
208
|
joachim99@77
|
209 std::list<LineItem>::iterator i = lineItemList.begin();
|
joachim99@77
|
210 for( ; i!=lineItemList.end(); ++i )
|
joachim99@77
|
211 {
|
joachim99@77
|
212 LineItem& li = *i;
|
joachim99@77
|
213 for (int j=0;;++j)
|
joachim99@77
|
214 {
|
joachim99@77
|
215 ReplacementItem& ri = g_replacementTable[j];
|
joachim99@77
|
216 if ( ri.fileType==0 || ri.operationType==0 )
|
joachim99@77
|
217 break;
|
joachim99@77
|
218 if ( li.fileType == ri.fileType && li.opType == ri.operationType )
|
joachim99@77
|
219 {
|
joachim99@77
|
220 li.command = kdiff3Command.c_str();
|
joachim99@77
|
221 break;
|
joachim99@77
|
222 }
|
joachim99@77
|
223 }
|
joachim99@77
|
224 }
|
joachim99@77
|
225
|
joachim99@77
|
226 bSuccess = writeMapFile( path, lineItemList );
|
joachim99@77
|
227 if ( !bSuccess )
|
joachim99@77
|
228 {
|
joachim99@77
|
229 if ( rename( bakName.c_str(), path.c_str() ) )
|
joachim99@77
|
230 std::cerr << "Error writing new map file, restoring old file also failed.\n";
|
joachim99@77
|
231 else
|
joachim99@77
|
232 std::cerr << "Error writing new map file, old file restored.\n";
|
joachim99@77
|
233
|
joachim99@77
|
234 return -1;
|
joachim99@77
|
235 }
|
joachim99@77
|
236 }
|
joachim99@77
|
237 else if ( installCommand == _T("uninstall") )
|
joachim99@77
|
238 {
|
joachim99@77
|
239 std::list<LineItem> lineItemList;
|
joachim99@77
|
240 bool bSuccess = readAndParseMapFile( path, lineItemList );
|
joachim99@77
|
241 if ( !bSuccess )
|
joachim99@77
|
242 {
|
joachim99@77
|
243 std::cerr << "Error reading original map file\n.";
|
joachim99@77
|
244 return -1;
|
joachim99@77
|
245 }
|
joachim99@77
|
246
|
joachim99@77
|
247 std::list<LineItem> lineItemListBak;
|
joachim99@77
|
248 bSuccess = readAndParseMapFile( bakName, lineItemListBak );
|
joachim99@77
|
249 if ( !bSuccess )
|
joachim99@77
|
250 {
|
joachim99@77
|
251 std::cerr << "Error reading backup map file.\n";
|
joachim99@77
|
252 return -1;
|
joachim99@77
|
253 }
|
joachim99@77
|
254
|
joachim99@77
|
255 std::list<LineItem>::iterator i = lineItemList.begin();
|
joachim99@77
|
256 for( ; i!=lineItemList.end(); ++i )
|
joachim99@77
|
257 {
|
joachim99@77
|
258 LineItem& li = *i;
|
joachim99@77
|
259 if ((int)toUpper(li.command).find("KDIFF3")>=0)
|
joachim99@77
|
260 {
|
joachim99@77
|
261 std::list<LineItem>::const_iterator j = lineItemListBak.begin();
|
joachim99@77
|
262 for (;j!=lineItemListBak.end();++j)
|
joachim99@77
|
263 {
|
joachim99@77
|
264 const LineItem& bi = *j; // backup iterator
|
joachim99@77
|
265 if ( li.fileType == bi.fileType && li.opType == bi.opType )
|
joachim99@77
|
266 {
|
joachim99@77
|
267 li.command = bi.command;
|
joachim99@77
|
268 break;
|
joachim99@77
|
269 }
|
joachim99@77
|
270 }
|
joachim99@77
|
271 }
|
joachim99@77
|
272 }
|
joachim99@77
|
273
|
joachim99@77
|
274 bSuccess = writeMapFile( path, lineItemList );
|
joachim99@77
|
275 if ( !bSuccess )
|
joachim99@77
|
276 {
|
joachim99@77
|
277 std::cerr << "Error writing map file.";
|
joachim99@77
|
278
|
joachim99@77
|
279 return -1;
|
joachim99@77
|
280 }
|
joachim99@77
|
281 }
|
joachim99@77
|
282 }
|
joachim99@77
|
283 return 0;
|
joachim99@77
|
284 }
|
joachim99@77
|
285
|
joachim99@77
|
286 extern "C"
|
joachim99@77
|
287 void __declspec(dllexport) nsisPlugin(HWND hwndParent, int string_size,
|
joachim99@77
|
288 char *variables, stack_t **stacktop,
|
joachim99@77
|
289 extra_parameters *extra)
|
joachim99@77
|
290 {
|
joachim99@77
|
291 //g_hwndParent=hwndParent;
|
joachim99@77
|
292
|
joachim99@77
|
293 EXDLL_INIT();
|
joachim99@77
|
294 {
|
joachim99@77
|
295 std::string param1( g_stringsize, ' ' );
|
joachim99@77
|
296 int retVal = popstring( ¶m1[0] );
|
joachim99@77
|
297 if ( retVal == 0 )
|
joachim99@77
|
298 {
|
joachim99@77
|
299 std::string param2( g_stringsize, ' ' );
|
joachim99@77
|
300 retVal = popstring( ¶m2[0] );
|
joachim99@77
|
301 if ( retVal == 0 )
|
joachim99@77
|
302 install( param1.c_str(), param2.c_str() );
|
joachim99@77
|
303 return;
|
joachim99@77
|
304 }
|
joachim99@77
|
305 std::cerr << "Not enough parameters." << std::endl;
|
joachim99@77
|
306 }
|
joachim99@77
|
307 }
|
joachim99@77
|
308
|
joachim99@77
|
309 /*
|
joachim99@77
|
310 int _tmain(int argc, _TCHAR* argv[])
|
joachim99@77
|
311 {
|
joachim99@77
|
312 if ( argc<3 )
|
joachim99@77
|
313 {
|
joachim99@77
|
314 std::cout << "This program is needed to install/uninstall KDiff3 for clearcase.\n"
|
joachim99@77
|
315 "It tries to patch the map file (clearcase-subdir\\lib\\mgrs\\map)\n"
|
joachim99@77
|
316 "Usage 1: ccInstHelper install pathToKdiff3.exe\n"
|
joachim99@77
|
317 "Usage 2: ccInstHelper uninstall pathToKdiff3.exe\n"
|
joachim99@77
|
318 "Backups of the original map files are created in the dir of the map file.\n";
|
joachim99@77
|
319 }
|
joachim99@77
|
320 else
|
joachim99@77
|
321 {
|
joachim99@77
|
322 return install( argv[1], argv[2] );
|
joachim99@77
|
323 }
|
joachim99@77
|
324
|
joachim99@77
|
325 return 0;
|
joachim99@77
|
326 }
|
joachim99@77
|
327 */
|