#include "FileTypeRegistrar.h" #include #include #include #include #define _STD_USING //#include "../nu/cast64.h" #include #ifdef ELEVATOR_SCOPE void Lock(); void UnLock(); #endif #if defined(_SYSINFOAPI_H_) && defined(NOT_BUILD_WINDOWS_DEPRECATE) && (_WIN32_WINNT >= 0x0501) #include #endif FileTypeRegistrar::FileTypeRegistrar() { refCount = 0; } HRESULT FileTypeRegistrar::QueryInterface(REFIID riid, LPVOID FAR *ppvObj) { if (!ppvObj) return E_POINTER; else if (IsEqualIID(riid, IID_IUnknown)) *ppvObj = static_cast(this); else if (IsEqualIID(riid, __uuidof(IFileTypeRegistrar))) *ppvObj = static_cast(this); else { *ppvObj = NULL; return E_NOINTERFACE; } AddRef(); return S_OK; } ULONG FileTypeRegistrar::AddRef(void) { #ifdef ELEVATOR_SCOPE Lock(); #endif return ++refCount; } ULONG FileTypeRegistrar::Release(void) { ULONG retCount=--refCount; #ifdef ELEVATOR_SCOPE UnLock(); #endif return retCount; } static LONG SetValue(HKEY hkey, const wchar_t *data) { return RegSetValueExW(hkey, NULL,0,REG_SZ,(const BYTE *)data, (DWORD)(sizeof(wchar_t)*(wcslen(data)+1))); } static LONG SetValue(HKEY hkey, const wchar_t *value, const wchar_t *data) { return RegSetValueExW(hkey, value,0,REG_SZ,(const BYTE *)data, (DWORD)(sizeof(wchar_t)*(wcslen(data)+1))); } HRESULT FileTypeRegistrar::RegisterMIMEType(const wchar_t *mimeType, const wchar_t *programName, const wchar_t *extension, int netscapeOnly) { HKEY mp3Key = NULL; if (!netscapeOnly) { wchar_t s[MAX_PATH] = {0}; if (RegCreateKeyW(HKEY_CLASSES_ROOT, extension, &mp3Key) == ERROR_SUCCESS) { SetValue(mp3Key, L"Content Type", mimeType); RegCloseKey(mp3Key); } StringCchPrintfW(s, MAX_PATH, L"MIME\\Database\\Content Type\\%s", mimeType); if (RegCreateKeyW(HKEY_CLASSES_ROOT, s, &mp3Key) == ERROR_SUCCESS) { RegDeleteValueW(mp3Key, L"CLSID"); SetValue(mp3Key, L"Extension", extension); RegCloseKey(mp3Key); } } if (RegOpenKeyW(HKEY_CURRENT_USER, L"Software\\Netscape\\Netscape Navigator\\Viewers", &mp3Key) == ERROR_SUCCESS) { SetValue(mp3Key, mimeType, programName); for (int x = 0; x < 999; x ++) { wchar_t st[100] = {0}; DWORD vt; DWORD s = 128; wchar_t b[128] = {0}; StringCchPrintfW(st, 100, L"TYPE%d", x); if (RegQueryValueExW(mp3Key, st, 0, &vt, (LPBYTE)b, &s) == ERROR_SUCCESS) { if (!wcscmp(b, mimeType)) break; } else { SetValue(mp3Key, st, mimeType); break; } } RegCloseKey(mp3Key); } return S_OK; } HRESULT FileTypeRegistrar::RegisterCDPlayer(const wchar_t *programName) { wchar_t buf2[MAX_PATH] = {0}; HKEY mp3Key = NULL; StringCchPrintfW(buf2, MAX_PATH, L"\"%s\" %%1", programName); if (RegOpenKeyW(HKEY_CLASSES_ROOT, L"AudioCD\\shell\\play\\command", &mp3Key) == ERROR_SUCCESS) { wchar_t b[MAX_PATH] = {0}; DWORD s = sizeof(b)/sizeof(*b); if (RegQueryValueEx(mp3Key, NULL, 0, NULL, (LPBYTE)b, &s) == ERROR_SUCCESS) { if (_wcsicmp(b, buf2)) { wchar_t buf3[MAX_PATH] = {0}; DWORD st = sizeof(buf3)/sizeof(*buf3); if (RegQueryValueExW(mp3Key, L"Winamp_Back", 0, NULL, (LPBYTE)buf3, &st) != ERROR_SUCCESS || _wcsicmp(buf3, b)) { SetValue(mp3Key, L"Winamp_Back", b); } SetValue(mp3Key, buf2); } } else SetValue(mp3Key, buf2); RegCloseKey(mp3Key); } return S_OK; } HRESULT FileTypeRegistrar::UnregisterCDPlayer(const wchar_t *programName) { wchar_t buf2[MAX_PATH] = {0}; HKEY mp3Key = NULL; StringCchPrintfW(buf2, MAX_PATH, L"\"%s\" %%1", programName); if (RegOpenKeyW(HKEY_CLASSES_ROOT, L"AudioCD\\shell\\play\\command", &mp3Key) == ERROR_SUCCESS) { wchar_t b[MAX_PATH] = {0}; DWORD s = sizeof(b)/sizeof(*b); if (RegQueryValueEx(mp3Key, NULL, 0, NULL, (LPBYTE)b, &s) == ERROR_SUCCESS) { if (!wcscmp(b, buf2)) { s = sizeof(b); if (RegQueryValueExW(mp3Key, L"Winamp_Back", 0, NULL, (LPBYTE)b, &s) == ERROR_SUCCESS) { if (!_wcsicmp(b, buf2)) b[0] = 0; if (SetValue(mp3Key, b) == ERROR_SUCCESS) RegDeleteValueW(mp3Key, L"Winamp_Back"); } else { buf2[0] = 0; SetValue(mp3Key, buf2); } } } RegCloseKey(mp3Key); } return S_OK; } static LONG myRegDeleteKeyEx(HKEY thiskey, LPCWSTR lpSubKey) { HKEY key = NULL; int retval = RegOpenKeyW(thiskey, lpSubKey, &key); if (retval == ERROR_SUCCESS) { wchar_t buffer[1024] = {0}; while (RegEnumKeyW(key, 0, buffer, 1024) == ERROR_SUCCESS) if ((retval = myRegDeleteKeyEx(key, buffer)) != ERROR_SUCCESS) break; RegCloseKey(key); retval = RegDeleteKeyW(thiskey, lpSubKey); } return retval; } HRESULT FileTypeRegistrar::RegisterType(const wchar_t *extension, const wchar_t *which_str, const wchar_t *prog_name) { HKEY mp3Key = NULL; LONG regResult = RegCreateKeyW(HKEY_CLASSES_ROOT, extension, &mp3Key); if (regResult == ERROR_SUCCESS) { wchar_t b[128] = {0}; DWORD s = sizeof(b)/sizeof(*b); if (RegQueryValueEx(mp3Key, NULL, 0, NULL, (LPBYTE)b, &s) == ERROR_SUCCESS) { if (wcsncmp(b, which_str, wcslen(b))) { SetValue(mp3Key, L"Winamp_Back", b); SetValue(mp3Key, which_str); } } else SetValue(mp3Key, which_str); if (mp3Key) RegCloseKey(mp3Key); } #if defined(_SYSINFOAPI_H_) && defined(NOT_BUILD_WINDOWS_DEPRECATE) && (_WIN32_WINNT >= 0x0501) if (IsWindowsVersionOrGreater(6, 0, 0)) // Vista #else OSVERSIONINFO version = {0}; version.dwOSVersionInfoSize = sizeof(version); if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO)); if (version.dwMajorVersion >= 6) // Vista #endif { TCHAR szKey[256] = {0}; StringCbPrintfW(szKey, sizeof(szKey), L"Software\\Clients\\Media\\%s\\Capabilities\\FileAssociations", prog_name); if (ERROR_SUCCESS == RegCreateKeyW(HKEY_LOCAL_MACHINE, szKey, &mp3Key)) { SetValue(mp3Key, extension, which_str); // TODO: cache IApplicationAssociationRegistration IApplicationAssociationRegistration* pAAR = NULL; HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC, __uuidof(IApplicationAssociationRegistration), (void**)&pAAR); if (SUCCEEDED(hr) && pAAR) { pAAR->SetAppAsDefault(prog_name, extension, AT_FILEEXTENSION); pAAR->Release(); } RegCloseKey(mp3Key); } } return S_OK; } HRESULT FileTypeRegistrar::UnregisterType(const wchar_t *extension, const wchar_t *which_str, const wchar_t *prog_name, int is_playlist) { HKEY mp3Key = NULL; LONG regResult = RegOpenKeyW(HKEY_CLASSES_ROOT, extension, &mp3Key); if (regResult == ERROR_SUCCESS) { wchar_t b[128] = {0}; DWORD s = sizeof(b)/sizeof(*b); if (RegQueryValueEx(mp3Key, NULL, 0, NULL, (LPBYTE)b, &s) == ERROR_SUCCESS) { size_t len = min(wcslen(b), wcslen(which_str)); if (!wcsncmp(b, which_str, len)) { s = sizeof(b)/sizeof(*b); if (RegQueryValueExW(mp3Key, L"Winamp_Back", 0, NULL, (LPBYTE)b, &s) == ERROR_SUCCESS) { if (SetValue(mp3Key, b) == ERROR_SUCCESS) RegDeleteValueW(mp3Key, L"Winamp_Back"); } else { RegDeleteValue(mp3Key, NULL); RegCloseKey(mp3Key); mp3Key = NULL; myRegDeleteKeyEx(HKEY_CLASSES_ROOT, extension); } } } if (mp3Key) RegCloseKey(mp3Key); if(!is_playlist) { myRegDeleteKeyEx(HKEY_CLASSES_ROOT, which_str); } } // TODO: benski> it'd be nice to have a function to remove any capabilities for which we no longer have a plugin for ... #if defined(_SYSINFOAPI_H_) && defined(NOT_BUILD_WINDOWS_DEPRECATE) && (_WIN32_WINNT >= 0x0501) if (IsWindowsVersionOrGreater(6, 0, 0)) // Vista #else OSVERSIONINFO version = { 0 }; version.dwOSVersionInfoSize = sizeof(version); if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO)); if (version.dwMajorVersion >= 6) // Vista #endif { TCHAR szKey[256] = {0}; StringCbPrintfW(szKey, sizeof(szKey), L"Software\\Clients\\Media\\%s\\Capabilities\\FileAssociations", prog_name); if (ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, szKey, &mp3Key)) { RegDeleteValue(mp3Key, extension); RegCloseKey(mp3Key); } } return S_OK; } HRESULT FileTypeRegistrar::AddDirectoryContext(const wchar_t *commandLine, const wchar_t *which_str, const wchar_t *description) { HKEY mp3Key = NULL; wchar_t regStr[256] = {0}; StringCbPrintfW(regStr, sizeof(regStr), L"SOFTWARE\\Classes\\Directory\\shell\\%s", which_str); if (RegCreateKeyW(HKEY_LOCAL_MACHINE, regStr,&mp3Key) == ERROR_SUCCESS) { SetValue(mp3Key, description); RegCloseKey(mp3Key); } StringCbPrintfW(regStr, sizeof(regStr), L"SOFTWARE\\Classes\\Directory\\shell\\%s\\command", which_str); if (RegCreateKeyW(HKEY_LOCAL_MACHINE,regStr,&mp3Key) == ERROR_SUCCESS) { SetValue(mp3Key, commandLine); RegCloseKey(mp3Key); } return S_OK; } HRESULT FileTypeRegistrar::RemoveDirectoryContext(const wchar_t *which_str) { wchar_t regStr[256] = {0}; StringCbPrintfW(regStr, sizeof(regStr), L"SOFTWARE\\Classes\\Directory\\shell\\%s", which_str); myRegDeleteKeyEx(HKEY_LOCAL_MACHINE, regStr); return S_OK; } HRESULT FileTypeRegistrar::AddAgent(const wchar_t *agentFilename) { HKEY key = NULL; STARTUPINFOW si = {sizeof(si), }; PROCESS_INFORMATION pi = {0, }; if (RegCreateKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", &key) == ERROR_SUCCESS) { SetValue(key, L"WinampAgent", agentFilename); RegCloseKey(key); } CreateProcessW(NULL, (LPWSTR)agentFilename, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return S_OK; } HRESULT FileTypeRegistrar::RemoveAgent() { HKEY key = NULL; // caller will have done this also, but we'll do it again at elevated level just in case that's where winamp agent is running HWND hwnd = FindWindow(L"WinampAgentMain", NULL); if (hwnd) { SendMessageW(hwnd, WM_CLOSE, 0, 0); } if (RegOpenKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", &key) == ERROR_SUCCESS) { RegDeleteValue(key, L"WinampAgent"); RegCloseKey(key); } return S_OK; } static LONG RegMedia_CreateKey(LPCWSTR lpSubKey, HKEY *phkResult, LPCWSTR prog_name) { WCHAR szKey[256] = {0}; HRESULT hr = (lpSubKey && *lpSubKey) ? StringCbPrintfW(szKey, sizeof(szKey), L"Software\\Clients\\Media\\%s\\%s", prog_name, lpSubKey) : StringCbPrintfW(szKey, sizeof(szKey), L"Software\\Clients\\Media\\%s", prog_name); if (S_OK != hr) return ERROR_NOT_ENOUGH_MEMORY; return RegCreateKeyW(HKEY_LOCAL_MACHINE, szKey, phkResult); } HRESULT FileTypeRegistrar::RegisterMediaPlayer(DWORD accessEnabled, const wchar_t *programName, const wchar_t *prog_name, int iconNumber) { HKEY mp3Key = NULL; wchar_t str[MAX_PATH+128] = {0}; if (RegMedia_CreateKey(NULL, &mp3Key, prog_name) == ERROR_SUCCESS) { SetValue(mp3Key, prog_name); RegCloseKey(mp3Key); } if (RegMedia_CreateKey(L"DefaultIcon",&mp3Key, prog_name) == ERROR_SUCCESS) { StringCchPrintfW(str,MAX_PATH+128,L"%s,%d",programName,iconNumber); SetValue(mp3Key, str); RegCloseKey(mp3Key); } if (RegMedia_CreateKey(L"InstallInfo",&mp3Key, prog_name) == ERROR_SUCCESS) { RegSetValueExW(mp3Key, L"IconsVisible", 0, REG_DWORD, (BYTE *)&accessEnabled, sizeof(accessEnabled)); StringCchPrintfW(str,MAX_PATH+128, L"\"%s\" /REG=AVCDL", programName); SetValue(mp3Key,L"ReinstallCommand", str); SetValue(mp3Key,L"ShowIconsCommand", str); StringCchPrintfW(str,MAX_PATH+128,L"\"%s\" /UNREG",programName); SetValue(mp3Key,L"HideIconsCommand", str); RegCloseKey(mp3Key); } if (RegMedia_CreateKey(L"shell",&mp3Key, prog_name) == ERROR_SUCCESS) RegCloseKey(mp3Key); if (RegMedia_CreateKey(L"shell\\open",&mp3Key, prog_name) == ERROR_SUCCESS) RegCloseKey(mp3Key); if (RegMedia_CreateKey(L"shell\\open\\command",&mp3Key, prog_name) == ERROR_SUCCESS) { SetValue(mp3Key, programName); RegCloseKey(mp3Key); } #if defined(_SYSINFOAPI_H_) && defined(NOT_BUILD_WINDOWS_DEPRECATE) && (_WIN32_WINNT >= 0x0501) if (IsWindowsVersionOrGreater(6, 0, 0)) // Vista #else OSVERSIONINFO version = { 0 }; version.dwOSVersionInfoSize = sizeof(version); if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO)); if (version.dwMajorVersion >= 6) // Vista #endif { if (ERROR_SUCCESS == RegMedia_CreateKey(L"Capabilities",&mp3Key, prog_name)) { SetValue(mp3Key,L"ApplicationDescription", L"Winamp. The Ultimate Media Player."); SetValue(mp3Key,L"ApplicationName", prog_name); RegCloseKey(mp3Key); } if (ERROR_SUCCESS == RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\\RegisteredApplications", &mp3Key)) { TCHAR szValue[256] = {0}; StringCbPrintfW(szValue, sizeof(szValue), L"Software\\Clients\\Media\\%s\\Capabilities", prog_name); SetValue(mp3Key, prog_name, szValue); RegCloseKey(mp3Key); } if (ERROR_SUCCESS == RegMedia_CreateKey(L"Capabilities\\FileAssociations",&mp3Key, prog_name)) { RegCloseKey(mp3Key); } if (ERROR_SUCCESS == RegMedia_CreateKey(L"Capabilities\\MimeAssociations",&mp3Key, prog_name)) { RegCloseKey(mp3Key); } } return S_OK; } HRESULT FileTypeRegistrar::RegisterMediaPlayerProtocol(LPCWSTR protocol, LPCWSTR prog_name) { HKEY mp3Key = NULL; #if defined(_SYSINFOAPI_H_) && defined(NOT_BUILD_WINDOWS_DEPRECATE) && (_WIN32_WINNT >= 0x0501) if (IsWindowsVersionOrGreater(6, 0, 0)) // Vista #else OSVERSIONINFO version = { 0 }; version.dwOSVersionInfoSize = sizeof(version); if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO)); if (version.dwMajorVersion >= 6) // Vista #endif { if (ERROR_SUCCESS == RegMedia_CreateKey(L"Capabilities\\URLAssociations",&mp3Key, prog_name)) { wchar_t szBuffer[64] = {0}; StringCbCopyW(szBuffer, sizeof(szBuffer), protocol); CharUpperW(szBuffer); SetValue(mp3Key, protocol, szBuffer); RegCloseKey(mp3Key); } } return S_OK; } HRESULT FileTypeRegistrar::UnregisterMediaPlayerProtocol(LPCWSTR protocol, LPCWSTR prog_name) { HKEY mp3Key = NULL; #if defined(_SYSINFOAPI_H_) && defined(NOT_BUILD_WINDOWS_DEPRECATE) && (_WIN32_WINNT >= 0x0501) if (IsWindowsVersionOrGreater(6, 0, 0)) // Vista #else OSVERSIONINFO version = { 0 }; version.dwOSVersionInfoSize = sizeof(version); if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO)); if (version.dwMajorVersion >= 6) // Vista #endif { if (ERROR_SUCCESS == RegMedia_CreateKey(L"Capabilities\\URLAssociations",&mp3Key, prog_name)) { RegDeleteValue(mp3Key, protocol); RegCloseKey(mp3Key); } } return S_OK; } static LONG RegCreateKey4(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpSubKey2, PHKEY phkResult) { wchar_t temp[1024] = {0}; StringCchPrintfW(temp, 1024, L"%s%s", lpSubKey, lpSubKey2); return RegCreateKeyW(hKey,temp,phkResult); } static LONG RegCreateKey5(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpSubKey2, LPCWSTR lpSubKey3, PHKEY phkResult) { wchar_t temp[1024] = {0}; StringCchPrintfW(temp, 1024, L"%s%s%s", lpSubKey, lpSubKey2, lpSubKey3); return RegCreateKeyW(hKey,temp,phkResult); } static LONG RegCreateKey6(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpSubKey2, LPCWSTR lpSubKey3, LPCWSTR lpSubKey4, PHKEY phkResult) { wchar_t temp[1024] = {0}; StringCchPrintfW(temp, 1024, L"%s%s%s%s", lpSubKey, lpSubKey2, lpSubKey3,lpSubKey4); return RegCreateKeyW(hKey,temp,phkResult); } HRESULT FileTypeRegistrar::SetupShell(const wchar_t *commandLine, const wchar_t *winamp_file, const wchar_t *description, const wchar_t *commandName, const wchar_t *dragAndDropGUID) { HKEY mp3Key = NULL; if (RegCreateKey5(HKEY_CLASSES_ROOT,winamp_file, L"\\shell\\", commandName,&mp3Key) == ERROR_SUCCESS) { SetValue(mp3Key, description); RegCloseKey(mp3Key); } if (RegCreateKey6(HKEY_CLASSES_ROOT,winamp_file, L"\\shell\\", commandName, L"\\command",&mp3Key) == ERROR_SUCCESS) { SetValue(mp3Key, commandLine); RegCloseKey(mp3Key); } /* Drag and Drop stuff */ if (dragAndDropGUID && *dragAndDropGUID) { if (RegCreateKey6(HKEY_CLASSES_ROOT,winamp_file, L"\\shell\\", commandName, L"\\DropTarget",&mp3Key) == ERROR_SUCCESS) { SetValue(mp3Key, L"Clsid", dragAndDropGUID); RegCloseKey(mp3Key); } } return S_OK; } HRESULT FileTypeRegistrar::RemoveShell(const wchar_t *winamp_file, const wchar_t *commandName) { wchar_t temp[1024] = {0}; StringCchPrintfW(temp, 1024, L"%s\\shell\\%s", winamp_file, commandName); myRegDeleteKeyEx(HKEY_CLASSES_ROOT, temp); return S_OK; } HRESULT FileTypeRegistrar::SetupFileType(const wchar_t *programName, const wchar_t *winamp_file, const wchar_t *name, int iconNumber, const wchar_t *defaultShellCommand, const wchar_t *iconPath) { HKEY mp3Key = NULL; wchar_t str[MAX_PATH+32] = {0}; if (RegCreateKeyW(HKEY_CLASSES_ROOT,winamp_file,&mp3Key) == ERROR_SUCCESS) { StringCchCopyW(str,MAX_PATH+32,name); SetValue(mp3Key, str); RegCloseKey(mp3Key); } if (RegCreateKey4(HKEY_CLASSES_ROOT,winamp_file, L"\\DefaultIcon",&mp3Key) == ERROR_SUCCESS) { StringCchPrintfW(str,MAX_PATH+32,(iconPath[0]?L"%s":L"%s,%d"),(iconPath[0]?iconPath:programName),iconNumber); SetValue(mp3Key, str); RegCloseKey(mp3Key); } if (RegCreateKey4(HKEY_CLASSES_ROOT,winamp_file, L"\\shell",&mp3Key) == ERROR_SUCCESS) { SetValue(mp3Key, defaultShellCommand); RegCloseKey(mp3Key); } return S_OK; } HRESULT FileTypeRegistrar::SetupDefaultFileType(const wchar_t *winamp_file, const wchar_t *defaultShellCommand){ HKEY mp3Key = NULL; if (RegCreateKey4(HKEY_CLASSES_ROOT,winamp_file, L"\\shell",&mp3Key) == ERROR_SUCCESS) { SetValue(mp3Key, defaultShellCommand); RegCloseKey(mp3Key); } return S_OK; } HRESULT FileTypeRegistrar::RegisterTypeShell(const wchar_t *programName, const wchar_t *which_file, const wchar_t *description, int iconNumber, const wchar_t *commandName) { HKEY mp3Key = NULL; if (RegCreateKeyW(HKEY_CLASSES_ROOT,which_file,&mp3Key) == ERROR_SUCCESS) { SetValue(mp3Key, description); char str[4]; str[0]=0; str[1]=0; str[2]=1; str[3]=0; RegSetValueExW(mp3Key, L"EditFlags",0,REG_BINARY,(BYTE *)str,4); RegCloseKey(mp3Key); } if (RegCreateKey4(HKEY_CLASSES_ROOT, which_file, L"\\DefaultIcon",&mp3Key) == ERROR_SUCCESS) { wchar_t str[MAX_PATH+32] = {0}; StringCchPrintfW(str,MAX_PATH+32,L"%s,%d",programName,iconNumber); SetValue(mp3Key, str); RegCloseKey(mp3Key); } if (RegCreateKey4(HKEY_CLASSES_ROOT,which_file, L"\\shell",&mp3Key) == ERROR_SUCCESS) { SetValue(mp3Key, commandName); RegCloseKey(mp3Key); } return S_OK; } HRESULT FileTypeRegistrar::RegisterGUID(const wchar_t *programName, const wchar_t *guidString) { HKEY mp3Key = NULL; if (RegCreateKey4(HKEY_CLASSES_ROOT,L"CLSID\\", guidString, &mp3Key) == ERROR_SUCCESS) { RegCloseKey(mp3Key); } if (RegCreateKey5(HKEY_CLASSES_ROOT,L"CLSID\\", guidString, L"\\LocalServer32",&mp3Key) == ERROR_SUCCESS) { wchar_t str[MAX_PATH+32] = {0}; StringCchPrintfW(str,MAX_PATH+32, L"\"%s\"",programName); SetValue(mp3Key, str); RegCloseKey(mp3Key); } return S_OK; } HRESULT FileTypeRegistrar::RegisterDVDPlayer(const wchar_t *programName, int iconNumber, const wchar_t *which_file /*Winamp.DVD*/, const wchar_t *commandName /* Winamp */, const wchar_t *provider /* Nullsoft Winamp */, const wchar_t *description /* Play in Winamp */) { // TODO: stop hardcoding stuff as soon as we start using this wchar_t winampPath[MAX_PATH+128] = {0}; wchar_t winampIcon[MAX_PATH] = {0}; HKEY mp3Key = NULL; // create icon path and exe-with-param path StringCbPrintfW(winampIcon,sizeof(winampIcon), L"\"%s\", %d", programName, iconNumber); StringCbPrintfW(winampPath,sizeof(winampPath), L"\"%s\" %1", programName); // uncomment if we ever want to overwrite the default icon... not set because we don't have a good dvd icon in winamp.exe /* if (RegOpenKey(HKEY_CLASSES_ROOT,"DVD\\DefaultIcon",&mp3Key) == ERROR_SUCCESS) { RegSetValueExW(mp3Key,NULL,0,REG_SZ,winampIcon,iconSize); } */ if (RegCreateKeyW(HKEY_CLASSES_ROOT,L"DVD\\shell",&mp3Key) == ERROR_SUCCESS) { // set winamp to be the default player SetValue(mp3Key, commandName); RegCloseKey(mp3Key); } if (RegCreateKey4(HKEY_CLASSES_ROOT,L"DVD\\shell\\", commandName, &mp3Key) == ERROR_SUCCESS) { // text to appear in right-click shell menu in explorer SetValue(mp3Key, description); RegCloseKey(mp3Key); } if (RegCreateKey5(HKEY_CLASSES_ROOT,L"DVD\\shell\\", commandName, L"\\command",&mp3Key) == ERROR_SUCCESS) { // set the executable path SetValue(mp3Key, winampPath); RegCloseKey(mp3Key); } if (RegCreateKeyW(HKEY_LOCAL_MACHINE,L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoplayHandlers\\EventHandlers\\PlayDVDMovieOnArrival",&mp3Key) == ERROR_SUCCESS) { // register winamp for dvd autoplay RegSetValueExW(mp3Key,which_file,0,REG_SZ,0,0); RegCloseKey(mp3Key); } if (RegCreateKey4(HKEY_LOCAL_MACHINE,L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoplayHandlers\\Handlers\\", which_file, &mp3Key) == ERROR_SUCCESS) { // autoplay details SetValue(mp3Key,L"Action", description); SetValue(mp3Key,L"DefaultIcon", winampIcon); SetValue(mp3Key,L"InvokeProgID", L"DVD"); SetValue(mp3Key,L"InvokeVerb", commandName); SetValue(mp3Key,L"Provider", provider); RegCloseKey(mp3Key); } return S_OK; } HRESULT FileTypeRegistrar::InstallItem(LPCWSTR sourceFile, LPCWSTR destinationFolder, LPCWSTR destinationFilename) { SHFILEOPSTRUCT op = {0}; op.hwnd = 0; op.wFunc = FO_COPY; wchar_t srcFile[MAX_PATH+1] = {0}; wchar_t *end; StringCchCopyExW(srcFile, MAX_PATH, sourceFile, &end, 0, 0); if (end) end[1]=0; // double null terminate op.pFrom = srcFile; wchar_t destFile[MAX_PATH+1] = {0}; PathCombineW(destFile, destinationFolder, destinationFilename); destFile[wcslen(destFile)+1]=0; // double null terminate op.pTo = destFile; op.fFlags=FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_SIMPLEPROGRESS|FOF_NOERRORUI|FOF_SILENT; op.lpszProgressTitle = L""; int val = SHFileOperation(&op); // send back the error message so we can show on the UI if (val != 0 && val != 0x71/*DE_SAMEFILE*/) { StringCchPrintfW((LPWSTR)destinationFilename,MAX_PATH,L"0x%x",val); } return ((val == 0 || val == 0x71/*DE_SAMEFILE*/) ? S_OK : E_FAIL); } HRESULT FileTypeRegistrar::DeleteItem(LPCWSTR file) { SHFILEOPSTRUCT op = {0}; op.wFunc = FO_DELETE; wchar_t srcFile[MAX_PATH+1] = {0}; wchar_t *end; StringCchCopyExW(srcFile, MAX_PATH, file, &end, 0, 0); if (end) end[1]=0; // double null terminate op.pFrom = srcFile; op.fFlags = FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_SIMPLEPROGRESS|FOF_NORECURSION|FOF_NOERRORUI|FOF_SILENT|FOF_ALLOWUNDO; op.lpszProgressTitle = L""; int val = SHFileOperation(&op); return val == 0?S_OK:E_FAIL; } HRESULT FileTypeRegistrar::RenameItem(LPCWSTR oldFile, LPCWSTR newFile, BOOL force) { SHFILEOPSTRUCT op = {0}; op.wFunc = force?FO_MOVE:FO_RENAME; wchar_t srcFile[MAX_PATH+1] = {0}; wchar_t *end; StringCchCopyExW(srcFile, MAX_PATH, oldFile, &end, 0, 0); if (end) end[1]=0; // double null terminate op.pFrom = srcFile; wchar_t destFile[MAX_PATH+1] = {0}; end=0; StringCchCopyExW(destFile, MAX_PATH, newFile, &end, 0, 0); if (end) end[1]=0; // double null terminate op.pTo = destFile; op.fFlags=FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_SIMPLEPROGRESS|FOF_NOERRORUI|FOF_SILENT; op.lpszProgressTitle = L""; int val = SHFileOperation(&op); return val == 0?S_OK:E_FAIL; /* if (!MoveFile(oldFile, newFile)) { // if move failed if (!force) // if they don't want to force the move return E_FAIL; if (CopyFile(oldFile, newFile, FALSE) && DeleteFile(oldFile)) // copy then delete return E_FAIL; } return S_OK; */ } HRESULT FileTypeRegistrar::CleanupDirectory(LPCWSTR directory) { wchar_t dirmask[MAX_PATH] = {0}; WIN32_FIND_DATAW d = {0}; PathCombineW(dirmask, directory, L"*.*"); HANDLE h = FindFirstFileW(dirmask, &d); if (h != INVALID_HANDLE_VALUE) { do { wchar_t v[MAX_PATH] = {0}; PathCombineW(v, directory, d.cFileName); if (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (wcscmp(d.cFileName,L".") && wcscmp(d.cFileName,L"..")) CleanupDirectory(v); } else { if(!DeleteFileW(v)) { // this handles some rogue cases where files in the wlz's aren't unloadable MoveFileExW(v, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); MoveFileExW(directory, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); } } } while (FindNextFileW(h, &d)); FindClose(h); } RemoveDirectoryW(directory); return S_OK; } HRESULT FileTypeRegistrar::MoveDirectoryContents(LPCWSTR oldDirectory, LPCWSTR newDirectory) { wchar_t fromDirectory[MAX_PATH+1] = {0}; // need to zero it all so it will be double-null terminated SHFILEOPSTRUCT sf = {0}; StringCchPrintfW(fromDirectory,MAX_PATH,L"%s\\*",oldDirectory); sf.wFunc = FO_MOVE; sf.pFrom = fromDirectory; sf.pTo = newDirectory; sf.fFlags = FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_NOERRORUI|FOF_NORECURSION; if(SHFileOperation(&sf)){ return E_FAIL; } return S_OK; } HRESULT FileTypeRegistrar::WriteProKey(LPCWSTR name, LPCWSTR key) { HKEY hkey = NULL; if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Nullsoft\\Winamp", 0, 0, 0, KEY_READ | KEY_WRITE, NULL, &hkey, NULL) == ERROR_SUCCESS) { if (*name) SetValue(hkey, L"regname", name); else RegDeleteValueW(hkey, L"regname"); if (*key) { wchar_t buf[33] = {0}; StringCchCopyW(buf + 1, 32, key); buf[0] = '~'; for (int x = 1;buf[x]; x ++) { wchar_t c = towupper(buf[x]); //char c = buf[x]; // benski> goes with above commented line that i'd like to uncomment if (c >= 'A' && c <= 'Z') { int w = c - 'A'; w += x; w %= 26; buf[x] = 'A' + w; } else if (c >= '0' && c <= '9') { int w = c - '0'; w += x * 27; w %= 10; buf[x] = 'a' + w; } else if (c == '-') buf[x] = '/'; } SetValue(hkey, L"regkey", buf); } else { RegDeleteValueW(hkey, L"regkey"); } RegCloseKey(hkey); return S_OK; } return E_FAIL; } HRESULT FileTypeRegistrar::WriteClientUIDKey(LPCWSTR path, LPCWSTR uid_str) { HKEY hkey = NULL; if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Nullsoft\\Winamp", 0, 0, 0, KEY_READ | KEY_WRITE, NULL, &hkey, NULL) == ERROR_SUCCESS) { SetValue(hkey, path, uid_str); RegCloseKey(hkey); return S_OK; } return E_FAIL; } HRESULT FileTypeRegistrar::RegisterProtocol(LPCWSTR protocol, LPCWSTR command, LPCWSTR icon) { return S_OK; HKEY mp3Key = NULL; if (RegCreateKeyW(HKEY_CLASSES_ROOT, protocol, &mp3Key) == ERROR_SUCCESS) { wchar_t regStr[256] = {0}; SetValue(mp3Key, L"URL:Winamp Command Handler"); SetValue(mp3Key, L"URL Protocol", L""); RegCloseKey(mp3Key); StringCbPrintfW(regStr, sizeof(regStr), L"%s\\DefaultIcon", protocol); if (RegCreateKeyW(HKEY_CLASSES_ROOT,regStr,&mp3Key) == ERROR_SUCCESS) { SetValue(mp3Key, icon); RegCloseKey(mp3Key); } StringCbPrintfW(regStr, sizeof(regStr), L"%s\\shell\\open\\command", protocol); if (RegCreateKeyW(HKEY_CLASSES_ROOT,regStr,&mp3Key) == ERROR_SUCCESS) { SetValue(mp3Key, command); RegCloseKey(mp3Key); } } return S_OK; } HRESULT FileTypeRegistrar::RegisterCapability(const wchar_t *programName, const wchar_t *winamp_file, const wchar_t *extension) { #if defined(_SYSINFOAPI_H_) && defined(NOT_BUILD_WINDOWS_DEPRECATE) && (_WIN32_WINNT >= 0x0501) if (IsWindowsVersionOrGreater(6, 0, 0)) // Vista #else OSVERSIONINFO version = { 0 }; version.dwOSVersionInfoSize = sizeof(version); if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO)); if (version.dwMajorVersion >= 6) // Vista #endif { HKEY hkey_file_associations = NULL; if (ERROR_SUCCESS == RegMedia_CreateKey(L"Capabilities\\FileAssociations", &hkey_file_associations, programName)) { RegDeleteValueW(hkey_file_associations, extension); // to make sure that they are all in case that we need SetValue(hkey_file_associations, extension, winamp_file); RegCloseKey(hkey_file_associations); } } return S_OK; }