/** * Is a disc image supported by this class? * @param pHeader Disc image header. * @param szHeader Size of header. * @return Class-specific disc format ID (>= 0) if supported; -1 if not. */ int DiscReader::isDiscSupported_static(const uint8_t *pHeader, size_t szHeader) { // DiscReader supports everything. RP_UNUSED(pHeader); RP_UNUSED(szHeader); return 0; }
/** * Write data to the file. * (NOTE: Not valid for RpMemFile; this will always return 0.) * @param ptr Input data buffer. * @param size Amount of data to read, in bytes. * @return Number of bytes written. */ size_t RpMemFile::write(const void *ptr, size_t size) { // Not a valid operation for RpMemFile. RP_UNUSED(ptr); RP_UNUSED(size); m_lastError = EBADF; return 0; }
/** * Truncate the file. * @param size New size. (default is 0) * @return 0 on success; -1 on error. */ int RpMemFile::truncate(int64_t size) { // Not supported. // TODO: Writable RpMemFile? RP_UNUSED(size); m_lastError = ENOTSUP; return -1; }
int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) { HANDLE hSingleInstanceMutex; // Filename and path buffers. TCHAR *exe_path = NULL; // MAX_PATH #define EXE_PATH_LEN (MAX_PATH) TCHAR *dll_filename = NULL; // MAX_PATH+32 #define DLL_FILENAME_LEN (MAX_PATH+32) TCHAR *last_backslash; HKEY hkeyCLSID = NULL; // HKEY_CLASSES_ROOT\\CLSID DWORD exe_path_len; LONG lResult; unsigned int i; static const TCHAR prg_title[] = _T("ROM Properties Page Configuration"); RP_UNUSED(hPrevInstance); // Set Win32 security options. secoptions_init(); // Check if another instance of rp-config is already running. // References: // - https://stackoverflow.com/questions/4191465/how-to-run-only-one-instance-of-application // - https://stackoverflow.com/a/33531179 // TODO: Localized window title? hSingleInstanceMutex = CreateMutex(nullptr, TRUE, _T("Local\\com.gerbilsoft.rom-properties.rp-config")); if (!hSingleInstanceMutex || GetLastError() == ERROR_ALREADY_EXISTS) { // Mutex already exists. // Set focus to the existing instance. // TODO: Localized window titles? HWND hWnd = FindWindow(_T("#32770"), prg_title); if (hWnd) { SetForegroundWindow(hWnd); } return EXIT_SUCCESS; } // Set the C locale. // TODO: C++ locale? setlocale(LC_ALL, ""); #define FAIL_MESSAGE(msg) do { \ MessageBox(NULL, (msg), prg_title, MB_ICONSTOP); \ goto fail; \ } while (0) // Get the executable path. // TODO: Support longer than MAX_PATH? exe_path = malloc(MAX_PATH*sizeof(TCHAR)); if (!exe_path) FAIL_MESSAGE(_T("Failed to allocate memory for the EXE path.")); exe_path_len = GetModuleFileName(hInstance, exe_path, EXE_PATH_LEN); if (exe_path_len == 0 || exe_path_len >= EXE_PATH_LEN) FAIL_MESSAGE(_T("Failed to get the EXE path.")); // Find the last backslash. last_backslash = _tcsrchr(exe_path, L'\\'); if (last_backslash) { // NULL out everything after the backslash. last_backslash[1] = 0; exe_path_len = (DWORD)(last_backslash - exe_path + 1); } else { // Invalid path... // FIXME: Handle this. FAIL_MESSAGE(_T("EXE path is invalid.")); } // Initialize dll_filename with exe_path. dll_filename = malloc(DLL_FILENAME_LEN*sizeof(TCHAR)); if (!dll_filename) FAIL_MESSAGE(_T("Failed to allocate memory for the DLL filename.")); memcpy(dll_filename, exe_path, exe_path_len*sizeof(TCHAR)); // First, check for rom-properties.dll in rp-config.exe's directory. _tcscpy(&dll_filename[exe_path_len], _T("rom-properties.dll")); TRY_LOAD_DLL(dll_filename); // Check the architecture-specific subdirectory. _tcscpy(&dll_filename[exe_path_len], rp_subdir); // NOTE: -1 because _countof() includes the NULL terminator. _tcscpy(&dll_filename[exe_path_len + _countof(rp_subdir) - 1], _T("rom-properties.dll")); TRY_LOAD_DLL(dll_filename); // Check the CLSIDs. lResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID"), 0, KEY_ENUMERATE_SUB_KEYS, &hkeyCLSID); if (lResult != ERROR_SUCCESS) FAIL_MESSAGE(_T("Failed to open HKEY_CLASSES_ROOT\\CLSID.")); // Need to open "HKCR\\CLSID\\{CLSID}\\InprocServer32". for (i = 0; i < _countof(CLSIDs); i++) { HKEY hkeyClass, hkeyInprocServer32; DWORD cbData, dwType; lResult = RegOpenKeyEx(hkeyCLSID, CLSIDs[i], 0, KEY_ENUMERATE_SUB_KEYS, &hkeyClass); if (lResult != ERROR_SUCCESS) continue; lResult = RegOpenKeyEx(hkeyClass, _T("InprocServer32"), 0, KEY_READ, &hkeyInprocServer32); if (lResult != ERROR_SUCCESS) { RegCloseKey(hkeyClass); continue; } // Read the default value to get the DLL filename. cbData = DLL_FILENAME_LEN*sizeof(TCHAR); lResult = RegQueryValueEx( hkeyInprocServer32, // hKey NULL, // lpValueName NULL, // lpReserved &dwType, // lpType (LPBYTE)dll_filename, // lpData &cbData); // lpcbData RegCloseKey(hkeyInprocServer32); RegCloseKey(hkeyClass); if (lResult != ERROR_SUCCESS || (dwType != REG_SZ && dwType != REG_EXPAND_SZ)) continue; // Verify the NULL terminator. if ((cbData % sizeof(TCHAR) != 0) || dll_filename[(cbData/sizeof(TCHAR))-1] != 0) { // Either this isn't a multiple of 2 bytes, // or there's no NULL terminator. continue; } if (dll_filename[0] != 0 && dwType == REG_EXPAND_SZ) { // Expand the string. // cchExpand includes the NULL terminator. TCHAR *wbuf; DWORD cchExpand = ExpandEnvironmentStrings(dll_filename, nullptr, 0); if (cchExpand == 0) { // Error expanding the string. continue; } wbuf = malloc(cchExpand*sizeof(TCHAR)); cchExpand = ExpandEnvironmentStrings(dll_filename, wbuf, cchExpand); if (cchExpand == 0) { // Error expanding the string. free(wbuf); } else { // String has been expanded. free(dll_filename); dll_filename = wbuf; } } // Attempt to load this DLL. TRY_LOAD_DLL(dll_filename); } // All options have failed... MessageBox(NULL, _T("Could not find rom-properties.dll.\n\n") _T("Please ensure the DLL is present in the same\ndirectory as rp-config.exe."), prg_title, MB_ICONWARNING); fail: free(exe_path); free(dll_filename); if (hkeyCLSID) { RegCloseKey(hkeyCLSID); } return EXIT_FAILURE; }