1 /*
2  * Copyright 2005 Martin Fuchs
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 
19 
20  //
21  // Explorer clone
22  //
23  // shellservices.cpp
24  //
25  // Martin Fuchs, 28.03.2005
26  //
27 
28 
29 #include <precomp.h>
30 
31 #include "shellservices.h"
32 
33 
34 int SSOThread::Run()
35 {
36 	ComInit usingCOM(COINIT_APARTMENTTHREADED|COINIT_DISABLE_OLE1DDE|COINIT_SPEED_OVER_MEMORY);
37 
38 	HKEY hkey;
39 	CLSID clsid;
40 	WCHAR name[MAX_PATH], value[MAX_PATH];
41 
42 	typedef vector<SIfacePtr<IOleCommandTarget>*> SSOVector;
43 	SSOVector sso_ptrs;
44 
45 	if (!RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad"), &hkey)) {
46 		for(int idx=0; ; ++idx) {
47 			DWORD name_len = MAX_PATH;
48 			DWORD value_len = sizeof(value);
49 
50 			if (RegEnumValueW(hkey, idx, name, &name_len, 0, NULL, (LPBYTE)&value, &value_len))
51 				break;
52 
53 			if (!_alive)
54 				break;
55 
56 			SIfacePtr<IOleCommandTarget>* sso_ptr = new SIfacePtr<IOleCommandTarget>;
57 
58 			if (CLSIDFromString(value, &clsid) == NOERROR) {
59 				if (SUCCEEDED(sso_ptr->CreateInstance(clsid, IID_IOleCommandTarget))) {
60 					if (SUCCEEDED((*sso_ptr)->Exec(&CGID_ShellServiceObject, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL)))
61 						sso_ptrs.push_back(sso_ptr);
62 				}
63 			}
64 		}
65 
66 		RegCloseKey(hkey);
67 	}
68 
69 	if (!sso_ptrs.empty()) {
70 		MSG msg;
71 
72 		while(_alive) {
73 			if (MsgWaitForMultipleObjects(1, &_evtFinish, FALSE, INFINITE, QS_ALLINPUT) == WAIT_OBJECT_0+0)
74 				break;	// _evtFinish has been set.
75 
76 			while(_alive) {
77 				if (!PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
78 					break;
79 
80 				if (msg.message == WM_QUIT)
81 					break;
82 
83 				TranslateMessage(&msg);
84 				DispatchMessage(&msg);
85 			}
86 		}
87 
88 		 // shutdown all running Shell Service Objects
89 		for(SSOVector::iterator it=sso_ptrs.begin(); it!=sso_ptrs.end(); ++it) {
90 			SIfacePtr<IOleCommandTarget>* sso_ptr = *it;
91 			(*sso_ptr)->Exec(&CGID_ShellServiceObject, OLECMDID_SAVE, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
92 			delete sso_ptr;
93 		}
94 	}
95 
96 	return 0;
97 }
98