// Classic Shell (c) 2009-2017, Ivo Beltchev // Open-Shell (c) 2017-2018, The Open-Shell Team // Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author #include #include #include #include #include "StringUtils.h" // Find and activate the Settings window static BOOL CALLBACK FindSettingsEnum( HWND hwnd, LPARAM lParam ) { wchar_t className[256]; if (!GetClassName(hwnd,className,_countof(className)) || _wcsicmp(className,L"#32770")!=0) return TRUE; DWORD process=0; GetWindowThreadProcessId(hwnd,&process); HANDLE hProcess=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,process); bool bFound=false; if (hProcess!=INVALID_HANDLE_VALUE) { wchar_t path[_MAX_PATH]; if (GetModuleFileNameEx(hProcess,NULL,path,_countof(path))) { if (_wcsicmp(PathFindFileName(path),L"ClassicExplorerSettings.exe")==0) { SetForegroundWindow(hwnd); bFound=true; } } CloseHandle(hProcess); } return !bFound; } HMODULE LoadClassicExplorerDll( void ) { wchar_t path[_MAX_PATH]; GetModuleFileName(NULL,path,_countof(path)); *PathFindFileName(path)=0; PathAppend(path,L"ClassicExplorer32.dll"); return LoadLibrary(path); } // A simple program that loads ClassicExplorer32.dll and calls the ShowExplorerSettings function // Why not use rundll32 instead? Because it doesn't include the correct manifest for comctl32.dll int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrCmdLine, int nCmdShow ) { INITCOMMONCONTROLSEX init={sizeof(init),ICC_STANDARD_CLASSES}; InitCommonControlsEx(&init); { const wchar_t *pXml=wcsstr(lpstrCmdLine,L"-xml "); if (pXml) { wchar_t xml[_MAX_PATH]; GetToken(pXml+5,xml,_countof(xml),L" "); HMODULE dll=LoadClassicExplorerDll(); if (!dll) return 1; typedef bool (*tImportSettingsXml)( const wchar_t *fname ); tImportSettingsXml DllImportSettingsXml=(tImportSettingsXml)GetProcAddress(dll,"DllImportSettingsXml"); if (!DllImportSettingsXml) return 1; CoInitialize(NULL); bool res=DllImportSettingsXml(xml); CoUninitialize(); return res?0:1; } } { const wchar_t *pBackup=wcsstr(lpstrCmdLine,L"-backup "); if (pBackup) { wchar_t xml[_MAX_PATH]; GetToken(pBackup+8,xml,_countof(xml),L" "); HMODULE dll=LoadClassicExplorerDll(); if (!dll) return 1; typedef bool (*tExportSettingsXml)( const wchar_t *fname ); tExportSettingsXml DllExportSettingsXml=(tExportSettingsXml)GetProcAddress(dll,"DllExportSettingsXml"); if (!DllExportSettingsXml) return 1; CoInitialize(NULL); bool res=DllExportSettingsXml(xml); CoUninitialize(); return res?0:1; } } #ifndef _WIN64 const wchar_t *pSaveAdmx=wcsstr(lpstrCmdLine,L"-saveadmx "); if (pSaveAdmx) { wchar_t language[100]; GetToken(pSaveAdmx+10,language,_countof(language),L" "); HMODULE dll=LoadClassicExplorerDll(); if (!dll) return 1; typedef bool (*tSaveAdmx)( const char *admxFile, const char *admlFile, const char *docFile, const wchar_t *language ); tSaveAdmx SaveAdmx=(tSaveAdmx)GetProcAddress(dll,"DllSaveAdmx"); if (!SaveAdmx || !SaveAdmx("ClassicExplorer.admx","ClassicExplorer.adml","ClassicExplorerADMX.txt",language)) return 1; return 0; } #endif // prevent multiple instances from running on the same desktop // the assumption is that multiple desktops for the same user will have different name (but may repeat across users) wchar_t userName[256]; DWORD len=_countof(userName); GetUserName(userName,&len); len=0; HANDLE desktop=GetThreadDesktop(GetCurrentThreadId()); GetUserObjectInformation(desktop,UOI_NAME,NULL,0,&len); wchar_t *deskName=(wchar_t*)malloc(len); GetUserObjectInformation(desktop,UOI_NAME,deskName,len,&len); wchar_t mutexName[1024]; Sprintf(mutexName,_countof(mutexName),L"ClassicExplorerSettings.Mutex.%s.%s",userName,deskName); free(deskName); HANDLE hMutex=CreateMutex(NULL,TRUE,mutexName); if (GetLastError()==ERROR_ALREADY_EXISTS || GetLastError()==ERROR_ACCESS_DENIED) { EnumWindows(FindSettingsEnum,0); return 0; } HMODULE dll=LoadClassicExplorerDll(); if (!dll) return 1; FARPROC proc=GetProcAddress(dll,"ShowExplorerSettings"); if (!proc) return 2; proc(); return 0; }