3535#define SETUP_DLL_NAME "http_server32.dll"
3636#endif
3737
38- //TODO: remove 1.5a when in beta.
39- #define SETUP_EVERYTHING_PROGRAM_NAME "Everything 1.5a "
40- #define SETUP_EVERYTHING_TASKBAR_NOTIFICATION "EVERYTHING_TASKBAR_NOTIFICATION_(1.5a)"
38+ #define SETUP_EVERYTHING_PROGRAM_NAME "Everything"
39+ #define SETUP_EVERYTHING_TASKBAR_NOTIFICATION "EVERYTHING_TASKBAR_NOTIFICATION "
40+ #define SETUP_EVERYTHING_TASKBAR_NOTIFICATION_1_5_ALPHA "EVERYTHING_TASKBAR_NOTIFICATION_(1.5a)"
4141
4242#define SETUP_MAX_STRING MAX_PATH
4343#define SETUP_MAX_COMMAND_LINE 32768
6565#include <windows.h>
6666#include <shellapi.h>
6767#include <Psapi.h>
68+ #include <shlobj.h> // SHBrowseForFolderW
69+ #include <shobjidl.h> // IShellItem
6870#include "../res/resource.h"
6971#include "../../src/version.h"
7072
73+ typedef struct setup_IFileOpenDialogVtbl_s
74+ {
75+ HRESULT (STDMETHODCALLTYPE * QueryInterface )(struct setup_IFileOpenDialog_s * This ,REFIID riid ,void * * ppvObject );
76+ ULONG (STDMETHODCALLTYPE * AddRef )(struct setup_IFileOpenDialog_s * This );
77+ ULONG (STDMETHODCALLTYPE * Release )(struct setup_IFileOpenDialog_s * This );
78+ HRESULT (STDMETHODCALLTYPE * Show )(struct setup_IFileOpenDialog_s * This ,HWND hwndOwner );
79+ HRESULT (STDMETHODCALLTYPE * SetFileTypes )(struct setup_IFileOpenDialog_s * This ,UINT cFileTypes ,const struct setup_COMDLG_FILTERSPEC_s * rgFilterSpec );
80+ HRESULT (STDMETHODCALLTYPE * SetFileTypeIndex )(struct setup_IFileOpenDialog_s * This ,UINT iFileType );
81+ HRESULT (STDMETHODCALLTYPE * GetFileTypeIndex )(struct setup_IFileOpenDialog_s * This ,UINT * piFileType );
82+ HRESULT (STDMETHODCALLTYPE * Advise )(struct setup_IFileOpenDialog_s * This ,struct _os_IFileDialogEvents_s * pfde ,DWORD * pdwCookie );
83+ HRESULT (STDMETHODCALLTYPE * Unadvise )(struct setup_IFileOpenDialog_s * This ,DWORD dwCookie );
84+ HRESULT (STDMETHODCALLTYPE * SetOptions )(struct setup_IFileOpenDialog_s * This ,int fos );
85+ HRESULT (STDMETHODCALLTYPE * GetOptions )(struct setup_IFileOpenDialog_s * This ,int * pfos );
86+ HRESULT (STDMETHODCALLTYPE * SetDefaultFolder )(struct setup_IFileOpenDialog_s * This ,IShellItem * psi );
87+ HRESULT (STDMETHODCALLTYPE * SetFolder )(struct setup_IFileOpenDialog_s * This ,IShellItem * psi );
88+ HRESULT (STDMETHODCALLTYPE * GetFolder )(struct setup_IFileOpenDialog_s * This ,IShellItem * * ppsi );
89+ HRESULT (STDMETHODCALLTYPE * GetCurrentSelection )(struct setup_IFileOpenDialog_s * This ,IShellItem * * ppsi );
90+ HRESULT (STDMETHODCALLTYPE * SetFileName )(struct setup_IFileOpenDialog_s * This ,LPCWSTR pszName );
91+ HRESULT (STDMETHODCALLTYPE * GetFileName )(struct setup_IFileOpenDialog_s * This ,LPWSTR * pszName );
92+ HRESULT (STDMETHODCALLTYPE * SetTitle )(struct setup_IFileOpenDialog_s * This ,LPCWSTR pszTitle );
93+ HRESULT (STDMETHODCALLTYPE * SetOkButtonLabel )(struct setup_IFileOpenDialog_s * This ,LPCWSTR pszText );
94+ HRESULT (STDMETHODCALLTYPE * SetFileNameLabel )(struct setup_IFileOpenDialog_s * This ,LPCWSTR pszLabel );
95+ HRESULT (STDMETHODCALLTYPE * GetResult )(struct setup_IFileOpenDialog_s * This ,IShellItem * * ppsi );
96+ HRESULT (STDMETHODCALLTYPE * AddPlace )(struct setup_IFileOpenDialog_s * This ,IShellItem * psi ,int fdap );
97+ HRESULT (STDMETHODCALLTYPE * SetDefaultExtension )(struct setup_IFileOpenDialog_s * This ,LPCWSTR pszDefaultExtension );
98+ HRESULT (STDMETHODCALLTYPE * Close )(struct setup_IFileOpenDialog_s * This ,HRESULT hr );
99+ HRESULT (STDMETHODCALLTYPE * SetClientGuid )(struct setup_IFileOpenDialog_s * This ,REFGUID guid );
100+ HRESULT (STDMETHODCALLTYPE * ClearClientData )(struct setup_IFileOpenDialog_s * This );
101+ HRESULT (STDMETHODCALLTYPE * SetFilter )(struct setup_IFileOpenDialog_s * This ,void * pFilter );
102+ HRESULT (STDMETHODCALLTYPE * GetResults )(struct setup_IFileOpenDialog_s * This ,void * * ppenum );
103+ HRESULT (STDMETHODCALLTYPE * GetSelectedItems )(struct setup_IFileOpenDialog_s * This ,void * * ppsai );
104+
105+ }setup_IFileOpenDialogVtbl_t ;
106+
107+ typedef struct setup_IFileOpenDialog_s
108+ {
109+ struct setup_IFileOpenDialogVtbl_s * lpVtbl ;
110+
111+ }setup_IFileOpenDialog_t ;
112+
113+ static const IID setup_CLSID_FileOpenDialog = {0xdc1c5a9c ,0xe88a ,0x4dde ,{0xa5 ,0xa1 ,0x60 ,0xf8 ,0x2a ,0x20 ,0xae ,0xf7 }};
114+ static const IID setup_IID_IFileOpenDialog = {0xd57c7288 ,0xd4ad ,0x4768 ,{0xbe ,0x02 ,0x9d ,0x96 ,0x95 ,0x32 ,0xd9 ,0x60 }};
115+
116+ #if defined(_WIN64 )
117+ #else
71118// load unicode for windows 95/98
72119HMODULE LoadUnicowsProc (void );
73120
@@ -90,6 +137,7 @@ HMODULE LoadUnicowsProc(void)
90137
91138 return NULL ;
92139}
140+ #endif
93141
94142void setup_main (void );
95143int setup_get_reg_string (HKEY root_hkey ,const char * key ,const char * value ,wchar_t * buf );
@@ -99,6 +147,9 @@ void setup_fatal(DWORD error_code,const char *msg);
99147void setup_cat_astring (wchar_t * wbuf ,DWORD size_in_wchars ,const char * as );
100148void setup_cat_wstring (wchar_t * wbuf ,DWORD size_in_wchars ,const wchar_t * ws );
101149void setup_cat_number (wchar_t * wbuf ,DWORD size_in_wchars ,DWORD number );
150+ static int setup_browse_for_folder (wchar_t * everything_exe_filename_wbuf );
151+ static void setup_copy_string (wchar_t * dst ,const wchar_t * src );
152+ static int setup_get_running_exe_filename (const char * window_class ,wchar_t * everything_exe_filename_wbuf );
102153
103154void setup_atow (const char * as ,wchar_t * ws )
104155{
@@ -167,6 +218,165 @@ int setup_get_reg_string(HKEY root_hkey,const char *key,const char *value,wchar_
167218 return ret ;
168219}
169220
221+ static void setup_copy_string (wchar_t * dst ,const wchar_t * src )
222+ {
223+ wchar_t * d ;
224+ const wchar_t * p ;
225+ SIZE_T run ;
226+
227+ d = dst ;
228+ p = src ;
229+ run = SETUP_MAX_STRING - 1 ;
230+
231+ while (* p )
232+ {
233+ if (!run )
234+ {
235+ break ;
236+ }
237+
238+ * d ++ = * p ;
239+ run -- ;
240+
241+ p ++ ;
242+ }
243+
244+ * d = 0 ;
245+ }
246+
247+ static int setup_browse_for_folder (wchar_t * everything_exe_filename_wbuf )
248+ {
249+ setup_IFileOpenDialog_t * file_open_dialog ;
250+
251+ // IFileOpenDialog, when closed, will focus the first dlg item on the previously active window.
252+ // it will then focus the correct, last focused item.
253+ // this breaks the previous edit selection
254+ if (SUCCEEDED (CoCreateInstance (& setup_CLSID_FileOpenDialog ,NULL ,CLSCTX_INPROC_SERVER ,& setup_IID_IFileOpenDialog ,& file_open_dialog )))
255+ {
256+ int ret ;
257+ IShellItem * shell_item ;
258+ HRESULT hres ;
259+
260+ ret = 0 ;
261+
262+ // setting advise for events does not allow us to select the control panel.
263+ // we only get FolderChanging events with no SetFolderSelection event
264+
265+ // FOS_NOCHANGEDIR = 0x00000008,
266+ // FOS_PICKFOLDERS = 0x00000020,
267+ // FOS_ALLNONSTORAGEITEMS = 0x80
268+ // FOS_FORCESHOWHIDDEN = 0x10000000,
269+
270+ file_open_dialog -> lpVtbl -> SetOptions (file_open_dialog ,0x20 | 0x08 | 0x80 | 0x10000000 );
271+
272+ file_open_dialog -> lpVtbl -> SetTitle (file_open_dialog ,L"Select Everything.exe Location" );
273+
274+ hres = file_open_dialog -> lpVtbl -> Show (file_open_dialog ,NULL );
275+ if (SUCCEEDED (hres ))
276+ {
277+ if (SUCCEEDED (file_open_dialog -> lpVtbl -> GetResult (file_open_dialog ,& shell_item )))
278+ {
279+ LPOLESTR filename ;
280+
281+ if (SUCCEEDED (shell_item -> lpVtbl -> GetDisplayName (shell_item ,SIGDN_DESKTOPABSOLUTEPARSING ,& filename )))
282+ {
283+ setup_copy_string (everything_exe_filename_wbuf ,filename );
284+
285+ ret = 1 ;
286+
287+ CoTaskMemFree (filename );
288+ }
289+
290+ shell_item -> lpVtbl -> Release (shell_item );
291+ }
292+ }
293+ else
294+ {
295+ if (hres == 0x800704c7 )
296+ {
297+ // The operation was canceled by the user.
298+ ExitProcess (1 );
299+ }
300+ }
301+
302+ file_open_dialog -> lpVtbl -> Release (file_open_dialog );
303+
304+ return ret ;
305+ }
306+
307+ {
308+ BROWSEINFOW bi ;
309+ ITEMIDLIST * iil ;
310+ int ret ;
311+
312+ ret = 0 ;
313+
314+
315+ // BIF_USENEWUI wont bring the initial selection into view.
316+ // BIF_NOTRANSLATETARGETS we dont want symbolic links targets, we want the actual path.
317+ // BIF_NEWDIALOGSTYLE allows computer to be selected, and keeps the OK button focused, which keeps the dialog focused. Otherwise keyboard focus is lost
318+ ZeroMemory (& bi ,sizeof (BROWSEINFOW ));
319+ bi .lpszTitle = L"Select Everything.exe Location" ;
320+ bi .pszDisplayName = L"" ;
321+ bi .ulFlags = BIF_USENEWUI | BIF_NOTRANSLATETARGETS | BIF_NEWDIALOGSTYLE ;
322+ bi .hwndOwner = NULL ;
323+
324+ iil = (ITEMIDLIST * )SHBrowseForFolderW (& bi );
325+
326+ if (iil )
327+ {
328+ if (SHGetPathFromIDListW (iil ,everything_exe_filename_wbuf ))
329+ {
330+ ret = 1 ;
331+ }
332+
333+ ILFree (iil );
334+ }
335+ else
336+ {
337+ // cancelled.
338+ ExitProcess (1 );
339+ }
340+
341+ return ret ;
342+ }
343+ }
344+
345+ static int setup_get_running_exe_filename (const char * window_class ,wchar_t * everything_exe_filename_wbuf )
346+ {
347+ int ret ;
348+ HWND everything_hwnd ;
349+ wchar_t class_name_wbuf [SETUP_MAX_STRING ];
350+
351+ ret = 0 ;
352+
353+ setup_atow (window_class ,class_name_wbuf );
354+
355+ everything_hwnd = FindWindowW (class_name_wbuf ,NULL );
356+ if (everything_hwnd )
357+ {
358+ DWORD process_id ;
359+
360+ if (GetWindowThreadProcessId (everything_hwnd ,& process_id ))
361+ {
362+ HANDLE process_handle ;
363+
364+ process_handle = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ ,FALSE,process_id );
365+ if (process_handle )
366+ {
367+ if (GetModuleFileNameExW (process_handle ,NULL ,everything_exe_filename_wbuf ,SETUP_MAX_STRING ))
368+ {
369+ ret = 1 ;
370+ }
371+
372+ CloseHandle (process_handle );
373+ }
374+ }
375+ }
376+
377+ return ret ;
378+ }
379+
170380int setup_get_everything_exe_filename (wchar_t * everything_exe_filename_wbuf )
171381{
172382 int ret ;
@@ -185,34 +395,29 @@ int setup_get_everything_exe_filename(wchar_t *everything_exe_filename_wbuf)
185395 // portable version running?
186396 if (!ret )
187397 {
188- HWND everything_hwnd ;
189- wchar_t class_name_wbuf [SETUP_MAX_STRING ];
190-
191- setup_atow (SETUP_EVERYTHING_TASKBAR_NOTIFICATION ,class_name_wbuf );
192-
193- everything_hwnd = FindWindowW (class_name_wbuf ,NULL );
194- if (everything_hwnd )
398+ if (setup_get_running_exe_filename (SETUP_EVERYTHING_TASKBAR_NOTIFICATION ,everything_exe_filename_wbuf ))
195399 {
196- DWORD process_id ;
197-
198- if (GetWindowThreadProcessId (everything_hwnd ,& process_id ))
199- {
200- HANDLE process_handle ;
201-
202- process_handle = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ ,FALSE,process_id );
203- if (process_handle )
204- {
205- if (GetModuleFileNameExW (process_handle ,NULL ,everything_exe_filename_wbuf ,SETUP_MAX_STRING ))
206- {
207- ret = 1 ;
208- }
209-
210- CloseHandle (process_handle );
211- }
212- }
400+ ret = 1 ;
213401 }
214402 }
215403
404+ // 1.5a version running?
405+ if (!ret )
406+ {
407+ if (setup_get_running_exe_filename (SETUP_EVERYTHING_TASKBAR_NOTIFICATION_1_5_ALPHA ,everything_exe_filename_wbuf ))
408+ {
409+ ret = 1 ;
410+ }
411+ }
412+
413+ if (!ret )
414+ {
415+ if (setup_browse_for_folder (everything_exe_filename_wbuf ))
416+ {
417+ ret = 1 ;
418+ }
419+ }
420+
216421 return ret ;
217422}
218423
@@ -377,6 +582,9 @@ void * __cdecl memset(void *p, int v, size_t s) {
377582void setup_main (void )
378583{
379584 wchar_t everything_exe_filename_wbuf [SETUP_MAX_STRING ];
585+
586+ // required for SHBrowseForFolder
587+ OleInitialize (0 );
380588
381589 // get everything install folder
382590 if (setup_get_everything_exe_filename (everything_exe_filename_wbuf ))
0 commit comments