#include #include #include #include #include // // ChangeDVDRegion: Function to change DVD drive region. // Parameters: // In: hWnd-window handle of the application that calls this function // Out: none. // Returns: // TRUE: if the drive region change is successful // FALSE: if drive region change fails (probably because no drive was found with a valid DVD-V disc). // BOOL ChangeDVDRegion(HWND hWnd) { typedef BOOL (*DVDPPLAUNCHER) (HWND hWnd, CHAR DriveLetter); BOOL bRegionChanged = FALSE; TCHAR szCmdLine[MAX_PATH]; // // First find out which drive is a DVD drive with a valid DVD-V disc. // TCHAR szDVDDrive[4]; if (! GetDriveLetter (szDVDDrive) ) { MessageBox(hWnd, TEXT("No DVD drive was found with DVD-Video disc.") TEXT("\nCannot change DVD region of the drive."), TEXT("Error"), MB_OK | MB_INFORMATION) ; return FALSE; } // // Detect which OS we are running on. For Windows NT, use the storprop.dll; // for Windows 95/98 platform, use the DVDRgn.exe application to change the region. // OSVERSIONINFO ver; ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&ver); if (VER_PLATFORM_WIN32_NT == ver.dwPlatformId) { // Windows NT platform HINSTANCE hInstDLL; DVDPPLAUNCHER dvdPPLauncher; CHAR szDVDDriveA[4]; #ifdef UNICODE WideCharToMultiByte(0, 0, szDVDDrive, -1, szDVDDriveA, sizeof(szDVDDriveA), NULL, NULL ); #else strcpy(szDVDDriveA, szDVDDrive); #endif // UNICODE GetSystemDirectory(szCmdLine, MAX_PATH); lstrcat(szCmdLine, TEXT("\\storprop.dll")); hInstDLL = LoadLibrary (szCmdLine); if (hInstDLL) { dvdPPLauncher = (DVDPPLAUNCHER) GetProcAddress(hInstDLL, "DvdLauncher"); if (dvdPPLauncher) { bRegionChanged = dvdPPLauncher(hWnd, szDVDDriveA[0]); } FreeLibrary(hInstDLL); } } // end of region change code for Windows NT platform else // Windows 98 platform { // Get path of \windows\dvdrgn.exe for command line string GetWindowsDirectory(szCmdLine, MAX_PATH); lstrcat(szCmdLine, TEXT("\\DVDRgn.exe ")); // Add only the drive letter as command line parameter lstrncat(szCmdLine, szDVDDrive, 1); // Prepare to execute DVDRgn.exe STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInfo; StartupInfo.cb = sizeof(StartupInfo); StartupInfo.dwFlags = STARTF_USESHOWWINDOW; StartupInfo.wShowWindow = SW_SHOWNORMAL; StartupInfo.lpReserved = NULL; StartupInfo.lpDesktop = NULL; StartupInfo.lpTitle = NULL; StartupInfo.cbReserved2 = 0; StartupInfo.lpReserved2 = NULL; if (CreateProcess(csModuleName, szCmdLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartupInfo, &ProcessInfo) ) { // Wait until DVDRgn.exe finishes WaitForSingleObject(ProcessInfo.hProcess, INFINITE); DWORD dwRet = 1; BOOL bRet = GetExitCodeProcess(ProcessInfo.hProcess, &dwRet); // If the user changed the drive region successfully, the exit code of DVDRgn.exe is 0. if (bRet && 0 == dwRet) { bRegionChanged = TRUE; } } } // end of region change code for Windows 95/98 platform if (bRegionChanged) // if region changed successfully { // // Delete old filter graph and create new filter graph via IDvdGraphBuilder::RenderDvdVideoVolume(). // } else // DVD region didn't happen { MessageBox(hWnd, TEXT("DVD drive region could not be changed.") TEXT("Error"), MB_OK | MB_INFORMATION) ; } } // // GetDriveLetter : Get the drive letter of the currently active DVD drive // Parameters: // In: pDvdC - pointer to IDvdControl interface of DVDNavigator filter. // Out: pszDrive - the first DVD drive that is found to have a valid DVD-V disc. // Returns: // TRUE: if a DVD drive is found (with valid disc) // FALSE: if no DVD drive was found with valid DVD-V disc. // BOOL GetDriveLetter(IDvdControl *pDvdC, TCHAR *pszDrive) { CHAR szPathA[MAX_PATH]; TCHAR szPath[MAX_PATH]; ULONG ulActualSize; pszDrive[0] = pszDrive[3] = 0; // // Get the current root directory // if (pDvdC ->GetRoot(szPathA, MAX_PATH, &ulActualSize)) { #ifdef UNICODE MultiByteToWideChar(CP_ACP, 0, szPathA, 0, szPath, MAX_PATH); #else lstrcpy(szPath, szPathA); #endif // UNICODE lstrcpyn(pszDrive, szPath, 3); if (DRIVE_CDROM == GetDriveType(pszDrive)) // could be a DVD drive return TRUE; } // // 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 dwLeng = GetLogicalDriveStrings(MAX_PATH, szPath); TCHAR *pszTemp = szPath; // Try all drives one by one for (DWORD dw = 0; dw < dwLeng; dw += 4) { // Look only for CD-ROM drives that has a disc with required (.ifo) files if (DRIVE_CDROM == GetDriveType(pszTemp)) { TCHAR szDVDPath1[MAX_PATH] TCHAR szDVDPath2[MAX_PATH]; lstrcpyn(szDVDPath1, pszTemp, 4); lstrcpyn(szDVDPath 2, pszTemp, 4); lstrcat(szDVDPath1, TEXT("Video_ts \\Video_ts.ifo")); lstrcat(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(achDVDPath1) && DoesFileExist(achDVDPath2)) { lstrcpyn(pszDrive, pszTemp, 3); return TRUE; // return the first drive that has a valid DVD-V disc } } pszTemp += 4; } return FALSE ; // didn't find any DVD drive with DVD-V content) } // // DoesFileExist : Determine if the given filename is an existing file. // Parameters: // In: pszFile - filename string to check for existence. // Out: None. // Returns: // TRUE: if the specified file is found. // FALSE: if the specified file is not found. // BOOL DoesFileExist(LPTSTR pszFile) { HANDLE hFile = NULL ; // // We don't want any error message box to pop up when we try to test // whether the required file is available toopen for read. // UINT uErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); 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; } **********Sample Code for Setting Default Region in Windows 2000********** #define DEFINEMY_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ const GUID name \ = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } typedef struct _SP_DEVICE_INTERFACE_DETAIL_DATA_MINE{ DWORD cbSize; CHAR DevicePath[255]; }SP_DEVICE_INTERFACE_DETAIL_DATA_MINE, * PSP_DEVICE_INTERFACE_DETAIL_DATA_MINE; VOID help( VOID ); INT CheckParameters( INT argc, CHAR * argv[] ); VOID __cdecl main( INT argc, CHAR * argv[] ) { // //Defining the CDROM GUID // DEFINEMY_GUID(cdromGUID, 0x53f56308L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); SP_DEVICE_INTERFACE_DETAIL_DATA_MINE DeviceInterfaceDetailData; SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; SP_DEVINFO_DATA DeviceInfoData; HDEVINFO DeviceInfo = INVALID_HANDLE_VALUE; DWORD RegNumValues = 0; DWORD loop = 0; DWORD ReturnCodes = 0; DWORD RetCode = 0; DWORD Region = 0; BOOL RegionSet = FALSE; CHAR szDevInstanceID[255]; CHAR szFriendlyName[255]; CHAR szClassLocal[1024]; HKEY hDeviceRegKey = INVALID_HANDLE_VALUE; INT DeviceInc = 0; // //Set the Region Number. // Region = CheckParameters(argc, argv); if (Region == -1) { // //Invalid region lets exit. // return; } DeviceInfo = SetupDiGetClassDevsEx( &cdromGUID, NULL, NULL, DIGCF_DEVICEINTERFACE, NULL, NULL, NULL ); if (DeviceInfo == INVALID_HANDLE_VALUE) { printf("Error in creating device info. Winerror = %d.\n", GetLastError()); return; } while (!ReturnCodes) { // //Here we will enumerate through all the CD/DVD-ROM drives // // //Zero out data buffers. // ZeroMemory(&DeviceInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA)); ZeroMemory(&DeviceInterfaceDetailData, sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)); ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); // //Here we enumerate the device Information. // if (!SetupDiEnumDeviceInterfaces( DeviceInfo, NULL, &cdromGUID, DeviceInc, &DeviceInterfaceData)) { ReturnCodes = GetLastError(); // //No need to continue processing lets move to the bottom. // DeviceInc++; continue; } DeviceInterfaceDetailData.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail( DeviceInfo, &DeviceInterfaceData, (PSP_DEVICE_INTERFACE_DETAIL_DATA) &DeviceInterfaceDetailData, 255, NULL, &DeviceInfoData )) { ReturnCodes = GetLastError(); } if (!ReturnCodes) { if (DeviceInterfaceData.Flags & SPINT_ACTIVE) { // //Getting device Friendly Name. // if (SetupDiGetDeviceRegistryProperty( DeviceInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, NULL, szFriendlyName, 255, NULL )) { printf("Device Name = %s.\n", szFriendlyName); } // //Getting Device Location in the Class area. // if (SetupDiGetDeviceRegistryProperty( DeviceInfo, &DeviceInfoData, SPDRP_DRIVER, NULL, szDevInstanceID, 255, NULL )) { printf("Device Instance ID = %s.\n", szDevInstanceID); sprintf(szClassLocal, "System\\CurrentControlSet\\Control\\Class\\%s\0", szDevInstanceID); RetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE, szClassLocal, 0, KEY_ALL_ACCESS, &hDeviceRegKey ); if (RetCode) { printf("ERROR: could not open registry key. Winerror.h = %d.\n", RetCode); }else{ printf("Device registry class values:\n"); // //We opened up the registry just fine. // RegQueryInfoKey( hDeviceRegKey, NULL, NULL, NULL, NULL, NULL, NULL, &RegNumValues, NULL, NULL, NULL, NULL); for (loop = 0; loop < RegNumValues; loop++) { // //Probably should not declare here, but it is easy and convenient. // DWORD SizeValueName = 255; DWORD TypeValue = 0; DWORD SizeOfbuffer = 1024; CHAR BuffData[1024]; CHAR BufferData[1024]; CHAR szValueName[255]; if (!RegEnumValue( hDeviceRegKey, loop, szValueName, &SizeValueName, NULL, &TypeValue, BufferData, &SizeOfbuffer)) { if (!_strnicmp(szValueName, "DefaultDvdRegion", SizeValueName)) { RegionSet = TRUE; // //Found the right region number. // RegSetValueEx( hDeviceRegKey, szValueName, 0, REG_DWORD, (UCHAR *) &Region, sizeof(DWORD) ); printf("Set Default Region from 0x%X to 0x%X.\n", *BufferData, Region); } } } if (!RegionSet) { // //Region key was not found so lets seed one //with the default key. // RegSetValueEx( hDeviceRegKey, "DefaultDvdRegion", 0, REG_DWORD, (UCHAR *) &Region, sizeof(DWORD) ); } RegionSet = FALSE; } RegCloseKey(hDeviceRegKey); } } } DeviceInc++; }//end of while if (ReturnCodes) { if (ReturnCodes != ERROR_NO_MORE_ITEMS) { printf("Could not get device interface info. Winerror.h = %d.\n", ReturnCodes); }else{ puts("Finished querying- no more items."); } } SetupDiDestroyDeviceInfoList(DeviceInfo); }//main VOID help( VOID ) /*++ Routine: This just prints a quick screen of help. Parameters: None Return Value: None --*/ { puts("cdregion will change the default region of all active cdroms in the system."); puts("Usage:"); puts("cdregion 1"); puts("cdregion [number of region]"); }//help INT CheckParameters( INT argc, CHAR * argv[] ) /*++ Routine: Checks the command line parameter and sends it back the region to set. Parameters: Command Line info Return: Region to set. --*/ { if (argc >= 2) { if (IsCharAlphaNumeric(argv[1][0])) { if (!IsCharAlpha(argv[1][0])) { // //Variable is a number. // return atoi(&argv[1][0]); } } } puts("Not enough parameters:"); help(); return -1; }//CheckParameters