source: trunk/gsinstaller/gsProgman.cpp@ 1397

Last change on this file since 1397 was 1397, checked in by cs025, 24 years ago

Initial revision

  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1#include "gsProgman.h"
2
3#include <stdio.h>
4
5// include shell for explorer-based OS'es
6#include <shlobj.h>
7// include dde for old (win 3.1/winNT 3.5) OS'es
8#include <ddeml.h>
9
10#include "FilePath.h"
11
12extern HINSTANCE app_instance;
13
14/**
15 * A private function for Dde callbacks; in practice it needs to be here,
16 * but does nothing whatsoever
17 */
18HDDEDATA CALLBACK DdeCallBack(
19 UINT uType, // transaction type
20 UINT uFmt, // clipboard data format
21 HCONV hconv, // handle to the conversation
22 HSZ hsz1, // handle to a string
23 HSZ hsz2, // handle to a string
24 HDDEDATA hdata, // handle to a global memory object
25 DWORD dwData1, // transaction-specific data
26 DWORD dwData2 // transaction-specific data
27 )
28{ return NULL;
29}
30
31 /**
32 * A private little function to do DDE activity
33 */
34bool DDEShellCommand(DWORD instance, char *command)
35{ HSZ serviceName;
36 HCONV conversation;
37 int commandLength;
38 HDDEDATA ddeData;
39 DWORD result;
40 bool reply = false;
41
42 // create DDE string from service request
43 serviceName = DdeCreateStringHandle(instance, "PROGMAN", CP_WINANSI);
44 if (serviceName == NULL)
45 { /*char buffer[20];
46 sprintf(buffer, "%d %d", DdeGetLastError(instance), instance);
47 MessageBox(0, buffer, "GSInstall", MB_OK);*/
48 return FALSE;
49 }
50
51 // strike up a conversation with the DDE service
52 if ((conversation = DdeConnect(instance, serviceName, serviceName, NULL)) != NULL)
53 { commandLength = lstrlen(command);
54
55 // send the message via DDE
56// MessageBox(0, command, "Executing", MB_OK);
57 ddeData = DdeClientTransaction((LPBYTE) command, commandLength + 1,
58 conversation, NULL, CF_TEXT, XTYP_EXECUTE,
59 1000, &result);
60 // if our reply isn't NULL, it succeeded
61 reply = (ddeData != NULL);
62 if (reply == false)
63 { /*
64 char buffer[20];
65
66 sprintf(buffer, "%d", DdeGetLastError(instance));
67 MessageBox(0, buffer, "DDE Error", MB_OK);*/
68 }
69
70 // disconnect the conversation
71 DdeDisconnect(conversation);
72 }
73 else
74 { MessageBox(0, "DDE Connect failed", "GSInstall", MB_OK);
75 }
76
77 // free DDE string
78 DdeFreeStringHandle(instance, serviceName);
79 return reply;
80}
81
82gsProgramManager::gsProgramManager()
83{ this->platform = new gsPlatform();
84 this->connected = false;
85}
86
87bool gsProgramManager::connect()
88{ HRESULT response;
89
90 if (this->platform->isExplorerShell())
91 { // Initialise the shell connection
92 response = CoInitialize(NULL);
93 if (response < 0)
94 { return false;
95 }
96 }
97 else
98 { FARPROC procPtr;
99
100 procPtr = MakeProcInstance((FARPROC) DdeCallBack, app_instance);
101
102 instance = 0L;
103 if (DdeInitialize(&instance, (PFNCALLBACK) procPtr, APPCMD_CLIENTONLY, 0L) != DMLERR_NO_ERROR)
104 { MessageBox(0, "DDE failed to initialise", "GSInstall", MB_OK);
105 return false;
106 }
107 }
108 this->connected = true;
109 return true;
110}
111
112bool gsProgramManager::disconnect()
113{ if (this->connected)
114 { if (this->platform->isExplorerShell())
115 { CoUninitialize();
116 }
117 else
118 { DdeUninitialize(instance);
119 }
120 }
121 this->connected = false;
122 return true;
123}
124
125bool gsProgramManager::addProgramGroup(const char *groupName)
126{ //CreateGroup(groupName);
127 char buffer[256];
128
129 if (this->platform->isExplorerShell())
130 { // add using shell controls
131 LPITEMIDLIST pidl;
132
133 if (SHGetSpecialFolderLocation(0, CSIDL_PROGRAMS, &pidl) == NOERROR)
134 { SHGetPathFromIDList(pidl, buffer);
135
136 // Create the folder as required
137 FilePath *path = new FilePath(buffer, groupName);
138 if (!CreateDirectory((char *) path->cString(), NULL))
139 { // it probably existed already - if so skip it!
140 DWORD reason = GetLastError();
141 if (reason != ERROR_ALREADY_EXISTS)
142 { return false;
143 }
144 }
145 }
146 }
147 else
148 { // add using program manager DDE
149 sprintf(buffer, "[CreateGroup (%s)]", groupName);
150 if (!DDEShellCommand(this->instance, buffer))
151 { // flag error by returning false
152 return false;
153 }
154 }
155 return true;
156}
157
158bool gsProgramManager::addIcon( const char *groupName, // group of the icon
159 const char *iconName, // name of the icon
160 const char *iconDestination, // destination file of the icon
161 const char *description) // the textual description
162 // of the icon (not usually displayed)
163{ bool reply = false;
164 char buffer[MAX_PATH];
165
166 if (this->platform->isExplorerShell())
167 { // create item using the shell
168 LPITEMIDLIST pidl;
169 HRESULT hres;
170 IShellLink* psl;
171 FilePath * fullPath;
172
173 if (SHGetSpecialFolderLocation(0, CSIDL_PROGRAMS, &pidl) != NOERROR)
174 { return false;
175 }
176
177 SHGetPathFromIDList(pidl, buffer);
178 fullPath = new FilePath(4, buffer, groupName, iconName, "!.lnk");
179
180 // Get a pointer to the IShellLink interface.
181 hres = CoCreateInstance(CLSID_ShellLink, NULL,
182 CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &psl);
183 if (SUCCEEDED(hres))
184 { IPersistFile* ppf;
185
186 // Set the path to the shortcut target, and add the
187 // description.
188 psl->SetPath(iconDestination);
189
190 psl->SetDescription(description);
191
192 // Query IShellLink for the IPersistFile interface for saving the
193 // shortcut in persistent storage.
194 hres = psl->QueryInterface(IID_IPersistFile, (void **) &ppf);
195
196 if (SUCCEEDED(hres))
197 { WCHAR wsz[MAX_PATH];
198
199 // Ensure that the string is ANSI.
200 MultiByteToWideChar(CP_ACP, 0, fullPath->cString(), -1, wsz, MAX_PATH);
201
202 // store the link in the "persistent" file
203 reply = ppf->Save(wsz, TRUE);
204
205 // release the persistent file handle
206 ppf->Release();
207 }
208 psl->Release();
209 }
210 }
211 else
212 { // Back to the dark ages with win 3.1!
213
214 // ensure that the requisite group is active; the add icon command will
215 // use the active group.
216 sprintf(buffer, "[ShowGroup(%s,5)]", groupName);
217 if (!DDEShellCommand(this->instance, buffer))
218 { // TODO: articulate/determine possible errors; expand error handling
219 return false;
220 }
221
222 // and now add the item itself to the active (given) group
223 sprintf(buffer, "[AddItem(%s,%s)]", iconDestination, iconName);
224 if (!DDEShellCommand(this->instance, buffer))
225 { // TODO: again work out what the problems could be
226 return false;
227 }
228 reply = true;
229 }
230 return reply;
231}
232
233bool gsProgramManager::removeProgramGroup(const char *groupName)
234{ //CreateGroup(groupName);
235 char buffer[256];
236
237 if (this->platform->isExplorerShell())
238 { // add using shell controls
239 LPITEMIDLIST pidl;
240
241 if (SHGetSpecialFolderLocation(0, CSIDL_PROGRAMS, &pidl) == NOERROR)
242 { SHGetPathFromIDList(pidl, buffer);
243
244 // Create the folder as required
245 FilePath *path = new FilePath(buffer, groupName);
246 if (!RemoveDirectory((char *) path->cString()))
247 { // TODO: find cause of failure to remove
248 DWORD reason = GetLastError();
249 if (reason != 0)
250 { return false;
251 }
252 }
253 }
254 }
255 else
256 { // add using program manager DDE
257 sprintf(buffer, "[DeleteGroup (%s)]", groupName);
258 if (!DDEShellCommand(this->instance, buffer))
259 { // flag error by returning false
260 return false;
261 }
262 }
263 return true;
264}
265
266bool gsProgramManager::removeIcon(const char *groupName, // group of the icon
267 const char *iconName) // name of the icon
268{ bool reply = false;
269 char buffer[MAX_PATH];
270
271 if (this->platform->isExplorerShell())
272 { // create item using the shell
273 LPITEMIDLIST pidl;
274 HRESULT hres;
275 IShellLink* psl;
276 FilePath * fullPath;
277
278 if (SHGetSpecialFolderLocation(0, CSIDL_PROGRAMS, &pidl) != NOERROR)
279 { return false;
280 }
281
282 SHGetPathFromIDList(pidl, buffer);
283 fullPath = new FilePath(4, buffer, groupName, iconName, "!.lnk");
284
285 // TODO: delete file
286 }
287 else
288 { // Back to the dark ages with win 3.1!
289
290 // ensure that the requisite group is active; the add icon command will
291 // use the active group.
292 sprintf(buffer, "[ShowGroup(%s,5)]", groupName);
293 if (!DDEShellCommand(this->instance, buffer))
294 { // TODO: articulate/determine possible errors; expand error handling
295 return false;
296 }
297
298 // and now add the item itself to the active (given) group
299 sprintf(buffer, "[DeleteItem(%s)]", iconName);
300 if (!DDEShellCommand(this->instance, buffer))
301 { // TODO: again work out what the problems could be
302 return false;
303 }
304 }
305 return reply;
306}
307
308
Note: See TracBrowser for help on using the repository browser.