/*
Copyright (C) 2019 Red Hat, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "shell.h"
#include
#include
#include
static bool filter_url(LPWSTR str)
{
// check and strip "file:///?"
WCHAR *src = str;
if (wcsncmp(str, L"file:///", 8) == 0) {
src += 8;
} else if (wcsncmp(str, L"file://", 7) == 0) {
src += 7;
} else {
return false;
}
WCHAR *dst = str;
while (*src) {
WCHAR c = *src++, save_char;
switch (c) {
// convert Unix to DOS path separators
case L'/':
c = L'\\';
break;
// hexadecimal encoding
case L'%':
if (!iswxdigit(src[0]) || !iswxdigit(src[1])) {
return false;
}
save_char = src[2];
src[2] = 0;
c = (WCHAR) wcstol(src, NULL, 16);
src[2] = save_char;
src += 2;
break;
// NOTE: do not convert + to space, paths like "C++"
// remain the same
default:
break;
}
*dst++ = c;
}
*dst = 0;
return true;
}
bool open_shell_directory(LPCWSTR directory)
{
HRESULT result;
IShellWindows *shellWindows = nullptr;
result = CoCreateInstance(
CLSID_ShellWindows,
NULL,
CLSCTX_ALL,
IID_IShellWindows,
(void**)&shellWindows
);
if (FAILED(result)) {
return false;
}
long windowsCount = 0;
result = shellWindows->get_Count(&windowsCount);
if (FAILED(result)) {
shellWindows->Release();
return false;
}
bool found = false;
for (long i = 0; i < windowsCount; i++) {
IDispatch *disp = nullptr;
_variant_t va(i, VT_I4);
result = shellWindows->Item(va, &disp);
if (FAILED(result)) {
continue;
}
IWebBrowser2 *pBrowser2 = nullptr;
result = disp->QueryInterface(IID_IWebBrowserApp, (void**)&pBrowser2);
if (SUCCEEDED(result)) {
BSTR url;
pBrowser2->get_LocationURL(&url);
if (filter_url(url) && lstrcmpiW(url, directory) == 0) {
found = true;
}
SysFreeString(url);
pBrowser2->Release();
}
disp->Release();
}
shellWindows->Release();
if (!found) {
ShellExecuteW(NULL, L"open", directory, NULL, NULL, SW_SHOWNORMAL);
}
return true;
}