windows-nt/Source/XPSP1/NT/drivers/storage/proppage/ideprop.c
2020-09-26 16:20:57 +08:00

852 lines
22 KiB
C

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: ideprop.c
//
//--------------------------------------------------------------------------
#include "propp.h"
#include "ideprop.h"
#include "resource.h"
#include "xpsp1res.h"
const TCHAR *szDeviceType[] = {
MASTER_DEVICE_TYPE_REG_KEY,
SLAVE_DEVICE_TYPE_REG_KEY
};
const TCHAR *szUserDeviceType[] = {
USER_MASTER_DEVICE_TYPE_REG_KEY,
USER_SLAVE_DEVICE_TYPE_REG_KEY
};
const TCHAR *szCurrentTransferMode[] = {
MASTER_DEVICE_TIMING_MODE,
SLAVE_DEVICE_TIMING_MODE
};
const TCHAR *szTransferModeAllowed[] = {
USER_MASTER_DEVICE_TIMING_MODE_ALLOWED,
USER_SLAVE_DEVICE_TIMING_MODE_ALLOWED
};
//
// Help ID mapping for context sensitive help
//
const DWORD IdeHelpIDs[]=
{
IDC_MASTER_DEVICE_TYPE, IDH_DEVMGR_IDE_MASTER_DEVICE_TYPE,
IDC_MASTER_XFER_MODE, IDH_DEVMGR_IDE_MASTER_XFER_MODE,
IDC_MASTER_CURRENT_XFER_MODE, IDH_DEVMGR_IDE_MASTER_CURRENT_XFER_MODE,
IDC_SLAVE_DEVICE_TYPE, IDH_DEVMGR_IDE_SLAVE_DEVICE_TYPE,
IDC_SLAVE_XFER_MODE, IDH_DEVMGR_IDE_SLAVE_XFER_MODE,
IDC_SLAVE_CURRENT_XFER_MODE, IDH_DEVMGR_IDE_SLAVE_CURRENT_XFER_MODE,
0,0
};
PPAGE_INFO IdeCreatePageInfo(IN HDEVINFO deviceInfoSet,
IN PSP_DEVINFO_DATA deviceInfoData)
{
PPAGE_INFO tmp = NULL;
if (!(tmp = LocalAlloc(LPTR, sizeof(PAGE_INFO)))) {
return NULL;
}
tmp->deviceInfoSet = deviceInfoSet;
tmp->deviceInfoData = deviceInfoData;
tmp->hKeyDev =
SetupDiCreateDevRegKey(deviceInfoSet,
deviceInfoData,
DICS_FLAG_GLOBAL,
0,
DIREG_DRV,
NULL,
NULL);
return tmp;
}
void
IdeDestroyPageInfo(PPAGE_INFO * ppPageInfo)
{
PPAGE_INFO ppi = *ppPageInfo;
if (ppi->hKeyDev != (HKEY) INVALID_HANDLE_VALUE) {
RegCloseKey(ppi->hKeyDev);
}
LocalFree(ppi);
*ppPageInfo = NULL;
}
HPROPSHEETPAGE
IdeCreatePropertyPage(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_IDE_PROPPAGE);
//
// following points to the dlg window proc
//
ppsp->pfnDlgProc = IdeDlgProc;
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 = IdeDlgCallback;
//
// Allocate the actual page
//
return CreatePropertySheetPage(ppsp);
}
BOOL APIENTRY
IdePropPageProvider(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 = IdeCreatePageInfo(ppr->DeviceInfoSet,
ppr->DeviceInfoData);
if (!ppi) {
return FALSE;
}
//
// If this fails, it is most likely that the user does not have
// write access to the devices key/subkeys in the registry.
// If you only want to read the settings, then change KEY_ALL_ACCESS
// to KEY_READ in CreatePageInfo.
//
// Administrators usually have access to these reg keys....
//
#if 0
if (ppi->hKeyDev == (HKEY) INVALID_HANDLE_VALUE) {
DWORD error = GetLastError();
IdeDestroyPageInfo(&ppi);
return FALSE;
}
#endif
hpsp = IdeCreatePropertyPage(&psp,
ppi);
if (!hpsp) {
return FALSE;
}
if (!pfnAdd(hpsp, lParam)) {
DestroyPropertySheetPage(hpsp);
return FALSE;
}
}
return TRUE;
}
UINT CALLBACK
IdeDlgCallback(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;
IdeDestroyPageInfo(&ppi);
return 0; // return value ignored
default:
break;
}
return TRUE;
}
void
IdeInitializeControls(PPAGE_INFO ppi,
HWND hDlg)
{
DWORD dwError,
dwType,
dwSize;
BOOL disableControls = FALSE;
HWND hwnd;
ULONG i;
ULONG j;
TCHAR buffer[50];
//
// defaults
for (i=0; i<2; i++) {
ppi->deviceType[i] = DeviceUnknown;
}
if (ppi->hKeyDev == (HKEY) INVALID_HANDLE_VALUE) {
//
// We weren't given write access, try to read the key and translate
// its value, but disable all of the controls
disableControls = TRUE;
ppi->hKeyDev =
SetupDiOpenDevRegKey(ppi->deviceInfoSet,
ppi->deviceInfoData,
DICS_FLAG_GLOBAL,
0, // current
DIREG_DRV,
KEY_READ);
}
if (ppi->hKeyDev != (HKEY) INVALID_HANDLE_VALUE) {
//
// get user choice device types
//
for (i=0; i<2; i++) {
//
// current device type
//
dwSize = sizeof(DWORD);
dwError = RegQueryValueEx(ppi->hKeyDev,
szDeviceType[i],
NULL,
&dwType,
(PBYTE) (ppi->currentDeviceType + i),
&dwSize);
if ((dwType != REG_DWORD) ||
(dwSize != sizeof(DWORD)) ||
(dwError != ERROR_SUCCESS)) {
ppi->currentDeviceType[i] = DeviceUnknown;
}
if (ppi->currentDeviceType[i] == DeviceNotExist) {
ppi->currentDeviceType[i] = DeviceUnknown;
}
//
// user choice device type
//
dwSize = sizeof(DWORD);
dwError = RegQueryValueEx(ppi->hKeyDev,
szUserDeviceType[i],
NULL,
&dwType,
(PBYTE) (ppi->deviceType + i),
&dwSize);
if ((dwType != REG_DWORD) ||
(dwSize != sizeof(DWORD)) ||
(dwError != ERROR_SUCCESS)) {
ppi->deviceType[i] = DeviceUnknown;
}
if (ppi->deviceType[i] != DeviceNotExist) {
ppi->deviceType[i] = DeviceUnknown;
}
//
// transfer mode allowed
//
dwSize = sizeof(DWORD);
ppi->transferModeAllowed[i] = 0xffffffff;
dwError = RegQueryValueEx(ppi->hKeyDev,
szTransferModeAllowed[i],
NULL,
&dwType,
(PBYTE) (ppi->transferModeAllowed + i),
&dwSize);
if ((dwType != REG_DWORD) ||
(dwSize != sizeof(DWORD)) ||
(dwError != ERROR_SUCCESS)) {
//
// default
//
ppi->transferModeAllowed[i] = 0xffffffff;
ppi->transferModeAllowedForAtapiDevice[i] = PIO_SUPPORT;
} else {
//
// user actually picked the xfer mode to use.
// set this atapi override value to -1 so
// that it won't affect the user selection
//
ppi->transferModeAllowedForAtapiDevice[i] = 0xffffffff;
}
//
// current transfer mode
//
dwSize = sizeof(DWORD);
dwError = RegQueryValueEx(ppi->hKeyDev,
szCurrentTransferMode[i],
NULL,
&dwType,
(PBYTE) (ppi->currentTransferMode + i),
&dwSize);
if ((dwType != REG_DWORD) ||
(dwSize != sizeof(DWORD)) ||
(dwError != ERROR_SUCCESS)) {
ppi->currentTransferMode[i] = 0;
}
if (ppi->deviceType[i] == DeviceNotExist) {
ppi->currentTransferMode[i] = 0;
}
}
//
// init drop lists
//
if (LoadString(ModuleInstance,
IDS_IDE_PIO_ONLY,
buffer,
50)) {
for (i=0; i<2; i++) {
hwnd = GetDlgItem(hDlg, IDC_MASTER_XFER_MODE + i);
SendMessage(hwnd,
CB_ADDSTRING,
0,
(LPARAM) buffer);
}
}
if (LoadString(ModuleInstance,
IDS_IDE_DMA,
buffer,
50)) {
for (i=0; i<2; i++) {
hwnd = GetDlgItem(hDlg, IDC_MASTER_XFER_MODE + i);
SendMessage(hwnd,
CB_ADDSTRING,
0,
(LPARAM) buffer);
}
}
if (LoadString(ModuleInstance,
IDS_IDE_AUTO_DETECT,
buffer,
50)) {
for (i=0; i<2; i++) {
hwnd = GetDlgItem(hDlg, IDC_MASTER_DEVICE_TYPE + i);
SendMessage(hwnd,
CB_ADDSTRING,
0,
(LPARAM) buffer);
}
}
if (LoadString(ModuleInstance,
IDS_IDE_NONE,
buffer,
50)) {
for (i=0; i<2; i++) {
hwnd = GetDlgItem(hDlg, IDC_MASTER_DEVICE_TYPE + i);
SendMessage(hwnd,
CB_ADDSTRING,
0,
(LPARAM) buffer);
}
}
IdeUpdate(ppi, hDlg);
}
if (disableControls) {
for (i=0; i<2; i++) {
EnableWindow(GetDlgItem(hDlg, IDC_MASTER_DEVICE_TYPE + i), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_MASTER_XFER_MODE + i), FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_MASTER_CURRENT_XFER_MODE + i), FALSE);
}
if (ppi->hKeyDev != (HKEY) INVALID_HANDLE_VALUE) {
RegCloseKey(ppi->hKeyDev);
ppi->hKeyDev = INVALID_HANDLE_VALUE;
}
}
}
void
IdeApplyChanges(PPAGE_INFO ppi,
HWND hDlg)
{
DMADETECTIONLEVEL newDmaDetectionLevel;
IDE_DEVICETYPE newDeviceType;
ULONG i;
BOOLEAN popupError = FALSE;
BOOLEAN changesMade = FALSE;
ULONG newXferMode;
if (ppi->hKeyDev == (HKEY) INVALID_HANDLE_VALUE) {
return;
}
//
// device type
//
for (i=0; i<2; i++) {
newDeviceType = (IDE_DEVICETYPE) SendDlgItemMessage(hDlg,
IDC_MASTER_DEVICE_TYPE + i,
CB_GETCURSEL,
(WPARAM) 0,
(LPARAM) 0);
if (newDeviceType == 1) {
newDeviceType = DeviceNotExist;
} else {
newDeviceType = DeviceUnknown;
}
if (ppi->deviceType[i] != newDeviceType) {
ppi->deviceType[i] = newDeviceType;
if (RegSetValueEx(ppi->hKeyDev,
szUserDeviceType[i],
0,
REG_DWORD,
(PBYTE) (ppi->deviceType + i),
sizeof(DWORD)) != ERROR_SUCCESS) {
popupError = TRUE;
} else {
changesMade = TRUE;
}
}
}
//
// transfer mode
//
for (i=0; i<2; i++) {
ULONG xferModeAllowed;
//
// NOTE: SendDlgItemMessage will send back 64-bit result in Sundown
//
newXferMode = (ULONG) SendDlgItemMessage(hDlg,
IDC_MASTER_XFER_MODE + i,
CB_GETCURSEL,
(WPARAM) 0,
(LPARAM) 0);
if (newXferMode == 0) {
newXferMode = PIO_SUPPORT;
} else {
newXferMode = 0xffffffff;
}
xferModeAllowed = ppi->transferModeAllowed[i];
if ((ppi->currentDeviceType[i] == DeviceIsAtapi) &&
(!(ppi->currentTransferMode[i] & ~PIO_SUPPORT))) {
//
// atapi override only if the current transfer mode is not DMA
// this is to take care of dvds and cdrws where we enable DMA
// by default.
//
xferModeAllowed &= ppi->transferModeAllowedForAtapiDevice[i];
}
if (newXferMode != xferModeAllowed) {
ppi->transferModeAllowed[i] = newXferMode;
if (RegSetValueEx(ppi->hKeyDev,
szTransferModeAllowed[i],
0,
REG_DWORD,
(PBYTE) (ppi->transferModeAllowed + i),
sizeof(DWORD)) != ERROR_SUCCESS) {
popupError = TRUE;
} else {
changesMade = TRUE;
}
}
}
if (popupError) {
TCHAR buf1[MAX_PATH+1];
TCHAR buf2[MAX_PATH+1];
RtlZeroMemory(buf1, sizeof(buf1));
RtlZeroMemory(buf2, sizeof(buf2));
LoadString(ModuleInstance, IDS_IDE_SAVE_ERROR, buf1, MAX_PATH);
LoadString(ModuleInstance, IDS_IDE_SAVE_ERROR, buf2, MAX_PATH);
MessageBox(hDlg, buf1, buf2, MB_OK);
}
if (changesMade) {
SP_DEVINSTALL_PARAMS devInstallParams;
devInstallParams.cbSize = sizeof (devInstallParams);
SetupDiGetDeviceInstallParams(ppi->deviceInfoSet,
ppi->deviceInfoData,
&devInstallParams
);
devInstallParams.Flags |= (DI_PROPERTIES_CHANGE);
SetupDiSetDeviceInstallParams(ppi->deviceInfoSet,
ppi->deviceInfoData,
&devInstallParams
);
CM_Reenumerate_DevNode_Ex( ppi->deviceInfoData->DevInst,
0,
NULL);
}
}
INT_PTR APIENTRY
IdeDlgProc(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
//
IdeInitializeControls(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);
return TRUE;
default:
break;
}
switch(LOWORD(wParam)) {
default:
break;
}
break;
case WM_CONTEXTMENU:
return IdeContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
case WM_HELP:
IdeHelp(hDlg, (LPHELPINFO) lParam);
break;
case WM_NOTIFY:
switch (((NMHDR *)lParam)->code) {
//
// Sent when the user clicks on Apply OR OK !!
//
case PSN_APPLY:
//
// Do what ever action is necessary
//
IdeApplyChanges(ppi,
hDlg);
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
return TRUE;
default:
break;
}
break;
}
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
return FALSE;
}
void
IdeUpdate (PPAGE_INFO ppi,
HWND hDlg)
{
ULONG i;
DWORD dwError,
dwType,
dwSize;
TCHAR buffer[50];
HMODULE hModule;
BOOLEAN bLibLoaded;
//
// set current values
//
for (i=0; i<2; i++) {
ULONG xferModeString;
ULONG xferModeAllowed;
hModule = ModuleInstance;
bLibLoaded = FALSE;
//
// current device type
//
SendDlgItemMessage(hDlg,
IDC_MASTER_DEVICE_TYPE + i,
CB_SETCURSEL,
ppi->deviceType[i] == DeviceNotExist? 1 : 0,
0L);
if (ppi->currentDeviceType[i] != DeviceUnknown) {
EnableWindow(GetDlgItem(hDlg, IDC_MASTER_DEVICE_TYPE + i), FALSE);
} else {
EnableWindow(GetDlgItem(hDlg, IDC_MASTER_DEVICE_TYPE + i), TRUE);
}
//
// select transfer mode
//
xferModeAllowed = ppi->transferModeAllowed[i];
if ((ppi->currentDeviceType[i] == DeviceIsAtapi) &&
(!(ppi->currentTransferMode[i] & ~PIO_SUPPORT))) {
//
// atapi override only if the current transfer mode is not DMA
// this is to take care of dvds and cdrws where we enable DMA
// by default.
//
xferModeAllowed &= ppi->transferModeAllowedForAtapiDevice[i];
}
if (xferModeAllowed & ~PIO_SUPPORT) {
SendDlgItemMessage(hDlg,
IDC_MASTER_XFER_MODE + i,
CB_SETCURSEL,
1,
0L);
} else {
SendDlgItemMessage(hDlg,
IDC_MASTER_XFER_MODE + i,
CB_SETCURSEL,
0,
0L);
}
//
// current transfer mode
//
if (ppi->currentTransferMode[i] & UDMA_SUPPORT) {
if (ppi->currentTransferMode[i] & UDMA_MODE6) {
hModule = LoadLibraryEx(_T("xpsp1res.dll"),
NULL,
LOAD_LIBRARY_AS_DATAFILE
);
if (hModule == NULL) {
hModule = ModuleInstance;
xferModeString = IDC_UDMA_MODE_STRING;
} else {
xferModeString = IDS_UDMA_MODE6_STRING;
bLibLoaded = TRUE;
}
} else if (ppi->currentTransferMode[i] & UDMA_MODE5) {
xferModeString = IDC_UDMA_MODE5_STRING;
} else if (ppi->currentTransferMode[i] & UDMA_MODE4) {
xferModeString = IDC_UDMA_MODE4_STRING;
} else if (ppi->currentTransferMode[i] & UDMA_MODE3) {
xferModeString = IDC_UDMA_MODE3_STRING;
} else if (ppi->currentTransferMode[i] & UDMA_MODE2) {
xferModeString = IDC_UDMA_MODE2_STRING;
} else if (ppi->currentTransferMode[i] & UDMA_MODE1) {
xferModeString = IDC_UDMA_MODE1_STRING;
} else if (ppi->currentTransferMode[i] & UDMA_MODE0) {
xferModeString = IDC_UDMA_MODE0_STRING;
} else {
xferModeString = IDC_UDMA_MODE_STRING;
}
} else if (ppi->currentTransferMode[i] & (MWDMA_SUPPORT | SWDMA_SUPPORT)) {
if (ppi->currentTransferMode[i] & MWDMA_MODE2) {
xferModeString = IDC_MWDMA_MODE2_STRING;
} else if (ppi->currentTransferMode[i] & MWDMA_MODE1) {
xferModeString = IDC_MWDMA_MODE1_STRING;
} else if (ppi->currentTransferMode[i] & SWDMA_MODE2) {
xferModeString = IDC_SWDMA_MODE2_STRING;
} else {
xferModeString = IDC_DMA_MODE_STRING;
}
} else if (ppi->currentTransferMode[i] & PIO_SUPPORT) {
xferModeString = IDC_PIO_MODE_STRING;
} else {
xferModeString = IDC_NO_MODE_STRING;
}
if (LoadString(hModule,
xferModeString,
buffer,
50)) {
SendDlgItemMessage(hDlg,
IDC_MASTER_CURRENT_XFER_MODE + i,
WM_SETTEXT,
0,
(LPARAM) buffer);
}
if (bLibLoaded) {
FreeLibrary(hModule);
hModule = ModuleInstance;
bLibLoaded = FALSE;
}
}
}
BOOL
IdeContextMenu(
HWND HwndControl,
WORD Xpos,
WORD Ypos
)
{
WinHelp(HwndControl,
_T("devmgr.hlp"),
HELP_CONTEXTMENU,
(ULONG_PTR) IdeHelpIDs);
return FALSE;
}
void
IdeHelp(
HWND ParentHwnd,
LPHELPINFO HelpInfo
)
{
if (HelpInfo->iContextType == HELPINFO_WINDOW) {
WinHelp((HWND) HelpInfo->hItemHandle,
_T("devmgr.hlp"),
HELP_WM_HELP,
(ULONG_PTR) IdeHelpIDs);
}
}