Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1589 lines
47 KiB

/*----------------------------------------------------------------------
file: pp.c - property page
----------------------------------------------------------------------*/
#include "cyyports.h"
#include "pp.h"
#include <htmlhelp.h>
#include <windowsx.h>
//TCHAR m_szDevMgrHelp[] = _T("devmgr.hlp");
TCHAR m_szCyycoinsHelp[] = _T("cyycoins.chm");
TCHAR y_szNumOfPorts[] = TEXT("NumOfPorts");
const DWORD HelpIDs[]=
{
IDC_STATIC, IDH_CYYCOINS_NOHELP,
IDC_STATIC_BOARD_DETAILS, IDH_CYYCOINS_NOHELP,
IDC_STATIC_SETTINGS, IDH_CYYCOINS_NOHELP,
IDC_NUM_PORTS, IDH_CYYCOINS_NUM_PORTS,
PP_NUM_PORTS, IDH_CYYCOINS_NUM_PORTS,
IDC_START_COM, IDH_CYYCOINS_START_COM,
PP_START_COM, IDH_CYYCOINS_START_COM,
IDC_RESTORE_DEFAULTS, IDH_CYYCOINS_RESTORE_DEFAULTS,
IDC_BUS_TYPE, IDH_CYYCOINS_BUS_TYPE,
PP_BUS_TYPE, IDH_CYYCOINS_BUS_TYPE,
IDC_CONFIGURATION, IDH_CYYCOINS_CONFIGURATION,
PP_CONFIGURATION, IDH_CYYCOINS_CONFIGURATION,
IDC_MODEL, IDH_CYYCOINS_MODEL,
PP_MODEL, IDH_CYYCOINS_MODEL,
0, 0
};
void InitPortParams(
IN OUT PPORT_PARAMS Params,
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData
)
{
SP_DEVINFO_LIST_DETAIL_DATA detailData;
HCOMDB hComDB;
DWORD maxPortsReported;
//DbgOut(TEXT("InitPortParams\n"));
ZeroMemory(Params, sizeof(PORT_PARAMS));
Params->DeviceInfoSet = DeviceInfoSet;
Params->DeviceInfoData = DeviceInfoData;
// Allocate and initialize PortUsage matrix
ComDBOpen(&hComDB);
if (hComDB != INVALID_HANDLE_VALUE) {
ComDBGetCurrentPortUsage(hComDB,
NULL,
0,
CDB_REPORT_BYTES,
&maxPortsReported);
//#if DBG
//{
// TCHAR buf[500];
// wsprintf(buf, TEXT("maxPortsReported %d\n"),maxPortsReported);
// DbgOut(buf);
//}
//#endif
if (maxPortsReported != 0) {
Params->ShowStartCom = TRUE;
//Params->PortUsage = (PBYTE) LocalAlloc(LPTR,maxPortsReported/8);
if (maxPortsReported > MAX_COM_PORT) {
Params->PortUsageSize = maxPortsReported;
} else {
Params->PortUsageSize = MAX_COM_PORT;
}
Params->PortUsage = (PBYTE) LocalAlloc(LPTR,Params->PortUsageSize/8);
if (Params->PortUsage != NULL) {
Params->PortUsageSize = maxPortsReported/8;
ComDBGetCurrentPortUsage(hComDB,
Params->PortUsage,
Params->PortUsageSize,
CDB_REPORT_BITS,
&maxPortsReported
);
}
}
ComDBClose(hComDB);
} else {
// This happens if we don't have sufficient security privileges.
// GetLastError returns 0 here!!! Some bug in ComDBOpen.
DbgOut(TEXT("cyycoins ComDBOpen failed.\n"));
}
//
// See if we are being invoked locally or over the network. If over the net,
// then disable all possible changes.
//
detailData.cbSize = sizeof(SP_DEVINFO_LIST_DETAIL_DATA);
if (SetupDiGetDeviceInfoListDetail(DeviceInfoSet, &detailData) &&
detailData.RemoteMachineHandle != NULL) {
Params->ShowStartCom = FALSE;
}
}
HPROPSHEETPAGE InitSettingsPage(PROPSHEETPAGE * psp,
OUT PPORT_PARAMS Params)
{
//
// Add the Port Settings property page
//
psp->dwSize = sizeof(PROPSHEETPAGE);
psp->dwFlags = PSP_USECALLBACK; // | PSP_HASHELP;
psp->hInstance = g_hInst;
psp->pszTemplate = MAKEINTRESOURCE(DLG_PP_PORTSETTINGS);
//
// following points to the dlg window proc
//
psp->pfnDlgProc = PortSettingsDlgProc;
psp->lParam = (LPARAM) Params;
//
// following points to some control callback of the dlg window proc
//
psp->pfnCallback = PortSettingsDlgCallback;
//
// allocate our "Ports Setting" sheet
//
return CreatePropertySheetPage(psp);
}
/*++
Routine Description: CyclomyPropPageProvider
Entry-point for adding additional device manager property
sheet pages. Registry specifies this routine under
Control\Class\PortNode::EnumPropPage32="msports.dll,thisproc"
entry. This entry-point gets called only when the Device
Manager asks for additional property pages.
Arguments:
Info - points to PROPSHEETPAGE_REQUEST, see setupapi.h
AddFunc - function ptr to call to add sheet.
Lparam - add sheet functions private data handle.
Return Value:
BOOL: FALSE if pages could not be added, TRUE on success
--*/
BOOL APIENTRY CyclomyPropPageProvider(LPVOID Info,
LPFNADDPROPSHEETPAGE AddFunc,
LPARAM Lparam
)
{
PSP_PROPSHEETPAGE_REQUEST pprPropPageRequest;
PROPSHEETPAGE psp;
HPROPSHEETPAGE hpsp;
PPORT_PARAMS params = NULL;
//DbgOut(TEXT("cyycoins CyclomyPropPageProvider entry\n"));
pprPropPageRequest = (PSP_PROPSHEETPAGE_REQUEST) Info;
//
// Allocate and zero out memory for the struct that will contain
// page specific data
//
params = (PPORT_PARAMS) LocalAlloc(LPTR, sizeof(PORT_PARAMS));
//******************************************************************
// TEST ERROR
// if (params)
// LocalFree(params);
// params = NULL;
//
//******************************************************************
if (!params) {
ErrMemDlg(GetFocus());
return FALSE;
}
if (pprPropPageRequest->PageRequested == SPPSR_ENUM_ADV_DEVICE_PROPERTIES) {
InitPortParams(params,
pprPropPageRequest->DeviceInfoSet,
pprPropPageRequest->DeviceInfoData);
hpsp = InitSettingsPage(&psp, params);
if (!hpsp) {
return FALSE;
}
if (!(*AddFunc)(hpsp, Lparam)) {
DestroyPropertySheetPage(hpsp);
return FALSE;
}
}
return TRUE;
} /* CyclomyPropPageProvider */
UINT CALLBACK
PortSettingsDlgCallback(HWND hwnd,
UINT uMsg,
LPPROPSHEETPAGE ppsp)
{
PPORT_PARAMS params;
switch (uMsg) {
case PSPCB_CREATE:
return TRUE; // return TRUE to continue with creation of page
case PSPCB_RELEASE:
//DbgOut(TEXT("PortSettingsDlgCallBack PSPCB_RELEASE\n"));
params = (PPORT_PARAMS) ppsp->lParam;
if (params->PortUsage) {
LocalFree(params->PortUsage);
}
LocalFree(params);
return 0; // return value ignored
default:
break;
}
return TRUE;
}
void
Port_OnCommand(
HWND DialogHwnd,
int ControlId,
HWND ControlHwnd,
UINT NotifyCode
);
BOOL
Port_OnContextMenu(
HWND HwndControl,
WORD Xpos,
WORD Ypos
);
void
Port_OnHelp(
HWND DialogHwnd,
LPHELPINFO HelpInfo
);
BOOL
Port_OnInitDialog(
HWND DialogHwnd,
HWND FocusHwnd,
LPARAM Lparam
);
BOOL
Port_OnNotify(
HWND DialogHwnd,
LPNMHDR NmHdr
);
/*++
Routine Description: PortSettingsDlgProc
The windows control function for the Port Settings properties window
Arguments:
hDlg, uMessage, wParam, lParam: standard windows DlgProc parameters
Return Value:
BOOL: FALSE if function fails, TRUE if function passes
--*/
INT_PTR APIENTRY
PortSettingsDlgProc(IN HWND hDlg,
IN UINT uMessage,
IN WPARAM wParam,
IN LPARAM lParam)
{
switch(uMessage) {
case WM_COMMAND:
Port_OnCommand(hDlg, (int) LOWORD(wParam), (HWND)lParam, (UINT)HIWORD(wParam));
break;
case WM_CONTEXTMENU:
return Port_OnContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
case WM_HELP:
Port_OnHelp(hDlg, (LPHELPINFO) lParam);
break;
case WM_INITDIALOG:
return Port_OnInitDialog(hDlg, (HWND)wParam, lParam);
case WM_NOTIFY:
return Port_OnNotify(hDlg, (NMHDR *)lParam);
}
return FALSE;
} /* PortSettingsDialogProc */
void
Port_OnRestoreDefaultsClicked(
HWND DialogHwnd,
PPORT_PARAMS Params
)
{
RestoreDefaults(DialogHwnd, Params);
PropSheet_Changed(GetParent(DialogHwnd), DialogHwnd);
}
void
Port_OnCommand(
HWND DialogHwnd,
int ControlId,
HWND ControlHwnd,
UINT NotifyCode
)
{
PPORT_PARAMS params = (PPORT_PARAMS)GetWindowLongPtr(DialogHwnd, DWLP_USER);
if (NotifyCode == CBN_SELCHANGE) {
PropSheet_Changed(GetParent(DialogHwnd), DialogHwnd);
}
else {
switch (ControlId) {
//case IDC_ADVANCED:
// Port_OnAdvancedClicked(DialogHwnd, params);
// break;
//
case IDC_RESTORE_DEFAULTS:
Port_OnRestoreDefaultsClicked(DialogHwnd, params);
break;
//
// Because this is a prop sheet, we should never get this.
// All notifications for ctrols outside of the sheet come through
// WM_NOTIFY
//
case IDCANCEL:
EndDialog(DialogHwnd, 0);
return;
}
}
}
BOOL
Port_OnContextMenu(
HWND HwndControl,
WORD Xpos,
WORD Ypos
)
{
// WinHelp(HwndControl,
// m_szCyycoinsHelp, //m_szDevMgrHelp,
// HELP_CONTEXTMENU,
// (ULONG_PTR) HelpIDs);
HtmlHelp(HwndControl,
m_szCyycoinsHelp,
HH_TP_HELP_CONTEXTMENU,
(ULONG_PTR) HelpIDs);
return FALSE;
}
void
Port_OnHelp(
HWND DialogHwnd,
LPHELPINFO HelpInfo
)
{
if (HelpInfo->iContextType == HELPINFO_WINDOW) {
// WinHelp((HWND) HelpInfo->hItemHandle,
// m_szCyycoinsHelp, //m_szDevMgrHelp,
// HELP_WM_HELP,
// (ULONG_PTR) HelpIDs);
HtmlHelp((HWND) HelpInfo->hItemHandle,
m_szCyycoinsHelp,
HH_TP_HELP_WM_HELP,
(ULONG_PTR) HelpIDs);
}
}
BOOL
Port_OnInitDialog(
HWND DialogHwnd,
HWND FocusHwnd,
LPARAM Lparam
)
{
PPORT_PARAMS params;
DWORD dwError;
//DbgOut(TEXT("Port_OnInitDialog\n"));
//
// 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.
//
params = (PPORT_PARAMS) ((LPPROPSHEETPAGE)Lparam)->lParam;
SetWindowLongPtr(DialogHwnd, DWLP_USER, (ULONG_PTR) params);
// Display board details
FillNumberOfPortsText(DialogHwnd,params);
FillModelAndBusTypeText(DialogHwnd,params);
//
// Set up the combo box with choices
//
if (params->ShowStartCom) {
ComDBOpen(&params->hComDB);
params->ShowStartCom = FillStartComCb(DialogHwnd, params);
if (params->hComDB != HCOMDB_INVALID_HANDLE_VALUE) {
ComDBClose(params->hComDB);
}
} else {
EnableWindow(GetDlgItem(DialogHwnd, PP_START_COM), FALSE);
EnableWindow(GetDlgItem(DialogHwnd, IDC_START_COM), FALSE);
}
return TRUE; // No need for us to set the focus.
}
BOOL
Port_OnNotify(
HWND DialogHwnd,
LPNMHDR NmHdr
)
{
PPORT_PARAMS params = (PPORT_PARAMS)GetWindowLongPtr(DialogHwnd, DWLP_USER);
switch (NmHdr->code) {
//
// Sent when the user clicks on Apply OR OK !!
//
case PSN_APPLY:
//DbgOut(TEXT("Port_OnNotify PSN_APPLY\n"));
//
// Write out the com port options to the registry
//
if (SavePortSettingsDlg(DialogHwnd, params)) {
SetWindowLongPtr(DialogHwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
} else {
SetWindowLongPtr(DialogHwnd, DWLP_MSGRESULT, PSNRET_INVALID);
}
return TRUE;
default:
//DbgOut(TEXT("Port_OnNotify default\n"));
return FALSE;
}
}
ULONG
FillModelAndBusTypeText(
IN HWND DialogHwnd,
IN PPORT_PARAMS Params
)
{
TCHAR szHardwareId[LINE_LEN];
PTCHAR szCharPtr;
HWND detailHwnd;
TCHAR szBusType[10];
TCHAR szConfiguration[10];
TCHAR szModel[10];
DWORD dataType;
ZeroMemory(szBusType,sizeof(szBusType));
ZeroMemory(szConfiguration,sizeof(szConfiguration));
ZeroMemory(szModel,sizeof(szModel));
if (SetupDiGetDeviceRegistryProperty(Params->DeviceInfoSet,
Params->DeviceInfoData,
SPDRP_HARDWAREID,
&dataType,
(PBYTE) szHardwareId,
sizeof(szHardwareId),
NULL)) {
szCharPtr = szHardwareId;
while (*szCharPtr) {
if (_tcsnicmp(szCharPtr,
TEXT("PCI\\VEN_120E&DEV_0100&SUBSYS_0100120E"),
_tcslen(TEXT("PCI\\VEN_120E&DEV_0100&SUBSYS_0100120E")))
== 0) {
wsprintf(szBusType, TEXT("PCI"));
wsprintf(szConfiguration, TEXT("Below 1MB"));
wsprintf(szModel, TEXT("YeP"));
break;
} else if (_tcsnicmp(szCharPtr,
TEXT("PCI\\VEN_120E&DEV_0101&SUBSYS_0100120E"),
_tcslen(TEXT("PCI\\VEN_120E&DEV_0101&SUBSYS_0100120E")))
== 0) {
wsprintf(szBusType, TEXT("PCI"));
wsprintf(szConfiguration, TEXT("Above 1MB"));
wsprintf(szModel, TEXT("YeP"));
break;
} else if (_tcsnicmp(szCharPtr,
TEXT("PCI\\VEN_120E&DEV_0100"),
_tcslen(TEXT("PCI\\VEN_120E&DEV_0100")))
== 0) {
wsprintf(szBusType, TEXT("PCI"));
wsprintf(szConfiguration, TEXT("Below 1MB"));
break;
} else if (_tcsnicmp(szCharPtr,
TEXT("PCI\\VEN_120E&DEV_0101"),
_tcslen(TEXT("PCI\\VEN_120E&DEV_0101")))
== 0) {
wsprintf(szBusType, TEXT("PCI"));
wsprintf(szConfiguration, TEXT("Above 1MB"));
break;
} else if (_tcsnicmp(szCharPtr,
TEXT("PCI\\VEN_120E&DEV_0102"),
_tcslen(TEXT("PCI\\VEN_120E&DEV_0102")))
== 0) {
wsprintf(szBusType, TEXT("PCI"));
wsprintf(szConfiguration, TEXT("Below 1MB"));
wsprintf(szModel, TEXT("4YP"));
break;
} else if (_tcsnicmp(szCharPtr,
TEXT("PCI\\VEN_120E&DEV_0103"),
_tcslen(TEXT("PCI\\VEN_120E&DEV_0103")))
== 0) {
wsprintf(szBusType, TEXT("PCI"));
wsprintf(szConfiguration, TEXT("Above 1MB"));
wsprintf(szModel, TEXT("4YP"));
break;
} else if (_tcsnicmp(szCharPtr,
TEXT("PCI\\VEN_120E&DEV_0104"),
_tcslen(TEXT("PCI\\VEN_120E&DEV_0104")))
== 0) {
wsprintf(szBusType, TEXT("PCI"));
wsprintf(szConfiguration, TEXT("Below 1MB"));
wsprintf(szModel, TEXT("8YP"));
break;
} else if (_tcsnicmp(szCharPtr,
TEXT("PCI\\VEN_120E&DEV_0105"),
_tcslen(TEXT("PCI\\VEN_120E&DEV_0105")))
== 0) {
wsprintf(szBusType, TEXT("PCI"));
wsprintf(szConfiguration, TEXT("Above 1MB"));
wsprintf(szModel, TEXT("8YP"));
break;
} else if (_tcsnicmp(szCharPtr,
TEXT("YISA"),
_tcslen(TEXT("YISA")))
== 0) {
wsprintf(szBusType, TEXT("ISA"));
} break;
szCharPtr = szCharPtr + _tcslen(szCharPtr) + 1;
}
if (*szBusType) {
detailHwnd = GetDlgItem(DialogHwnd, PP_BUS_TYPE);
SetWindowText(detailHwnd,szBusType);
}
if (*szConfiguration) {
detailHwnd = GetDlgItem(DialogHwnd, IDC_CONFIGURATION);
SetWindowText(detailHwnd,TEXT("Configuration:"));
detailHwnd = GetDlgItem(DialogHwnd, PP_CONFIGURATION);
SetWindowText(detailHwnd,szConfiguration);
}
if (*szModel) {
detailHwnd = GetDlgItem(DialogHwnd, IDC_MODEL);
SetWindowText(detailHwnd,TEXT("Model:"));
detailHwnd = GetDlgItem(DialogHwnd, PP_MODEL);
SetWindowText(detailHwnd,szModel);
}
}
return ERROR_SUCCESS;
}
ULONG
FillNumberOfPortsText(
IN HWND DialogHwnd,
IN PPORT_PARAMS Params
)
{
HKEY hDeviceKey;
DWORD err,numOfPortsSize,numOfPorts;
HWND numportHwnd;
TCHAR szText[10];
err = ERROR_SUCCESS;
if((hDeviceKey = SetupDiOpenDevRegKey(Params->DeviceInfoSet,
Params->DeviceInfoData,
DICS_FLAG_GLOBAL,
0,
DIREG_DEV,
KEY_READ)) == INVALID_HANDLE_VALUE) {
err = GetLastError();
goto FillNPortsExit;
}
numOfPortsSize = sizeof(numOfPorts);
err = RegQueryValueEx(hDeviceKey,
y_szNumOfPorts,
NULL,
NULL,
(PBYTE)&numOfPorts,
&numOfPortsSize
);
//********************************************************
// TEST ERROR
// err=ERROR_REGISTRY_CORRUPT;
//********************************************************
RegCloseKey(hDeviceKey);
if(err != ERROR_SUCCESS) {
goto FillNPortsExit;
}
numportHwnd = GetDlgItem(DialogHwnd, PP_NUM_PORTS);
wsprintf(szText, TEXT("%d"),numOfPorts);
SetWindowText(numportHwnd,szText);
FillNPortsExit:
//if (err != ERROR_SUCCESS) {
// MyMessageBoxWithErr(DialogHwnd,IDS_NUM_PORTS_DISABLED,IDS_CYCLOMY,MB_ICONWARNING,err);
//}
return err;
}
/*++
Routine Description: FillStartComCb
fill in the Port Name combo box selection with a list
of possible un-used portnames
Arguments:
poppOurPropParams: where to save the data to
hDlg: address of the window
Return Value:
BOOL: TRUE if StartCom CB displayed with no errors
--*/
BOOL
FillStartComCb(
HWND ParentHwnd,
PPORT_PARAMS Params
)
{
int i, j, nEntries;
DWORD nCurPortNum = 0;
DWORD nCom; // Changed from int to DWORD (Fanny)
DWORD dwError;
TCHAR szCom[40];
TCHAR szInUse[40];
char mask, *current;
HWND portHwnd;
DEVINST devInst,newInst;
//DbgOut(TEXT("FillStartComCb\n"));
portHwnd = GetDlgItem(ParentHwnd, PP_START_COM);
if (Params->hComDB == HCOMDB_INVALID_HANDLE_VALUE) {
// This happens if we don't have sufficient security privileges.
EnableWindow(portHwnd, FALSE);
EnableWindow(GetDlgItem(ParentHwnd, IDC_START_COM), FALSE);
return 0;
}
if (Params->PortUsage == NULL || Params->PortUsageSize == 0) {
MyMessageBox(ParentHwnd,
IDS_MEM_ALLOC_WRN,
IDS_CYCLOMY,
MB_ICONWARNING);
EnableWindow(portHwnd, FALSE);
EnableWindow(GetDlgItem(ParentHwnd, IDC_START_COM), FALSE);
return 0;
}
if (!LoadString(g_hInst, IDS_IN_USE, szInUse, CharSizeOf(szInUse))) {
wcscpy(szInUse, _T(" (in use)"));
}
//
// first tally up which ports NOT to offer in list box, ie,
// my ports should not appear as In Use.
//
if (CM_Get_Child(&devInst,(Params->DeviceInfoData)->DevInst,0) == CR_SUCCESS) {
if ((dwError=GetPortName(devInst,Params->szComName,sizeof(Params->szComName))) != ERROR_SUCCESS) {
MyMessageBoxWithErr(ParentHwnd,IDS_START_COM_DISABLED,IDS_CYCLOMY,MB_ICONWARNING,dwError);
EnableWindow(portHwnd, FALSE);
EnableWindow(GetDlgItem(ParentHwnd, IDC_START_COM), FALSE);
return 0;
}
nCurPortNum = myatoi(&Params->szComName[3]);
//nCom = myatoi(&szCom[3]);
if ((dwError=CheckComRange(ParentHwnd,Params,nCurPortNum)) != COM_RANGE_OK) {
if (dwError == COM_RANGE_TOO_BIG) {
MyMessageBox(ParentHwnd,IDS_COM_TOO_BIG_WRN,IDS_CYCLOMY,MB_ICONWARNING);
} else {
MyMessageBox(ParentHwnd,IDS_MEM_ALLOC_WRN,IDS_CYCLOMY,MB_ICONWARNING);
}
EnableWindow(portHwnd, FALSE);
EnableWindow(GetDlgItem(ParentHwnd, IDC_START_COM), FALSE);
return 0;
}
current = Params->PortUsage + (nCurPortNum-1) / 8;
if ((i = nCurPortNum % 8))
*current &= ~(1 << (i-1));
else
*current &= ~(0x80);
Params->NumChildren = 1;
while (CM_Get_Sibling(&newInst,devInst,0) == CR_SUCCESS) {
if ((dwError=GetPortName(newInst,szCom,sizeof(szCom))) != ERROR_SUCCESS) {
MyMessageBoxWithErr(ParentHwnd,IDS_START_COM_DISABLED,IDS_CYCLOMY,MB_ICONWARNING,dwError);
EnableWindow(portHwnd, FALSE);
EnableWindow(GetDlgItem(ParentHwnd, IDC_START_COM), FALSE);
return 0;
}
nCom = myatoi(&szCom[3]);
if ((dwError=CheckComRange(ParentHwnd,Params,nCom)) != COM_RANGE_OK) {
if (dwError == COM_RANGE_TOO_BIG) {
MyMessageBox(ParentHwnd,IDS_COM_TOO_BIG_WRN,IDS_CYCLOMY,MB_ICONWARNING);
} else {
MyMessageBox(ParentHwnd,IDS_MEM_ALLOC_WRN,IDS_CYCLOMY,MB_ICONWARNING);
}
EnableWindow(portHwnd, FALSE);
EnableWindow(GetDlgItem(ParentHwnd, IDC_START_COM), FALSE);
return 0;
}
current = Params->PortUsage + (nCom-1) / 8;
if ((i = nCom % 8))
*current &= ~(1 << (i-1));
else
*current &= ~(0x80);
Params->NumChildren++;
devInst = newInst;
}
}
// Fill Start COM Combo Box
current = Params->PortUsage;
mask = 0x1;
for(nEntries = j = 0, i = MIN_COM-1; i < MAX_COM_PORT; i++) {
wsprintf(szCom, TEXT("COM%d"), i+1);
if (*current & mask) {
wcscat(szCom, szInUse);
}
if (mask == (char) 0x80) {
mask = 0x01;
current++;
}
else {
mask <<= 1;
}
ComboBox_AddString(portHwnd, szCom);
}
ComboBox_SetCurSel(portHwnd, nCurPortNum-1);
return 1;
} /* FillStartComCb */
/*++
Routine Description: SavePortSettingsDlg
save changes in the Cyclom-Y Settings dlg sheet
Arguments:
Params: where to save the data to
ParentHwnd: address of the window
Return Value:
BOOL: FALSE if function fails, TRUE if function passes
--*/
BOOL
SavePortSettingsDlg(
IN HWND DialogHwnd,
IN PPORT_PARAMS Params
)
{
BOOL retValue = TRUE;
//
// store changes to win.ini; broadcast changes to apps
//
if (Params->ShowStartCom) {
ComDBOpen(&Params->hComDB);
retValue = SavePortSettings(DialogHwnd, Params);
if (Params->hComDB != HCOMDB_INVALID_HANDLE_VALUE) {
ComDBClose(Params->hComDB);
}
}
return retValue;
} /* SavePortSettingsDlg */
/*++
Routine Description: SavePortSettings
Read the dlg screen selections for baudrate, parity, etc.
If changed from what we started with, then save them
Arguments:
hDlg: address of the window
szComName: which comport we're dealing with
Params: contains, baudrate, parity, etc
Return Value:
BOOL: FALSE if function fails, TRUE if function passes
--*/
BOOL
SavePortSettings(
IN HWND DialogHwnd,
IN PPORT_PARAMS Params
)
{
UINT startComNum, curComNum, newComNum = CB_ERR;
DEVINST devInst,newInst;
TCHAR buffer[BUFFER_SIZE];
PCHILD_DATA ChildPtr,VarChildPtr;
DWORD numChild=0;
DWORD i;
DWORD dwError = ERROR_SUCCESS;
BOOL retValue = FALSE; // FALSE = failure
//DbgOut(TEXT("SavePortSettings\n"));
curComNum = myatoi(Params->szComName + wcslen(m_szCOM));
newComNum = ComboBox_GetCurSel(GetDlgItem(DialogHwnd, PP_START_COM));
if (newComNum == CB_ERR) {
newComNum = curComNum;
}
else {
newComNum++;
}
if (newComNum == curComNum) {
return TRUE; // No change, so just accept it.
}
startComNum = newComNum;
if (Params->hComDB == HCOMDB_INVALID_HANDLE_VALUE) {
MyMessageBox(DialogHwnd,IDS_INVALID_HCOMDB,IDS_CYCLOMY,MB_ICONERROR);
return retValue;
}
ChildPtr = (PCHILD_DATA) LocalAlloc(LPTR,Params->NumChildren * sizeof(CHILD_DATA));
if (ChildPtr == NULL) {
MyMessageBox(DialogHwnd, IDS_MEM_ALLOC_ERR, IDS_CYCLOMY, MB_ICONERROR);
return retValue;
}
VarChildPtr = ChildPtr;
if (CM_Get_Child(&devInst,(Params->DeviceInfoData)->DevInst,0) == CR_SUCCESS) {
if ((dwError = GetPortData(devInst,VarChildPtr)) != ERROR_SUCCESS) {
MyMessageBoxWithErr(DialogHwnd,IDS_START_COM_NOT_CHANGED,IDS_CYCLOMY,
MB_ICONERROR,dwError);
//ComboBox_SetCurSel(GetDlgItem(DialogHwnd,PP_START_COM), curComNum-1);
goto Return;
}
numChild++;
if (!QueryDosDevice(VarChildPtr->szComName, buffer, BUFFER_SIZE-1)) {
dwError = GetLastError();
MyMessageBoxWithErr(DialogHwnd, IDS_START_COM_NOT_CHANGED, IDS_CYCLOMY,
MB_ICONERROR,dwError);
//ComboBox_SetCurSel(GetDlgItem(DialogHwnd,PP_START_COM), curComNum-1);
goto Return;
}
//#if DBG
//{
//TCHAR buf[500];
//wsprintf(buf, TEXT("QueryDosDevice(%s,buffer,%d) returned %s\n"),VarChildPtr->szComName,BUFFER_SIZE-1,buffer);
//DbgOut(buf);
//}
//#endif
if (TryToOpen(VarChildPtr->szComName) == FALSE) {
dwError = GetLastError();
MyMessageBox(DialogHwnd, IDS_PORT_OPEN_ERROR,IDS_CYCLOMY,MB_ICONERROR,
VarChildPtr->szComName);
//ComboBox_SetCurSel(GetDlgItem(DialogHwnd,PP_START_COM), curComNum-1);
goto Return;
}
if ((dwError = CheckComRange(DialogHwnd,Params,newComNum)) != COM_RANGE_OK) {
if (dwError == COM_RANGE_TOO_BIG) {
MyMessageBox(DialogHwnd, IDS_COM_TOO_BIG_ERR,IDS_CYCLOMY,MB_ICONERROR);
} else {
MyMessageBox(DialogHwnd, IDS_MEM_ALLOC_ERR,IDS_CYCLOMY,MB_ICONERROR);
}
//ComboBox_SetCurSel(GetDlgItem(DialogHwnd,PP_START_COM), curComNum-1);
goto Return;
}
if (!NewComAvailable(Params,newComNum)) {
MyMessageBox(DialogHwnd, IDS_PORT_IN_USE_ERROR, IDS_CYCLOMY,MB_ICONERROR);
//ComboBox_SetCurSel(GetDlgItem(DialogHwnd,PP_START_COM), curComNum-1);
goto Return;
}
VarChildPtr->NewComNum = newComNum;
while (CM_Get_Sibling(&newInst,devInst,0) == CR_SUCCESS) {
if (numChild >= Params->NumChildren) {
// We should never reach here.
DbgOut(TEXT("cyycoins Somehow I'm getting different number of children this time!\n"));
break;
}
VarChildPtr++;
if ((dwError=GetPortData(newInst,VarChildPtr)) != ERROR_SUCCESS) {
MyMessageBoxWithErr(DialogHwnd, IDS_START_COM_NOT_CHANGED, IDS_CYCLOMY,
MB_ICONERROR,dwError);
goto Return;
}
numChild++;
if (!QueryDosDevice(VarChildPtr->szComName, buffer, BUFFER_SIZE-1)) {
dwError = GetLastError();
MyMessageBoxWithErr(DialogHwnd, IDS_START_COM_NOT_CHANGED, IDS_CYCLOMY,
MB_ICONERROR,dwError);
goto Return;
}
if (TryToOpen(VarChildPtr->szComName) == FALSE) {
dwError = GetLastError();
MyMessageBox(DialogHwnd, IDS_PORT_OPEN_ERROR,IDS_CYCLOMY,
MB_ICONERROR,VarChildPtr->szComName);
goto Return;
}
while (1) {
newComNum++;
if ((dwError=CheckComRange(DialogHwnd,Params,newComNum)) != COM_RANGE_OK) {
if (dwError == COM_RANGE_TOO_BIG) {
MyMessageBox(DialogHwnd, IDS_COM_TOO_BIG_ERR,IDS_CYCLOMY,MB_ICONERROR);
} else {
MyMessageBox(DialogHwnd, IDS_MEM_ALLOC_ERR,IDS_CYCLOMY,MB_ICONERROR);
}
//ComboBox_SetCurSel(GetDlgItem(DialogHwnd,PP_START_COM), curComNum-1);
goto Return;
}
if (NewComAvailable(Params,newComNum)) {
break;
}
}
VarChildPtr->NewComNum = newComNum;
devInst = newInst;
}
}
if (startComNum < curComNum) {
VarChildPtr = ChildPtr;
}
for (i=0; i<numChild; i++) {
EnactComNameChanges(DialogHwnd,Params,VarChildPtr);
if (startComNum < curComNum) {
VarChildPtr++;
} else {
VarChildPtr--;
}
}
retValue = TRUE; // TRUE = SUCCESS
Return:
if (ChildPtr) {
VarChildPtr = ChildPtr;
for (i=0; i<numChild; i++) {
ClosePortData(VarChildPtr);
VarChildPtr++;
}
LocalFree(ChildPtr);
}
return retValue;
} /* SavePortSettings */
void
RestoreDefaults(
HWND DialogHwnd,
PPORT_PARAMS Params
)
{
USHORT ushIndex;
ushIndex =
(USHORT) ComboBox_FindString(GetDlgItem(DialogHwnd, PP_START_COM),
-1,
Params->szComName);
ushIndex = (ushIndex == CB_ERR) ? 0 : ushIndex;
ComboBox_SetCurSel(GetDlgItem(DialogHwnd, PP_START_COM), ushIndex);
}
void
MigratePortSettings(
LPCTSTR OldComName,
LPCTSTR NewComName
)
{
TCHAR settings[BUFFER_SIZE];
TCHAR szNew[20], szOld[20];
lstrcpy(szOld, OldComName);
wcscat(szOld, m_szColon);
lstrcpy(szNew, NewComName);
wcscat(szNew, m_szColon);
settings[0] = TEXT('\0');
GetProfileString(m_szPorts,
szOld,
TEXT(""),
settings,
sizeof(settings) / sizeof(TCHAR) );
//
// Insert the new key based on the old one
//
if (settings[0] == TEXT('\0')) {
WriteProfileString(m_szPorts, szNew, m_szDefParams);
}
else {
WriteProfileString(m_szPorts, szNew, settings);
}
//
// Notify everybody of the changes and blow away the old key
//
SendWinIniChange((LPTSTR)m_szPorts);
WriteProfileString(m_szPorts, szOld, NULL);
}
void
EnactComNameChanges(
IN HWND ParentHwnd,
IN PPORT_PARAMS Params,
IN PCHILD_DATA ChildPtr)
{
DWORD dwNewComNameLen;
TCHAR buffer[BUFFER_SIZE];
TCHAR szFriendlyNameFormat[LINE_LEN];
TCHAR szDeviceDesc[LINE_LEN];
TCHAR szNewComName[20];
UINT i;
UINT curComNum,NewComNum;
SP_DEVINSTALL_PARAMS spDevInstall;
//DbgOut(TEXT("EnactComNameChanges\n"));
NewComNum = ChildPtr->NewComNum;
curComNum = myatoi(ChildPtr->szComName + wcslen(m_szCOM));
wsprintf(szNewComName, _T("COM%d"), NewComNum);
dwNewComNameLen = ByteCountOf(wcslen(szNewComName) + 1);
//
// Change the name in the symbolic namespace.
// First try to get what device the old com name mapped to
// (ie something like \Device\Serial0). Then remove the mapping. If
// the user isn't an admin, then this will fail and the dialog will popup.
// Finally, map the new name to the old device retrieved from the
// QueryDosDevice
//
//if (updateMapping)
{
BOOL removed;
HKEY hSerialMap;
if (!QueryDosDevice(ChildPtr->szComName, buffer, BUFFER_SIZE-1)) {
//
// This shouldn't happen because the previous QueryDosDevice call
// succeeded
//
MyMessageBox(ParentHwnd, IDS_PORT_RENAME_ERROR, IDS_CYCLOMY,
MB_ICONERROR, curComNum);
return;
}
//
// If this fails, then the following define will just replace the current
// mapping.
//
removed = DefineDosDevice(DDD_REMOVE_DEFINITION, ChildPtr->szComName, NULL);
if (!DefineDosDevice(DDD_RAW_TARGET_PATH, szNewComName, buffer)) {
//
// error, first fix up the remove definition and restore the old
// mapping
//
if (removed) {
DefineDosDevice(DDD_RAW_TARGET_PATH, ChildPtr->szComName, buffer);
}
MyMessageBox(ParentHwnd, IDS_PORT_RENAME_ERROR, IDS_CYCLOMY,
MB_ICONERROR, curComNum);
return;
}
//
// Set the \\HARDWARE\DEVICEMAP\SERIALCOMM field
//
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
m_szRegSerialMap,
0,
KEY_ALL_ACCESS,
&hSerialMap) == ERROR_SUCCESS) {
TCHAR szSerial[BUFFER_SIZE];
DWORD dwSerialSize, dwEnum, dwType, dwComSize;
TCHAR szCom[BUFFER_SIZE];
i = 0;
do {
dwSerialSize = CharSizeOf(szSerial);
dwComSize = sizeof(szCom);
dwEnum = RegEnumValue(hSerialMap,
i++,
szSerial,
&dwSerialSize,
NULL,
&dwType,
(LPBYTE)szCom,
&dwComSize);
if (dwEnum == ERROR_SUCCESS) {
if(dwType != REG_SZ)
continue;
if (wcscmp(szCom, ChildPtr->szComName) == 0) {
RegSetValueEx(hSerialMap,
szSerial,
0,
REG_SZ,
(PBYTE) szNewComName,
dwNewComNameLen);
break;
}
}
} while (dwEnum == ERROR_SUCCESS);
}
RegCloseKey(hSerialMap);
}
//
// Update the com db
//
if (Params->hComDB != HCOMDB_INVALID_HANDLE_VALUE) {
ComDBReleasePort(Params->hComDB, (DWORD) curComNum);
ComDBClaimPort(Params->hComDB, (DWORD) NewComNum, TRUE, NULL);
}
//
// Set the friendly name in the form of DeviceDesc (COM#)
//
if (ReplaceFriendlyName(ChildPtr->DeviceInfoSet,
&ChildPtr->DeviceInfoData,
szNewComName) == FALSE) {
// ReplaceFriendlyName failed. Use original code.
if (LoadString(g_hInst,
IDS_FRIENDLY_FORMAT,
szFriendlyNameFormat,
CharSizeOf(szFriendlyNameFormat)) &&
SetupDiGetDeviceRegistryProperty(ChildPtr->DeviceInfoSet,
&ChildPtr->DeviceInfoData,
SPDRP_DEVICEDESC,
NULL,
(PBYTE) szDeviceDesc,
sizeof(szDeviceDesc),
NULL)) {
wsprintf(buffer, szFriendlyNameFormat, szDeviceDesc, szNewComName);
}
else {
//
// Use the COM port name straight out
//
lstrcpy(buffer, szNewComName);
}
SetupDiSetDeviceRegistryProperty(ChildPtr->DeviceInfoSet,
&ChildPtr->DeviceInfoData,
SPDRP_FRIENDLYNAME,
(PBYTE) buffer,
ByteCountOf(wcslen(buffer)+1));
}
//
// Set the parent dialog's title to reflect the change in the com port's name
//
//ChangeParentTitle(GetParent(ParentHwnd), AdvancedData->szComName, szNewComName);
MigratePortSettings(ChildPtr->szComName, szNewComName);
//
// Update the PortName value in the devnode
//
RegSetValueEx(ChildPtr->hDeviceKey,
m_szPortName,
0,
REG_SZ,
(PBYTE)szNewComName,
dwNewComNameLen);
//
// Now broadcast this change to the device manager
//
ZeroMemory(&spDevInstall, sizeof(SP_DEVINSTALL_PARAMS));
spDevInstall.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
if (SetupDiGetDeviceInstallParams(Params->DeviceInfoSet,
Params->DeviceInfoData,
&spDevInstall)) {
spDevInstall.Flags |= DI_PROPERTIES_CHANGE;
SetupDiSetDeviceInstallParams(Params->DeviceInfoSet,
Params->DeviceInfoData,
&spDevInstall);
}
}
BOOL
NewComAvailable(
IN PPORT_PARAMS Params,
IN DWORD NewComNum
)
{
DWORD i;
UCHAR mask;
if ((i = NewComNum % 8))
mask = 1 << (i-1);
else
mask = (char) 0x80;
if (Params->PortUsage[(NewComNum-1)/8] & mask) {
//
// Port has been previously claimed
//
return FALSE;
}
return TRUE;
}
BOOL
TryToOpen(
IN PTCHAR szCom
)
{
TCHAR szComFileName[20]; // more than enough for "\\.\COMXxxx"
HANDLE hCom;
lstrcpy(szComFileName, L"\\\\.\\");
lstrcat(szComFileName, szCom);
//
// Make sure that the port has not been opened by another application
//
hCom = CreateFile(szComFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
//
// If the file handle is invalid, then the com port is open, warn the user
//
if (hCom == INVALID_HANDLE_VALUE) {
return FALSE;
}
CloseHandle(hCom);
return TRUE;
}
ULONG
GetPortName(
IN DEVINST PortInst,
IN OUT TCHAR *ComName,
IN ULONG ComNameSize
)
{
HDEVINFO portInfo;
SP_DEVINFO_DATA portData;
TCHAR portId[MAX_DEVICE_ID_LEN];
DWORD dwPortNameSize, dwError;
HKEY hDeviceKey;
dwError = ERROR_SUCCESS;
if (CM_Get_Device_ID(PortInst,portId,CharSizeOf(portId),0) == CR_SUCCESS) {
portInfo = SetupDiCreateDeviceInfoList(NULL,NULL);
if (portInfo != INVALID_HANDLE_VALUE) {
portData.cbSize = sizeof(SP_DEVINFO_DATA);
if (SetupDiOpenDeviceInfo(portInfo,portId,NULL,0,&portData)) {
hDeviceKey = SetupDiOpenDevRegKey(portInfo,&portData,
DICS_FLAG_GLOBAL,0,
DIREG_DEV,KEY_READ);
if (hDeviceKey == INVALID_HANDLE_VALUE) {
dwError = GetLastError();
}
dwPortNameSize = ComNameSize;
dwError = RegQueryValueEx(hDeviceKey,
m_szPortName, // "PortName"
NULL,
NULL,
(PBYTE)ComName,
&dwPortNameSize);
if (dwError == ERROR_SUCCESS) {
// #if DBG
// {
// TCHAR buf[500];
// wsprintf(buf, TEXT("cyycoins PortName %s\n"),ComName);
// DbgOut(buf);
// }
// #endif
}
RegCloseKey(hDeviceKey);
} else {
dwError = GetLastError();
}
SetupDiDestroyDeviceInfoList(portInfo);
} else {
dwError = GetLastError();
}
}
return dwError;
}
ULONG
GetPortData(
IN DEVINST PortInst,
OUT PCHILD_DATA ChildPtr
)
{
HDEVINFO portInfo;
HKEY hDeviceKey;
TCHAR portId[MAX_DEVICE_ID_LEN];
DWORD dwPortNameSize,dwError;
dwError = ERROR_SUCCESS;
portInfo = INVALID_HANDLE_VALUE;
hDeviceKey = INVALID_HANDLE_VALUE;
if (CM_Get_Device_ID(PortInst,portId,CharSizeOf(portId),0) == CR_SUCCESS) {
portInfo = SetupDiCreateDeviceInfoList(NULL,NULL);
if (portInfo != INVALID_HANDLE_VALUE) {
ChildPtr->DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (SetupDiOpenDeviceInfo(portInfo,
portId,
NULL,
0,
&ChildPtr->DeviceInfoData)) {
hDeviceKey = SetupDiOpenDevRegKey(portInfo,&ChildPtr->DeviceInfoData,
DICS_FLAG_GLOBAL,0,
DIREG_DEV,KEY_ALL_ACCESS);
if (hDeviceKey == INVALID_HANDLE_VALUE) {
dwError = GetLastError();
} else {
dwPortNameSize = sizeof(ChildPtr->szComName);
dwError = RegQueryValueEx(hDeviceKey,
m_szPortName, // "PortName"
NULL,
NULL,
(PBYTE)ChildPtr->szComName,
&dwPortNameSize);
if (dwError != ERROR_SUCCESS) {
RegCloseKey(hDeviceKey);
hDeviceKey = INVALID_HANDLE_VALUE;
}
}
} else {
dwError = GetLastError();
}
if (dwError != ERROR_SUCCESS) {
SetupDiDestroyDeviceInfoList(portInfo);
portInfo = INVALID_HANDLE_VALUE;
}
} else {
dwError = GetLastError();
}
}
ChildPtr->DeviceInfoSet = portInfo;
ChildPtr->hDeviceKey = hDeviceKey;
return dwError;
}
void
ClosePortData(
IN PCHILD_DATA ChildPtr
)
{
if (ChildPtr->hDeviceKey != INVALID_HANDLE_VALUE) {
RegCloseKey(ChildPtr->hDeviceKey);
}
if (ChildPtr->DeviceInfoSet != INVALID_HANDLE_VALUE) {
SetupDiDestroyDeviceInfoList(ChildPtr->DeviceInfoSet);
}
}
/*++
Routine Description: CheckComRange
Returns TRUE if Com port is in the PortUsage range.
Arguments:
ParentHwnd: address of the window
Params: where to save the data to
ComPort: com port to be checked
Return Value:
COM_RANGE_OK
COM_RANGE_TOO_BIG
COM_RANGE_MEM_ERR
--*/
DWORD
CheckComRange(
HWND ParentHwnd,
PPORT_PARAMS Params,
DWORD nCom
)
{
PBYTE newPortUsage;
DWORD portsReported;
HCOMDB hComDB;
DWORD comUsageSize = Params->PortUsageSize*8;
if (nCom > MAX_COM_PORT) {
return COM_RANGE_TOO_BIG;
}
if (nCom > comUsageSize) {
if (comUsageSize < 256) {
comUsageSize = 256;
} else if (comUsageSize < 1024) {
comUsageSize = 1024;
} else if (comUsageSize < 2048) {
comUsageSize = 2048;
} else {
return COM_RANGE_TOO_BIG;
}
// Re-alloc to COMDB_MAX_PORTS_ARBITRATED
newPortUsage = (PBYTE) LocalAlloc(LPTR,comUsageSize/8);
if (newPortUsage == NULL) {
return COM_RANGE_MEM_ERR;
} else {
//DbgOut(TEXT("Params->PortUsage replaced\n"));
LocalFree(Params->PortUsage);
Params->PortUsage = newPortUsage;
Params->PortUsageSize = comUsageSize/8;
ComDBGetCurrentPortUsage(Params->hComDB,
NULL,
0,
0,
&portsReported
);
if (comUsageSize > portsReported) {
if (ComDBResizeDatabase(Params->hComDB, comUsageSize) != ERROR_SUCCESS){
//return COM_RANGE_TOO_BIG; // TODO: Replace by a better message.
}
}
ComDBGetCurrentPortUsage(Params->hComDB,
Params->PortUsage,
Params->PortUsageSize,
CDB_REPORT_BITS,
&portsReported
);
}
}
return COM_RANGE_OK;
}