source: trunk/gsinstaller/unInstall.cpp@ 1673

Last change on this file since 1673 was 1673, checked in by cs025, 23 years ago

Fixed problem in uninstalling which appeared when uninstalling the shortcut
icons.
Parameters to undo didn't permit two parameters to be the same, and if for
example a shortcut was in a group with the same name, a parameter
disappeared. Fixed by extending stringArray class to be configured to accept
duplicate entries.

  • Property svn:keywords set to Author Date Id Revision
File size: 6.6 KB
Line 
1#include "unInstall.h"
2
3#include <stdio.h>
4#include <stdarg.h>
5#include "File.h"
6
7bool installManager::logExists()
8{
9 HANDLE fHandle;
10
11 fHandle = CreateFile(this->logfileName.c_str(), GENERIC_READ | GENERIC_WRITE,
12 FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
13 FILE_ATTRIBUTE_NORMAL, NULL);
14 if (fHandle == INVALID_HANDLE_VALUE)
15 { return false;
16 }
17 CloseHandle(fHandle);
18 return true;
19}
20
21bool installManager::ensureLog()
22{
23 if (this->logExists() == false)
24 { HANDLE fHandle;
25
26 fHandle = CreateFile(this->logfileName.c_str(), GENERIC_READ | GENERIC_WRITE,
27 FILE_SHARE_WRITE, NULL, CREATE_NEW,
28 FILE_ATTRIBUTE_NORMAL, NULL);
29 if (fHandle != INVALID_HANDLE_VALUE)
30 {
31 CloseHandle(fHandle);
32 return true;
33 }
34 return false;
35 }
36 return true;
37}
38
39bool installManager::setLogFile(string filename)
40{ this->logfileName = filename;
41 this->setModule("default");
42 return true;
43}
44
45bool installManager::readLog()
46{ string command;
47 stringArray params;
48
49 // don't try to open an non-existing log; this has serious
50 // repercussions with bad old VC++
51 if (!this->logExists())
52 { this->setModule("default");
53 this->changed = false;
54 return true;
55 }
56
57 // open the log file
58 this->logfile.open(this->logfileName.c_str(), ios::in);
59#ifndef __BORLANDC__
60 if (this->logfile.is_open())
61#else
62 if (this->logfile.rdbuf()->is_open())
63#endif
64 {
65 // Get the commands into this object from the existing log file
66 while ((command = this->readCommand(params)) != "")
67 { if (command[0] == '[' && command[command.length()-1] == ']')
68 { this->setModule(command.substr(1, command.length() - 2));
69 }
70 else
71 { unInstallCommand action(command, params);
72 this->storeCommand(action);
73 }
74 }
75
76 // close the logfile
77 this->logfile.close();
78
79 // and clear the status bits, 'cos VC++ doesn't clear them when
80 // we reopen the file later.
81 this->logfile.clear();
82 }
83 this->changed = false;
84
85 // set to the default module
86 this->setModule("default");
87 return true;
88}
89
90void installManager::setModule(string moduleName)
91{ this->currentModule = moduleName;
92}
93
94bool installManager::storeCommand(unInstallCommand &command)
95{ this->modules[this->currentModule].push_back(command);
96 this->changed = true; // set the "changed" flag
97 return true;
98}
99
100bool installManager::writeCommand(unInstallCommand &command)
101{ if (!this->writeString(command.command))
102 { return false;
103 }
104 for (unsigned int p = 0; p < command.parameters.size(); p ++)
105 { if (!this->writeSeparator())
106 { return false;
107 }
108 if (!this->writeString(command.parameters[p]))
109 { return false;
110 }
111 }
112 if (!this->writeString("\n"))
113 { return false;
114 }
115 return true;
116}
117
118bool installManager::writeString(char *buffer)
119{ string s(buffer);
120 return this->writeString(s);
121}
122
123bool installManager::writeString(string str)
124{ bool quote;
125
126 // TODO: check for space characters in str and quote if necessary
127 quote = str.find_first_of(' ') < str.length();
128
129 if (quote)
130 { this->logfile << "\"";
131 }
132 this->logfile << str;
133 if (quote)
134 { this->logfile << "\"";
135 }
136 return true;
137}
138
139bool installManager::writeSeparator()
140{ this->logfile << " ";
141 return true;
142}
143
144string installManager::readString()
145{ string reply = "";
146 char c;
147
148 if (this->logfile.eof())
149 { return reply;
150 }
151
152 this->logfile >> c;
153 while (c <= ' ' && !this->logfile.eof())
154 { this->logfile.get();
155 }
156
157 if (this->logfile.eof())
158 { return reply;
159 }
160
161 if (c == '\"')
162 { do
163 { c = this->logfile.get();
164 if (c != '\"')
165 { reply += c;
166 }
167 }
168 while (c != '\"' && !this->logfile.eof());
169 }
170 else
171 { while (c > ' ')
172 { reply += c;
173 if (this->logfile.eof())
174 { break;
175 }
176 c = this->logfile.get();
177 }
178 if (!this->logfile.eof())
179 { this->logfile.putback(c);
180 }
181 //this->logfile >> reply;
182 }
183 return reply;
184}
185
186string installManager::readCommand(stringArray &array)
187{ string reply = "";
188 char c;
189
190 array.clear();
191
192 if (this->logfile.eof())
193 { return reply;
194 }
195
196 reply = this->readString();
197 if (reply == "")
198 { return reply;
199 }
200
201 while(!this->logfile.eof() &&
202 (c = this->logfile.get()) != '\n')
203 { this->logfile.putback(c);
204 array.add(this->readString());
205 }
206 if (!this->logfile.eof())
207 { this->logfile.putback(c);
208 }
209
210 return reply;
211}
212
213string installManager::popCommand(stringArray &array)
214{ string command;
215
216 if (this->modules[this->currentModule].size() == 0)
217 { command = "";
218 }
219 else
220 { unsigned int last;
221
222 last = this->modules[this->currentModule].size() - 1;
223 command = this->modules[this->currentModule][last].commandName();
224 array = this->modules[this->currentModule][last].parameterList();
225 this->modules[this->currentModule].erase(this->modules[this->currentModule].begin() + last);
226 }
227 return command;
228}
229
230bool installManager::recordLog()
231{ // just return if there are no changes to record
232 if (this->changed == false)
233 { return true;
234 }
235
236 // if the file didn't open, then this is almost certainly being compiled
237 // with Microsoft Visual C++ which has a library which fails to open the
238 // file if it doesn't already exist. Do a createfile and hope for success.
239 // TODO: add proper error handling here
240 this->ensureLog();
241 this->logfile.open(this->logfileName.c_str(), ios::out);
242#ifndef __BORLANDC__
243 if (!this->logfile.is_open())
244#else
245 if (!this->logfile.rdbuf()->is_open())
246#endif
247 { MessageBox(0, "Unable to open log file", "Test", MB_OK);
248 }
249
250 unInstallCommandMap::iterator here = this->modules.begin();
251 unInstallCommandMap::iterator end = this->modules.end();
252
253 while (here != end)
254 {
255 this->writeString("[" + (*here).first + "]\n");
256
257 unInstallCommandList::iterator ahere = (*here).second.begin();
258 unInstallCommandList::iterator aend = (*here).second.end();
259
260 while (ahere != aend)
261 { this->writeCommand(*ahere);
262 ahere ++;
263 }
264 here ++;
265 }
266 this->logfile.close();
267
268 this->changed = false;
269
270 return true;
271}
272
273bool installManager::isEmpty()
274{ unInstallCommandMap::iterator here = this->modules.begin();
275 unInstallCommandMap::iterator end = this->modules.end();
276
277 while (here != end)
278 { this->writeString("[" + (*here).first + "]\n");
279
280 unInstallCommandList::iterator ahere = (*here).second.begin();
281 unInstallCommandList::iterator aend = (*here).second.end();
282 if (ahere != aend)
283 { return false;
284 }
285 here ++;
286 }
287 return true;
288}
289
290installManager::~installManager()
291{ this->recordLog();
292}
Note: See TracBrowser for help on using the repository browser.