1200 lines
29 KiB
C
1200 lines
29 KiB
C
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1998 - 1999
|
|
//
|
|
// File: dvdprop.c
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "propp.h"
|
|
#include "ntddcdvd.h"
|
|
#include "dvdprop.h"
|
|
#include "volprop.h"
|
|
#include "resource.h"
|
|
|
|
//
|
|
// Instantiate the device interface GUIDs defined in ntddstor.h in this module
|
|
//
|
|
#include <initguid.h>
|
|
#include <ntddstor.h>
|
|
|
|
//
|
|
// Help ID mapping for context sensitive help
|
|
//
|
|
const DWORD DvdHelpIDs[]=
|
|
{
|
|
IDC_CURRENT_REGION, IDH_DEVMGR_DVD_CURRENT, //Current region box
|
|
IDC_NEW_REGION, IDH_DEVMGR_DVD_NEW, //New region box
|
|
IDC_DVD_COUNTRY_LIST, IDH_DEVMGR_DVD_LIST, //List box
|
|
IDC_DVD_HELP, IDH_DEVMGR_DVD_NOHELP,
|
|
IDC_CHANGE_TEXT, IDH_DEVMGR_DVD_NOHELP,
|
|
0, 0
|
|
};
|
|
|
|
ULONG RegionIndexTable[MAX_REGIONS] = {
|
|
DVD_REGION1_00,
|
|
DVD_REGION2_00,
|
|
DVD_REGION3_00,
|
|
DVD_REGION4_00,
|
|
DVD_REGION5_00,
|
|
DVD_REGION6_00
|
|
};
|
|
|
|
ULONG RegionSizeTable[MAX_REGIONS] = {
|
|
DVD_MAX_REGION1,
|
|
DVD_MAX_REGION2,
|
|
DVD_MAX_REGION3,
|
|
DVD_MAX_REGION4,
|
|
DVD_MAX_REGION5,
|
|
DVD_MAX_REGION6
|
|
};
|
|
|
|
BOOL
|
|
IsUserAdmin(
|
|
VOID
|
|
);
|
|
|
|
PPAGE_INFO DvdCreatePageInfo(IN HDEVINFO deviceInfoSet,
|
|
IN PSP_DEVINFO_DATA deviceInfoData)
|
|
{
|
|
PPAGE_INFO tmp = NULL;
|
|
|
|
if (!(tmp = LocalAlloc(LPTR, sizeof(PAGE_INFO)))) {
|
|
return NULL;
|
|
}
|
|
|
|
memset (tmp, 0, sizeof(PAGE_INFO));
|
|
tmp->deviceInfoSet = deviceInfoSet;
|
|
tmp->deviceInfoData = deviceInfoData;
|
|
|
|
return tmp;
|
|
}
|
|
|
|
void
|
|
DvdDestroyPageInfo(PPAGE_INFO * ppPageInfo)
|
|
{
|
|
PPAGE_INFO ppi = *ppPageInfo;
|
|
|
|
LocalFree(ppi);
|
|
*ppPageInfo = NULL;
|
|
}
|
|
|
|
HPROPSHEETPAGE
|
|
DvdCreatePropertyPage(PROPSHEETPAGE * ppsp,
|
|
PPAGE_INFO ppi)
|
|
{
|
|
//
|
|
// Add the Port Settings property page
|
|
//
|
|
ppsp->dwSize = sizeof(PROPSHEETPAGE);
|
|
ppsp->dwFlags = PSP_USECALLBACK; // | PSP_HASHELP;
|
|
ppsp->hInstance = ModuleInstance;
|
|
ppsp->pszTemplate = MAKEINTRESOURCE(ID_DVD_PROPPAGE);
|
|
|
|
//
|
|
// following points to the dlg window proc
|
|
//
|
|
ppsp->pfnDlgProc = DvdDlgProc;
|
|
ppsp->lParam = (LPARAM) ppi;
|
|
|
|
//
|
|
// Following points to the control callback of the dlg window proc.
|
|
// The callback gets called before creation/after destruction of the page
|
|
//
|
|
ppsp->pfnCallback = DvdDlgCallback;
|
|
|
|
//
|
|
// Allocate the actual page
|
|
//
|
|
return CreatePropertySheetPage(ppsp);
|
|
}
|
|
|
|
|
|
BOOL APIENTRY
|
|
DvdPropPageProvider(LPVOID pinfo,
|
|
LPFNADDPROPSHEETPAGE pfnAdd,
|
|
LPARAM lParam)
|
|
{
|
|
PSP_PROPSHEETPAGE_REQUEST ppr;
|
|
PROPSHEETPAGE psp;
|
|
HPROPSHEETPAGE hpsp;
|
|
PPAGE_INFO ppi = NULL;
|
|
|
|
ppr = (PSP_PROPSHEETPAGE_REQUEST) pinfo;
|
|
|
|
if (ppr->PageRequested == SPPSR_ENUM_ADV_DEVICE_PROPERTIES) {
|
|
|
|
ppi = DvdCreatePageInfo(ppr->DeviceInfoSet,
|
|
ppr->DeviceInfoData);
|
|
|
|
if (!ppi) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (!GetCurrentRpcData(ppi, &ppi->regionData)) {
|
|
|
|
//
|
|
// not a DVD-ROM with RPC2 support
|
|
//
|
|
DvdDestroyPageInfo(&ppi);
|
|
return FALSE;
|
|
}
|
|
|
|
memset(&psp, 0, sizeof(PROPSHEETPAGE));
|
|
|
|
hpsp = DvdCreatePropertyPage(&psp, ppi);
|
|
|
|
if (!hpsp) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (!pfnAdd(hpsp, lParam)) {
|
|
DestroyPropertySheetPage(hpsp);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
UINT CALLBACK
|
|
DvdDlgCallback(HWND hwnd,
|
|
UINT uMsg,
|
|
LPPROPSHEETPAGE ppsp)
|
|
{
|
|
PPAGE_INFO ppi;
|
|
|
|
switch (uMsg) {
|
|
case PSPCB_CREATE:
|
|
return TRUE; // return TRUE to continue with creation of page
|
|
|
|
case PSPCB_RELEASE:
|
|
ppi = (PPAGE_INFO) ppsp->lParam;
|
|
DvdDestroyPageInfo(&ppi);
|
|
|
|
return 0; // return value ignored
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
DvdInitializeControls(PPAGE_INFO ppi,
|
|
HWND hDlg)
|
|
{
|
|
DWORD dwError;
|
|
DWORD dwType;
|
|
DWORD dwSize;
|
|
BOOL disableControls = FALSE;
|
|
HWND hwnd;
|
|
ULONG i;
|
|
ULONG j;
|
|
TCHAR buffer[1000];
|
|
|
|
hwnd = GetDlgItem(hDlg, IDC_DVD_COUNTRY_LIST);
|
|
for (i=0; i<MAX_REGIONS; i++) {
|
|
|
|
for (j=0; j<RegionSizeTable[i]; j++) {
|
|
|
|
if (LoadString(ModuleInstance,
|
|
RegionIndexTable[i] + j,
|
|
buffer,
|
|
100)) {
|
|
|
|
SendMessage(hwnd,
|
|
LB_ADDSTRING,
|
|
0,
|
|
(LPARAM) buffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
hwnd = GetDlgItem(hDlg, IDC_DVD_HELP);
|
|
if (LoadString(ModuleInstance,
|
|
DVD_HELP,
|
|
buffer,
|
|
1000)) {
|
|
|
|
SendMessage(hwnd,
|
|
WM_SETTEXT,
|
|
0,
|
|
(LPARAM) buffer);
|
|
}
|
|
|
|
hwnd = GetDlgItem(hDlg, IDC_DVD_CAUTION);
|
|
if (LoadString(ModuleInstance,
|
|
DVD_CAUTION,
|
|
buffer,
|
|
1000)) {
|
|
|
|
SendMessage(hwnd,
|
|
WM_SETTEXT,
|
|
0,
|
|
(LPARAM) buffer);
|
|
}
|
|
|
|
hwnd = GetDlgItem(hDlg, IDC_DVD_CHANGE_HELP);
|
|
if (LoadString(ModuleInstance,
|
|
DVD_CHANGE_HELP,
|
|
buffer,
|
|
1000)) {
|
|
|
|
SendMessage(hwnd,
|
|
WM_SETTEXT,
|
|
0,
|
|
(LPARAM) buffer);
|
|
}
|
|
|
|
DvdUpdateCurrentSettings (ppi, hDlg);
|
|
}
|
|
|
|
BOOL
|
|
DvdApplyChanges(PPAGE_INFO ppi,
|
|
HWND hDlg)
|
|
{
|
|
UCHAR keyBuffer[DVD_SET_RPC_KEY_LENGTH];
|
|
PDVD_COPY_PROTECT_KEY copyProtectKey;
|
|
PDVD_SET_RPC_KEY rpcKey;
|
|
ULONG i;
|
|
BOOL popupError = FALSE;
|
|
BOOL status;
|
|
ULONG returned;
|
|
TCHAR bufferFormat[500];
|
|
TCHAR buffer[500];
|
|
TCHAR titleBuffer[500];
|
|
BOOL okToProceed;
|
|
HANDLE writeHandle = INVALID_HANDLE_VALUE;
|
|
|
|
if ((ppi->newRegion == 0) ||
|
|
(ppi->currentRegion == ppi->newRegion)) {
|
|
|
|
//
|
|
// nothing to do
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// confirm with the user
|
|
//
|
|
|
|
okToProceed = FALSE;
|
|
|
|
if (ppi->regionData.ResetCount == 1) {
|
|
|
|
if (LoadString(ModuleInstance,
|
|
DVD_SET_RPC_CONFIRM_LAST_CHANCE,
|
|
buffer,
|
|
500) &&
|
|
LoadString(ModuleInstance,
|
|
DVD_SET_RPC_CONFIRM_TITLE,
|
|
titleBuffer,
|
|
500)) {
|
|
|
|
if (MessageBox(hDlg,
|
|
buffer,
|
|
titleBuffer,
|
|
MB_ICONEXCLAMATION | MB_OKCANCEL |
|
|
MB_DEFBUTTON2 | MB_APPLMODAL) == IDOK) {
|
|
|
|
okToProceed = TRUE;
|
|
}
|
|
}
|
|
} else {
|
|
if (LoadString(ModuleInstance,
|
|
DVD_SET_RPC_CONFIRM,
|
|
bufferFormat,
|
|
500) &&
|
|
LoadString(ModuleInstance,
|
|
DVD_SET_RPC_CONFIRM_TITLE,
|
|
titleBuffer,
|
|
500)) {
|
|
|
|
wsprintf (buffer, bufferFormat, ppi->newRegion);
|
|
|
|
if (MessageBox(hDlg,
|
|
buffer,
|
|
titleBuffer,
|
|
MB_ICONEXCLAMATION | MB_OKCANCEL |
|
|
MB_DEFBUTTON2 | MB_APPLMODAL) == IDOK) {
|
|
|
|
okToProceed = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (okToProceed == FALSE) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// make sure the drive has a dvd with the same region
|
|
// call GetCurrentRpcData
|
|
//
|
|
|
|
writeHandle = UtilpGetDeviceHandle(ppi->deviceInfoSet,
|
|
ppi->deviceInfoData,
|
|
(LPGUID)&CdRomClassGuid,
|
|
GENERIC_READ | GENERIC_WRITE);
|
|
|
|
if (writeHandle != INVALID_HANDLE_VALUE) {
|
|
|
|
copyProtectKey = (PDVD_COPY_PROTECT_KEY) keyBuffer;
|
|
|
|
memset(copyProtectKey, 0, DVD_SET_RPC_KEY_LENGTH);
|
|
|
|
copyProtectKey->KeyLength = DVD_SET_RPC_KEY_LENGTH;
|
|
copyProtectKey->KeyType = DvdSetRpcKey;
|
|
|
|
rpcKey = (PDVD_SET_RPC_KEY) copyProtectKey->KeyData;
|
|
rpcKey->PreferredDriveRegionCode = ~(1 << (ppi->newRegion - 1));
|
|
|
|
status = DeviceIoControl(writeHandle,
|
|
IOCTL_DVD_SEND_KEY2,
|
|
copyProtectKey,
|
|
DVD_SET_RPC_KEY_LENGTH,
|
|
NULL,
|
|
0,
|
|
&returned,
|
|
FALSE);
|
|
|
|
CloseHandle (writeHandle);
|
|
|
|
} else {
|
|
|
|
status = 0;
|
|
|
|
}
|
|
|
|
if (!status) {
|
|
|
|
|
|
if (LoadString(ModuleInstance,
|
|
DVD_SET_RPC_ERROR,
|
|
bufferFormat,
|
|
500) &&
|
|
LoadString(ModuleInstance,
|
|
DVD_SET_RPC_ERROR_TITLE,
|
|
titleBuffer,
|
|
500)) {
|
|
|
|
wsprintf (buffer, bufferFormat, ppi->newRegion);
|
|
|
|
MessageBox(hDlg,
|
|
buffer,
|
|
titleBuffer,
|
|
MB_ICONERROR | MB_OK);
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
} else {
|
|
|
|
GetCurrentRpcData(ppi, &ppi->regionData);
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
INT_PTR APIENTRY
|
|
DvdDlgProc(IN HWND hDlg,
|
|
IN UINT uMessage,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam)
|
|
{
|
|
PPAGE_INFO ppi;
|
|
|
|
ppi = (PPAGE_INFO) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch (uMessage) {
|
|
case WM_INITDIALOG:
|
|
|
|
//
|
|
// on WM_INITDIALOG call, lParam points to the property
|
|
// sheet page.
|
|
//
|
|
// The lParam field in the property sheet page struct is set by the
|
|
// caller. When I created the property sheet, I passed in a pointer
|
|
// to a struct containing information about the device. Save this in
|
|
// the user window long so I can access it on later messages.
|
|
//
|
|
ppi = (PPAGE_INFO) ((LPPROPSHEETPAGE)lParam)->lParam;
|
|
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR) ppi);
|
|
|
|
//
|
|
// Initialize dlg controls
|
|
//
|
|
DvdInitializeControls(ppi, hDlg);
|
|
|
|
//
|
|
// Didn't set the focus to a particular control. If we wanted to,
|
|
// then return FALSE
|
|
//
|
|
return TRUE;
|
|
|
|
case WM_COMMAND:
|
|
|
|
switch (HIWORD(wParam)) {
|
|
case CBN_SELCHANGE:
|
|
PropSheet_Changed(GetParent(hDlg), hDlg);
|
|
DvdUpdateNewRegionBox (ppi, hDlg);
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, (LONG_PTR) PSNRET_NOERROR);
|
|
return TRUE;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch(LOWORD(wParam)) {
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
return DvdContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
|
|
|
|
case WM_HELP:
|
|
DvdHelp(hDlg, (LPHELPINFO) lParam);
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
|
|
switch (((NMHDR *)lParam)->code) {
|
|
|
|
// case PSN_KILLACTIVE:
|
|
// if (ppi->changesFailed) {
|
|
//
|
|
// SetWindowLong(hDlg, DWL_MSGRESULT, TRUE);
|
|
// } else {
|
|
//
|
|
// SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
|
|
// }
|
|
// return TRUE;
|
|
|
|
//
|
|
// Sent when the user clicks on Apply OR OK !!
|
|
//
|
|
case PSN_APPLY:
|
|
//
|
|
// Do what ever action is necessary
|
|
//
|
|
if (DvdApplyChanges(ppi, hDlg)) {
|
|
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
|
|
ppi->changesFailed = FALSE;
|
|
|
|
DvdUpdateCurrentSettings(ppi, hDlg);
|
|
|
|
} else {
|
|
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
|
|
ppi->changesFailed = TRUE;
|
|
}
|
|
return TRUE;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
DvdUpdateNewRegionBox (PPAGE_INFO ppi,
|
|
HWND hDlg)
|
|
{
|
|
HWND hwnd;
|
|
ULONG selectionIndex;
|
|
WCHAR buffer[100];
|
|
ULONG currentRegion;
|
|
BOOL status;
|
|
|
|
//
|
|
// new region code
|
|
//
|
|
hwnd = GetDlgItem(hDlg, IDC_DVD_COUNTRY_LIST);
|
|
//
|
|
// NOTE: SendMessage() will return 64-bit result in Sundown
|
|
//
|
|
selectionIndex = (ULONG) SendMessage(hwnd,
|
|
LB_GETCURSEL,
|
|
(WPARAM) 0,
|
|
(LPARAM) 0);
|
|
|
|
if (selectionIndex != LB_ERR) {
|
|
|
|
if (LB_ERR != SendMessage(hwnd,
|
|
LB_GETTEXT,
|
|
selectionIndex,
|
|
(LPARAM) buffer)) {
|
|
|
|
ppi->newRegion = DvdCountryToRegion (buffer);
|
|
if (ppi->newRegion != -1) {
|
|
|
|
if (LoadString(ModuleInstance,
|
|
DVD_REGION1_NAME + ppi->newRegion - 1,
|
|
buffer,
|
|
100)) {
|
|
|
|
hwnd = GetDlgItem(hDlg, IDC_NEW_REGION);
|
|
SendMessage(hwnd,
|
|
WM_SETTEXT,
|
|
0,
|
|
(LPARAM) buffer);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ULONG
|
|
DvdCountryToRegion (LPCTSTR Country)
|
|
{
|
|
ULONG i;
|
|
ULONG j;
|
|
WCHAR buffer[100];
|
|
|
|
for (i=0; i<MAX_REGIONS; i++) {
|
|
|
|
for (j=0; j<RegionSizeTable[i]; j++) {
|
|
|
|
if (LoadString(ModuleInstance,
|
|
RegionIndexTable[i] + j,
|
|
buffer,
|
|
100)) {
|
|
|
|
if (!wcscmp(buffer, Country)) {
|
|
|
|
return i + 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
BOOL
|
|
GetCurrentRpcData(
|
|
PPAGE_INFO ppi,
|
|
PDVD_REGION regionData
|
|
)
|
|
{
|
|
BOOL status;
|
|
ULONG returned;
|
|
UCHAR regionMask;
|
|
UCHAR userResetsAvailable;
|
|
HANDLE deviceHandle;
|
|
PDVD_COPY_PROTECT_KEY copyProtectKey;
|
|
PDVD_RPC_KEY rpcKey;
|
|
ULONG rpcScheme;
|
|
|
|
deviceHandle = UtilpGetDeviceHandle(ppi->deviceInfoSet,
|
|
ppi->deviceInfoData,
|
|
(LPGUID)&CdRomClassGuid,
|
|
GENERIC_READ);
|
|
|
|
if (deviceHandle == INVALID_HANDLE_VALUE) {
|
|
return FALSE;
|
|
}
|
|
|
|
copyProtectKey = LocalAlloc(LPTR, DVD_RPC_KEY_LENGTH);
|
|
|
|
if (copyProtectKey == NULL) {
|
|
CloseHandle(deviceHandle);
|
|
return FALSE;
|
|
}
|
|
|
|
copyProtectKey->KeyLength = DVD_RPC_KEY_LENGTH;
|
|
copyProtectKey->KeyType = DvdGetRpcKey;
|
|
|
|
returned = 0;
|
|
status = DeviceIoControl(deviceHandle,
|
|
IOCTL_DVD_READ_KEY,
|
|
copyProtectKey,
|
|
DVD_RPC_KEY_LENGTH,
|
|
copyProtectKey,
|
|
DVD_RPC_KEY_LENGTH,
|
|
&returned,
|
|
FALSE);
|
|
|
|
//
|
|
// this will default to not showing the property page
|
|
//
|
|
|
|
rpcScheme = 0;
|
|
|
|
if (status && (returned == DVD_RPC_KEY_LENGTH)) {
|
|
|
|
rpcKey = (PDVD_RPC_KEY) copyProtectKey->KeyData;
|
|
rpcScheme = rpcKey->RpcScheme;
|
|
regionMask = ~rpcKey->RegionMask;
|
|
userResetsAvailable = rpcKey->UserResetsAvailable;
|
|
DebugPrint((1, "Got %x user resets available\n", userResetsAvailable));
|
|
|
|
} else {
|
|
|
|
DebugPrint((1, "Maybe not a DVD drive?\n", status, returned));
|
|
|
|
}
|
|
|
|
LocalFree(copyProtectKey);
|
|
|
|
if (rpcScheme == 0) {
|
|
|
|
//
|
|
// all region drive. no need to show the property sheet
|
|
//
|
|
|
|
DebugPrint((1, "All Region DVD-ROM Drive -- no property sheet\n"));
|
|
CloseHandle(deviceHandle);
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
//
|
|
// get region status
|
|
//
|
|
|
|
memset(regionData, 0, sizeof(DVD_REGION));
|
|
status = DeviceIoControl(deviceHandle,
|
|
IOCTL_DVD_GET_REGION,
|
|
NULL,
|
|
0,
|
|
regionData,
|
|
sizeof(DVD_REGION),
|
|
&returned,
|
|
FALSE);
|
|
|
|
if (!(status && (returned == sizeof(DVD_REGION)))) {
|
|
|
|
//
|
|
// no media in the drive
|
|
//
|
|
DebugPrint((1, "No media in drive? making up info\n"));
|
|
regionData->CopySystem = 1;
|
|
regionData->RegionData = 0xff;
|
|
regionData->SystemRegion = regionMask;
|
|
regionData->ResetCount = userResetsAvailable;
|
|
|
|
}
|
|
|
|
CloseHandle(deviceHandle);
|
|
return TRUE;
|
|
}
|
|
|
|
ULONG
|
|
DvdRegionMaskToRegionNumber (
|
|
UCHAR PlayMask
|
|
)
|
|
{
|
|
ULONG i;
|
|
ULONG mask;
|
|
|
|
if (!PlayMask) {
|
|
|
|
return 0;
|
|
}
|
|
|
|
for (i=0, mask=1; i<8; i++, mask <<= 1) {
|
|
|
|
if (PlayMask & mask) {
|
|
|
|
return i + 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void
|
|
DvdUpdateCurrentSettings (PPAGE_INFO ppi,
|
|
HWND hDlg)
|
|
{
|
|
HWND hwnd;
|
|
ULONG selectionIndex;
|
|
WCHAR buffer[100];
|
|
WCHAR formatBuffer[100];
|
|
BOOL status;
|
|
|
|
ppi->currentRegion = DvdRegionMaskToRegionNumber (
|
|
ppi->regionData.SystemRegion
|
|
);
|
|
|
|
//
|
|
// current region
|
|
//
|
|
if (ppi->currentRegion) {
|
|
|
|
status = LoadString(ModuleInstance,
|
|
DVD_REGION1_NAME + ppi->currentRegion - 1,
|
|
buffer,
|
|
100);
|
|
} else {
|
|
|
|
status = LoadString(ModuleInstance,
|
|
DVD_NOREGION_NAME,
|
|
buffer,
|
|
100);
|
|
}
|
|
|
|
if (status) {
|
|
|
|
hwnd = GetDlgItem(hDlg, IDC_CURRENT_REGION);
|
|
SendMessage(hwnd,
|
|
WM_SETTEXT,
|
|
0,
|
|
(LPARAM) buffer);
|
|
}
|
|
|
|
//
|
|
// region change limit
|
|
//
|
|
if (LoadString(ModuleInstance,
|
|
DVD_CHANGE_TEXT,
|
|
formatBuffer,
|
|
100)) {
|
|
|
|
wsprintf (buffer, formatBuffer, (ULONG) ppi->regionData.ResetCount);
|
|
|
|
hwnd = GetDlgItem(hDlg, IDC_CHANGE_TEXT);
|
|
SendMessage(hwnd,
|
|
WM_SETTEXT,
|
|
0,
|
|
(LPARAM) buffer);
|
|
}
|
|
|
|
if (ppi->regionData.ResetCount == 0) {
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DVD_COUNTRY_LIST), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_NEW_REGION), FALSE);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// SystemLocale2DvdRegion expects
|
|
// this list to be sorted by LCID numbers
|
|
//
|
|
// Note: Due to PoliCheck, comments with
|
|
// approximated region/country names
|
|
// had to be removed.
|
|
//
|
|
LCID_2_DVD_TABLE Lcid2DvdTable[] = {
|
|
{0x0401, 2},
|
|
{0x0402, 2},
|
|
{0x0403, 2},
|
|
{0x0404, 3},
|
|
{0x0405, 2},
|
|
{0x0406, 2},
|
|
{0x0407, 2},
|
|
{0x0408, 2},
|
|
{0x0409, 1},
|
|
{0x040a, 2},
|
|
{0x040b, 2},
|
|
{0x040c, 2},
|
|
{0x040d, 2},
|
|
{0x040e, 2},
|
|
{0x040f, 2},
|
|
{0x0410, 2},
|
|
{0x0411, 2},
|
|
{0x0412, 3},
|
|
{0x0413, 2},
|
|
{0x0414, 2},
|
|
{0x0415, 2},
|
|
{0x0416, 4},
|
|
{0x0418, 2},
|
|
{0x0419, 5},
|
|
{0x041a, 2},
|
|
{0x041b, 2},
|
|
{0x041c, 2},
|
|
{0x041d, 2},
|
|
{0x041e, 3},
|
|
{0x041f, 2},
|
|
{0x0420, 5},
|
|
{0x0421, 3},
|
|
{0x0422, 5},
|
|
{0x0423, 5},
|
|
{0x0424, 2},
|
|
{0x0425, 5},
|
|
{0x0426, 5},
|
|
{0x0427, 5},
|
|
{0x0429, 2},
|
|
{0x042a, 3},
|
|
{0x042b, 5},
|
|
{0x042c, 5},
|
|
{0x042d, 2},
|
|
{0x042f, 2},
|
|
{0x0436, 2},
|
|
{0x0437, 5},
|
|
{0x0438, 2},
|
|
{0x0439, 5},
|
|
{0x043e, 3},
|
|
{0x043f, 5},
|
|
{0x0441, 5},
|
|
{0x0443, 5},
|
|
{0x0444, 5},
|
|
{0x0445, 5},
|
|
{0x0446, 5},
|
|
{0x0447, 5},
|
|
{0x0448, 5},
|
|
{0x0449, 5},
|
|
{0x044a, 5},
|
|
{0x044b, 5},
|
|
{0x044c, 5},
|
|
{0x044d, 5},
|
|
{0x044e, 5},
|
|
{0x044f, 5},
|
|
{0x0457, 5},
|
|
{0x0801, 2},
|
|
{0x0804, 6},
|
|
{0x0807, 2},
|
|
{0x0809, 2},
|
|
{0x080a, 4},
|
|
{0x080c, 2},
|
|
{0x0810, 2},
|
|
{0x0813, 2},
|
|
{0x0814, 2},
|
|
{0x0816, 2},
|
|
{0x081a, 2},
|
|
{0x081d, 2},
|
|
{0x0827, 5},
|
|
{0x082c, 5},
|
|
{0x083e, 3},
|
|
{0x0843, 5},
|
|
{0x0861, 5},
|
|
{0x0c01, 2},
|
|
{0x0c04, 3},
|
|
{0x0c07, 2},
|
|
{0x0c09, 4},
|
|
{0x0c0a, 2},
|
|
{0x0c0c, 1},
|
|
{0x0c1a, 2},
|
|
{0x1001, 5},
|
|
{0x1004, 3},
|
|
{0x1007, 2},
|
|
{0x1009, 1},
|
|
{0x100a, 4},
|
|
{0x100c, 2},
|
|
{0x1401, 5},
|
|
{0x1404, 3},
|
|
{0x1407, 2},
|
|
{0x1409, 4},
|
|
{0x140a, 4},
|
|
{0x140c, 2},
|
|
{0x1801, 5},
|
|
{0x1809, 2},
|
|
{0x180a, 4},
|
|
{0x180c, 2},
|
|
{0x1c01, 5},
|
|
{0x1c09, 2},
|
|
{0x1c0a, 4},
|
|
{0x2001, 2},
|
|
{0x2009, 4},
|
|
{0x200a, 4},
|
|
{0x2401, 2},
|
|
{0x2409, 4},
|
|
{0x240a, 4},
|
|
{0x2801, 2},
|
|
{0x2809, 4},
|
|
{0x280a, 4},
|
|
{0x2c01, 2},
|
|
{0x2c09, 4},
|
|
{0x2c0a, 4},
|
|
{0x3001, 2},
|
|
{0x3009, 5},
|
|
{0x300a, 4},
|
|
{0x3401, 2},
|
|
{0x3409, 3},
|
|
{0x340a, 4},
|
|
{0x3801, 2},
|
|
{0x380a, 4},
|
|
{0x3c01, 2},
|
|
{0x3c0a, 4},
|
|
{0x4001, 2},
|
|
{0x400a, 4},
|
|
{0x440a, 4},
|
|
{0x480a, 4},
|
|
{0x4c0a, 4},
|
|
{0x500a, 1}
|
|
};
|
|
#define NUM_LCID_ENTRIES (sizeof(Lcid2DvdTable)/sizeof(LCID_2_DVD_TABLE))
|
|
|
|
|
|
DWORD
|
|
SystemLocale2DvdRegion (
|
|
LCID Lcid
|
|
)
|
|
{
|
|
#define MID_INDEX(x,y) (((y-x)/2) + x)
|
|
|
|
DWORD i;
|
|
DWORD j;
|
|
DWORD k;
|
|
|
|
|
|
i=0;
|
|
j=NUM_LCID_ENTRIES;
|
|
|
|
while (1) {
|
|
|
|
k = MID_INDEX(i,j);
|
|
|
|
if (Lcid2DvdTable[k].Lcid != Lcid) {
|
|
|
|
if (i == j) {
|
|
|
|
//
|
|
// not in the table,
|
|
// return a default region of ZERO!!!
|
|
//
|
|
return 0;
|
|
}
|
|
|
|
if (Lcid2DvdTable[k].Lcid < Lcid) {
|
|
|
|
i = k;
|
|
|
|
} else { // Lcid2DvdTable[k].Lcid > Lcid
|
|
|
|
j = k;
|
|
}
|
|
|
|
} else {
|
|
|
|
return Lcid2DvdTable[k].DvdRegion;
|
|
}
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
DvdClassInstaller(
|
|
IN DI_FUNCTION InstallFunction,
|
|
IN HDEVINFO DeviceInfoSet,
|
|
IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine acts as the class installer for hard disk controllers
|
|
(IDE controllers/channels). It provides special handling for the
|
|
following DeviceInstaller function codes:
|
|
|
|
DIF_INSTALLDEVICE - get the system locale and write it to the driver key
|
|
|
|
Arguments:
|
|
|
|
InstallFunction - Specifies the device installer function code indicating
|
|
the action being performed.
|
|
|
|
DeviceInfoSet - Supplies a handle to the device information set being
|
|
acted upon by this install action.
|
|
|
|
DeviceInfoData - Optionally, supplies the address of a device information
|
|
element being acted upon by this install action.
|
|
|
|
Return Value:
|
|
|
|
If this function successfully completed the requested action, the return
|
|
value is NO_ERROR.
|
|
|
|
If the default behavior is to be performed for the requested action, the
|
|
return value is ERROR_DI_DO_DEFAULT.
|
|
|
|
If an error occurred while attempting to perform the requested action, a
|
|
Win32 error code is returned.
|
|
|
|
--*/
|
|
|
|
{
|
|
switch(InstallFunction) {
|
|
|
|
case DIF_ADDPROPERTYPAGE_ADVANCED:
|
|
case DIF_ADDREMOTEPROPERTYPAGE_ADVANCED:
|
|
{
|
|
//
|
|
// get the current class install parameters for the device
|
|
//
|
|
SP_ADDPROPERTYPAGE_DATA AddPropertyPageData;
|
|
|
|
//
|
|
// DeviceInfoSet is NULL if setup is requesting property pages for
|
|
// the device setup class. We don't want to do anything in this
|
|
// case.
|
|
//
|
|
if (DeviceInfoData==NULL)
|
|
return ERROR_DI_DO_DEFAULT;
|
|
|
|
ZeroMemory(&AddPropertyPageData, sizeof(SP_ADDPROPERTYPAGE_DATA));
|
|
AddPropertyPageData.ClassInstallHeader.cbSize =
|
|
sizeof(SP_CLASSINSTALL_HEADER);
|
|
|
|
if (SetupDiGetClassInstallParams(DeviceInfoSet, DeviceInfoData,
|
|
(PSP_CLASSINSTALL_HEADER)&AddPropertyPageData,
|
|
sizeof(SP_ADDPROPERTYPAGE_DATA), NULL ))
|
|
{
|
|
PVOLUME_PAGE_DATA pVolumePageData;
|
|
HPROPSHEETPAGE pageHandle;
|
|
PROPSHEETPAGE page;
|
|
|
|
//
|
|
// Ensure that the maximum number of dynamic pages for the
|
|
// device has not yet been met
|
|
//
|
|
if (AddPropertyPageData.NumDynamicPages >=
|
|
MAX_INSTALLWIZARD_DYNAPAGES)
|
|
return NO_ERROR;
|
|
|
|
if (IsUserAdmin())
|
|
pVolumePageData = HeapAlloc(GetProcessHeap(), 0,
|
|
sizeof(VOLUME_PAGE_DATA));
|
|
else
|
|
pVolumePageData = NULL;
|
|
|
|
if (pVolumePageData)
|
|
{
|
|
HMODULE LdmModule;
|
|
SP_DEVINFO_LIST_DETAIL_DATA DeviceInfoSetDetailData;
|
|
//
|
|
// Save DeviceInfoSet and DeviceInfoData
|
|
//
|
|
pVolumePageData->DeviceInfoSet = DeviceInfoSet;
|
|
pVolumePageData->DeviceInfoData = DeviceInfoData;
|
|
|
|
//
|
|
// Create volume property sheet page
|
|
//
|
|
memset(&page, 0, sizeof(PROPSHEETPAGE));
|
|
|
|
page.dwSize = sizeof(PROPSHEETPAGE);
|
|
page.dwFlags = PSP_USECALLBACK;
|
|
page.hInstance = ModuleInstance;
|
|
page.pszTemplate = MAKEINTRESOURCE(ID_VOLUME_PROPPAGE);
|
|
page.pfnDlgProc = VolumeDialogProc;
|
|
page.pfnCallback = VolumeDialogCallback;
|
|
|
|
page.lParam = (LPARAM) pVolumePageData;
|
|
|
|
pageHandle = CreatePropertySheetPage(&page);
|
|
if(!pageHandle)
|
|
{
|
|
HeapFree(GetProcessHeap(), 0, pVolumePageData);
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// Add the new page to the list of dynamic property
|
|
// sheets
|
|
//
|
|
AddPropertyPageData.DynamicPages[
|
|
AddPropertyPageData.NumDynamicPages++]=pageHandle;
|
|
|
|
//
|
|
// Check if the property page is pulled up from disk manager.
|
|
//
|
|
pVolumePageData->bInvokedByDiskmgr = FALSE;
|
|
LdmModule = GetModuleHandle(TEXT("dmdskmgr"));
|
|
if ( LdmModule )
|
|
{
|
|
IS_REQUEST_PENDING pfnIsRequestPending;
|
|
pfnIsRequestPending = (IS_REQUEST_PENDING)
|
|
GetProcAddress(LdmModule, "IsRequestPending");
|
|
if (pfnIsRequestPending)
|
|
{
|
|
if ((*pfnIsRequestPending)())
|
|
pVolumePageData->bInvokedByDiskmgr = TRUE;
|
|
}
|
|
}
|
|
|
|
SetupDiSetClassInstallParams(DeviceInfoSet,DeviceInfoData,
|
|
(PSP_CLASSINSTALL_HEADER)&AddPropertyPageData,
|
|
sizeof(SP_ADDPROPERTYPAGE_DATA));
|
|
}
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
|
|
case DIF_INSTALLDEVICE : {
|
|
|
|
HKEY hKey;
|
|
DWORD dvdRegion;
|
|
|
|
hKey = SetupDiOpenDevRegKey (DeviceInfoSet,
|
|
DeviceInfoData,
|
|
DICS_FLAG_GLOBAL,
|
|
0,
|
|
DIREG_DEV,
|
|
KEY_READ | KEY_WRITE);
|
|
if (hKey != INVALID_HANDLE_VALUE) {
|
|
|
|
dvdRegion = SystemLocale2DvdRegion (GetSystemDefaultLCID());
|
|
|
|
RegSetValueEx (hKey,
|
|
TEXT("DefaultDvdRegion"),
|
|
0,
|
|
REG_DWORD,
|
|
(PUCHAR) &dvdRegion,
|
|
sizeof(dvdRegion)
|
|
);
|
|
|
|
RegCloseKey (hKey);
|
|
}
|
|
}
|
|
//
|
|
// fall through
|
|
//
|
|
|
|
default :
|
|
//
|
|
// Just do the default action.
|
|
//
|
|
return ERROR_DI_DO_DEFAULT;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
DvdContextMenu(
|
|
HWND HwndControl,
|
|
WORD Xpos,
|
|
WORD Ypos
|
|
)
|
|
{
|
|
WinHelp(HwndControl,
|
|
_T("devmgr.hlp"),
|
|
HELP_CONTEXTMENU,
|
|
(ULONG_PTR) DvdHelpIDs);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
DvdHelp(
|
|
HWND ParentHwnd,
|
|
LPHELPINFO HelpInfo
|
|
)
|
|
{
|
|
if (HelpInfo->iContextType == HELPINFO_WINDOW) {
|
|
WinHelp((HWND) HelpInfo->hItemHandle,
|
|
_T("devmgr.hlp"),
|
|
HELP_WM_HELP,
|
|
(ULONG_PTR) DvdHelpIDs);
|
|
}
|
|
}
|