Adición de Region-Change compatibilidad con una aplicación
[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEngine y Captura de audio/vídeo en Media Foundation. Esas características se han optimizado para Windows 10 y Windows 11. Microsoft recomienda encarecidamente que el nuevo código use MediaPlayer, IMFMediaEngine y Audio/Video Capture en Media Foundation en lugar de DirectShow, siempre que sea posible. Microsoft sugiere que el código existente que usa las API heredadas se reescriba para usar las nuevas API si es posible.
Se proporcionan las siguientes funciones para los desarrolladores que desean integrar la compatibilidad con el cambio de región en sus descodificadores o aplicaciones de DVD.
// Forward declares, constants, typedefs.
const short MAX_DRIVE_NAME = 4;
struct DriveName
{
TCHAR name[MAX_DRIVE_NAME];
};
BOOL DoesFileExist(LPTSTR pszFile);
BOOL GetDriveLetter(IDvdInfo2 *pDvd, DriveName& szDrive);
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
/////////////////////////////////////////////////////////////////////
// ChangeDVDRegion : Function to change the DVD drive region.
// Parameters:
// hWnd - Handle to the application window.
// Returns TRUE if the change is successful, or FALSE otherwise.
// (Failure usually means there was no drive with a valid DVD-V disc.)
/////////////////////////////////////////////////////////////////////
BOOL ChangeDVDRegion(HWND hWnd, IDvdInfo2 *pDvd)
{
typedef BOOL (APIENTRY *DVDPPLAUNCHER) (HWND hWnd, CHAR DriveLetter);
// First find out which drive is a DVD drive with a valid DVD-V disc.
DriveName szDVDDrive;
if (! GetDriveLetter(pDvd, szDVDDrive) )
{
MessageBox(hWnd, TEXT("No DVD drive was found with DVD-V disc."),
TEXT("Error"), MB_OK | MB_ICONERROR) ;
return FALSE;
}
// Detect the version.
OSVERSIONINFO ver;
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&ver);
if (VER_PLATFORM_WIN32_NT == ver.dwPlatformId)
{
HINSTANCE hInstDLL;
DVDPPLAUNCHER dvdPPLauncher;
CHAR szDVDDriveA[MAX_DRIVE_NAME];
const TCHAR szDllName[] = TEXT("\\storprop.dll");
// Allocate a large enough string to hold the path + the name.
TCHAR szCmdLine[MAX_PATH + (sizeof(szDllName)/sizeof(TCHAR)) + 1];
#ifdef UNICODE
WideCharToMultiByte(CP_ACP, 0, szDVDDrive.name, -1,
szDVDDriveA, sizeof(szDVDDriveA), NULL, NULL );
#else
StringCchCopy(szDVDDriveA, MAX_DRIVE_NAME, szDVDDrive.name);
#endif
UINT cb = GetSystemDirectory(szCmdLine, MAX_PATH + 1);
if (cb == 0 || cb > MAX_PATH + 1)
{
return FALSE;
}
StringCchCat(szCmdLine, ARRAY_SIZE(szCmdLine), szDllName);
hInstDLL = LoadLibrary (szCmdLine);
if (hInstDLL)
{
BOOL bResult = FALSE;
dvdPPLauncher = (DVDPPLAUNCHER) GetProcAddress(hInstDLL,
"DvdLauncher");
if (dvdPPLauncher)
{
bResult = dvdPPLauncher(hWnd, szDVDDriveA[0]);
}
FreeLibrary(hInstDLL);
return bResult;
}
}
else
{
return FALSE;
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////
// GetDriveLetter: Returns the drive letter of the active DVD drive.
// Parameters:
// pDvdC - IDvdControl2 interface of the DVD Navigator filter.
// pszDrive - Receives the first DVD drive with a valid DVD-V disc.
// Returns TRUE if there is a DVD drive with a valid disc.
/////////////////////////////////////////////////////////////////////
BOOL GetDriveLetter(IDvdInfo2 *pDvd, DriveName& pszDrive)
{
WCHAR szPathW[MAX_PATH];
TCHAR szPath[MAX_PATH];
ULONG ulActualSize = 0;
pszDrive.name[0] = pszDrive.name[MAX_DRIVE_NAME - 1] = 0;
// Get the current root directory
HRESULT hr = pDvd->GetDVDDirectory(szPathW, MAX_PATH, &ulActualSize);
if (SUCCEEDED(hr))
{
#ifdef UNICODE
StringCchCopy(pszDrive.name, MAX_DRIVE_NAME, szPathW);
#else
WideCharToMultiByte(CP_ACP, 0, szPathW, ulActualSize, szPath, MAX_PATH, 0, 0);
StringCchCopy(pszDrive.name, MAX_DRIVE_NAME, szPath);
#endif
if (DRIVE_CDROM == GetDriveType(pszDrive.name)) // could be a DVD drive
return TRUE;
}
// Now loop through all the valid drives to detect which one
// is a DVD drive with a valid DVD-V disc in it.
// Get all valid drives
DWORD dwLen = GetLogicalDriveStrings(MAX_PATH, szPath);
if (dwLen > MAX_PATH)
{
// The function returns a larger value if the buffer is too small.
return FALSE;
}
// Try all drives one by one
for (size_t dw = 0; dw < dwLen; )
{
TCHAR *szTmp = szPath + dw;
// Look only for CD-ROM drives that has a disc with required (.ifo) files
if (DRIVE_CDROM == GetDriveType(szTmp))
{
TCHAR szDVDPath1[MAX_PATH + 1];
TCHAR szDVDPath2[MAX_PATH + 1];
StringCchCopy(szDVDPath1, MAX_DRIVE_NAME, szTmp);
StringCchCopy(szDVDPath2, MAX_DRIVE_NAME, szTmp);
StringCchCat(szDVDPath1, ARRAY_SIZE(szDVDPath1), TEXT("Video_ts\\Video_ts.ifo"));
StringCchCat(szDVDPath2, ARRAY_SIZE(szDVDPath2), TEXT("Video_ts\\Vts_01_0.ifo"));
// If the .ifo files exist on this drive then it has a valid DVD-V disc
if (DoesFileExist(szDVDPath1) && DoesFileExist(szDVDPath2))
{
StringCchCopy(pszDrive.name, MAX_DRIVE_NAME, szTmp);
return TRUE; // return the first drive that has a valid DVD-V disc
}
}
size_t len = 0;
StringCchLength(szTmp, STRSAFE_MAX_CCH, &len);
dw += len + 1;
}
return FALSE ; // didn't find any DVD drive with DVD-V content
}
/////////////////////////////////////////////////////////////////////
// DoesFileExist : Determines whether a specified file exists
// Parameters:
// pszFile - File name to check.
// Returns TRUE if the specified file is found, or FALSE otherwise.
/////////////////////////////////////////////////////////////////////
BOOL DoesFileExist(LPTSTR pszFile)
{
if (pszFile == NULL)
{
return FALSE;
}
size_t len = 0;
if (FAILED(StringCchLength(pszFile, STRSAFE_MAX_CCH, &len)))
{
return FALSE;
}
if (len > MAX_PATH)
{
return FALSE;
}
// We don't want any error message box to pop up when we try to test
// if the required file is available to open for read --apcb.
UINT uErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
HANDLE hFile = CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
SetErrorMode(uErrorMode); // restore error mode
if (INVALID_HANDLE_VALUE == hFile)
{
return FALSE;
}
CloseHandle(hFile);
return TRUE;
}
Temas relacionados