/*++ Copyright (c) 1990-2003 Microsoft Corporation All rights reserved Module Name: config.c Abstract: Handles spooler entry points for adding, deleting, and configuring localui ports. // @@BEGIN_DDKSPLIT Environment: User Mode -Win32 Revision History: // @@END_DDKSPLIT --*/ #include "precomp.h" #pragma hdrstop #include "spltypes.h" #include "localui.h" #include "local.h" #include "lmon.h" /* From Control Panel's control.h: */ #define CHILD_PORTS 0 /* From cpl.h: */ #define CPL_INIT 1 #define CPL_DBLCLK 5 #define CPL_EXIT 7 // @@BEGIN_DDKSPLIT /* Hack: */ // @@END_DDKSPLIT #define CHILD_PORTS_HELPID 0 /* ConfigCOMPort * * Calls the Control Panel Ports applet * to permit user to set Baud rate etc. */ typedef void (WINAPI *CFGPROC)(HWND, ULONG, ULONG, ULONG); BOOL ConfigLPTPort( HWND hWnd, HANDLE hXcv ); BOOL ConfigCOMPort( HWND hWnd, HANDLE hXcv, PCWSTR pszServer, PCWSTR pszPortName ); LPWSTR GetPortName( HWND hWnd, HANDLE hXcv ); BOOL AddPortUI( PCWSTR pszServer, HWND hWnd, PCWSTR pszMonitorNameIn, PWSTR *ppszPortNameOut ) { PWSTR pszPortName = NULL; BOOL rc = TRUE; WCHAR szLocalMonitor[MAX_PATH+1]; DWORD dwReturn, dwStatus; DWORD cbNeeded; PRINTER_DEFAULTS Default; PWSTR pszServerName = NULL; HANDLE hXcv = NULL; DWORD dwLastError = ERROR_SUCCESS; // // // if (hWnd && !IsWindow (hWnd)) { // // Invalid parent window handle causes problems in function with DialogBoxParam call. // That function when the handle is bad returns ZERO, the same value as ERROR_SUCCEED. // PortNameDlg function calls EndDialog (ERROR_SUCCEES) if everything is alright. // SetLastError (ERROR_INVALID_WINDOW_HANDLE); if (ppszPortNameOut) { *ppszPortNameOut = NULL; } return FALSE; } // // // /* Get the user to enter a port name: */ if (!(pszServerName = ConstructXcvName(pszServer, pszMonitorNameIn, L"XcvMonitor"))) { rc = FALSE; goto Done; } Default.pDatatype = NULL; Default.pDevMode = NULL; Default.DesiredAccess = SERVER_ACCESS_ADMINISTER; if (!(rc = OpenPrinter((PWSTR) pszServerName, &hXcv, &Default))) { rc = FALSE; goto Done; } if (!(pszPortName = GetPortName(hWnd, hXcv))) { rc = FALSE; goto Done; } // We can't Add, Configure, or Delete Remote COM ports if (IS_COM_PORT(pszPortName) || IS_LPT_PORT(pszPortName)) { SetLastError(ERROR_NOT_SUPPORTED); rc = FALSE; goto Done; } if(IS_COM_PORT(pszPortName)) CharUpperBuff(pszPortName, 3); else if(IS_LPT_PORT(pszPortName)) CharUpperBuff(pszPortName, 3); rc = XcvData( hXcv, L"AddPort", (PBYTE) pszPortName, (wcslen(pszPortName) + 1)*sizeof(WCHAR), (PBYTE) &dwReturn, 0, &cbNeeded, &dwStatus); if (rc) { if(dwStatus == ERROR_SUCCESS) { if(ppszPortNameOut) *ppszPortNameOut = AllocSplStr(pszPortName); if(IS_LPT_PORT(pszPortName)) rc = ConfigLPTPort(hWnd, hXcv); else if(IS_COM_PORT(pszPortName)) rc = ConfigCOMPort(hWnd, hXcv, pszServer, pszPortName); } else if (dwStatus == ERROR_ALREADY_EXISTS) { Message( hWnd, MSG_ERROR, IDS_LOCALMONITOR, IDS_PORTALREADYEXISTS_S, pszPortName ); } else { SetLastError(dwStatus); rc = FALSE; } } Done: dwLastError = GetLastError (); FreeSplStr(pszPortName); FreeSplMem(pszServerName); if (hXcv) ClosePrinter(hXcv); SetLastError (dwLastError); return rc; } BOOL DeletePortUI( PCWSTR pszServer, HWND hWnd, PCWSTR pszPortName ) { PRINTER_DEFAULTS Default; PWSTR pszServerName = NULL; DWORD dwOutput; DWORD cbNeeded; BOOL bRet; HANDLE hXcv = NULL; DWORD dwStatus; DWORD dwLastError = ERROR_SUCCESS; // // // if (hWnd && !IsWindow (hWnd)) { SetLastError (ERROR_INVALID_WINDOW_HANDLE); return FALSE; } // // // if (!(pszServerName = ConstructXcvName(pszServer, pszPortName, L"XcvPort"))) { bRet = FALSE; goto Done; } Default.pDatatype = NULL; Default.pDevMode = NULL; Default.DesiredAccess = SERVER_ACCESS_ADMINISTER; if (!(bRet = OpenPrinter((PWSTR) pszServerName, &hXcv, &Default))) goto Done; // Since we can't Add or Configure Remote COM ports, let's not allow deletion either if (IS_COM_PORT(pszPortName) || IS_LPT_PORT(pszPortName)) { SetLastError(ERROR_NOT_SUPPORTED); bRet = FALSE; } else { bRet = XcvData( hXcv, L"DeletePort", (PBYTE) pszPortName, (wcslen(pszPortName) + 1)*sizeof(WCHAR), (PBYTE) &dwOutput, 0, &cbNeeded, &dwStatus); if (!bRet && (ERROR_BUSY == dwStatus)) { // // Port cannot be deleted cause it is in use. // ErrorMessage ( hWnd, dwStatus ); // // Error is handled here and caller does not need to do anything // SetLastError (ERROR_CANCELLED); } else if (bRet && (ERROR_SUCCESS != dwStatus)) { SetLastError(dwStatus); bRet = FALSE; } } Done: dwLastError = GetLastError (); if (hXcv) ClosePrinter(hXcv); FreeSplMem(pszServerName); SetLastError (dwLastError); return bRet; } /* ConfigurePortUI * */ BOOL ConfigurePortUI( PCWSTR pName, HWND hWnd, PCWSTR pPortName ) { BOOL bRet; PRINTER_DEFAULTS Default; PWSTR pServerName = NULL; HANDLE hXcv = NULL; DWORD dwLastError = ERROR_SUCCESS; // // // if (hWnd && !IsWindow (hWnd)) { SetLastError (ERROR_INVALID_WINDOW_HANDLE); return FALSE; } // // // if (!(pServerName = ConstructXcvName(pName, pPortName, L"XcvPort"))) { bRet = FALSE; goto Done; } Default.pDatatype = NULL; Default.pDevMode = NULL; Default.DesiredAccess = SERVER_ACCESS_ADMINISTER; if (!(bRet = OpenPrinter((PWSTR) pServerName, &hXcv, &Default))) goto Done; if( IS_LPT_PORT( (PWSTR) pPortName ) ) bRet = ConfigLPTPort(hWnd, hXcv); else if( IS_COM_PORT( (PWSTR) pPortName ) ) bRet = ConfigCOMPort(hWnd, hXcv, pName, pPortName); else { Message( hWnd, MSG_INFORMATION, IDS_LOCALMONITOR, IDS_NOTHING_TO_CONFIGURE ); SetLastError(ERROR_CANCELLED); bRet = FALSE; } Done: dwLastError = GetLastError (); FreeSplMem(pServerName); if (hXcv) { ClosePrinter(hXcv); hXcv = NULL; } SetLastError (dwLastError); return bRet; } /* ConfigLPTPort * * Calls a dialog box which prompts the user to enter timeout and retry * values for the port concerned. * The dialog writes the information to the registry (win.ini for now). */ BOOL ConfigLPTPort( HWND hWnd, HANDLE hXcv ) { PORTDIALOG Port; INT iRet; // // ZeroMemory (&Port, sizeof (Port)); iRet = -1; // // Port.hXcv = hXcv; iRet = (INT)DialogBoxParam(hInst, MAKEINTRESOURCE( DLG_CONFIGURE_LPT ), hWnd, ConfigureLPTPortDlg, (LPARAM) &Port); if (iRet == ERROR_SUCCESS) { // // DialogBoxParam returns zero if hWnd is invalid. // ERROR_SUCCESS is equal to zero. // => We need to check LastError too. // return ERROR_SUCCESS == GetLastError (); } if (iRet == -1) return FALSE; SetLastError(iRet); return FALSE; } /* ConfigCOMPort * */ BOOL ConfigCOMPort( HWND hWnd, HANDLE hXcv, PCWSTR pszServer, PCWSTR pszPortName ) { DWORD dwStatus; BOOL bRet = FALSE; COMMCONFIG CommConfig; COMMCONFIG *pCommConfig = &CommConfig; COMMCONFIG *pCC = NULL; PWSTR pszPort = NULL; DWORD cbNeeded; // GetDefaultCommConfig can't handle trailing :, so remove it! if (!(pszPort = (PWSTR) AllocSplStr(pszPortName))) goto Done; pszPort[wcslen(pszPort) - 1] = L'\0'; cbNeeded = sizeof CommConfig; if (!XcvData( hXcv, L"GetDefaultCommConfig", (PBYTE) pszPort, (wcslen(pszPort) + 1)*sizeof *pszPort, (PBYTE) pCommConfig, cbNeeded, &cbNeeded, &dwStatus)) goto Done; if (dwStatus != ERROR_SUCCESS) { if (dwStatus != ERROR_INSUFFICIENT_BUFFER) { SetLastError(dwStatus); goto Done; } if (!(pCommConfig = pCC = AllocSplMem(cbNeeded))) goto Done; if (!XcvData( hXcv, L"GetDefaultCommConfig", (PBYTE) pszPort, (wcslen(pszPort) + 1)*sizeof *pszPort, (PBYTE) pCommConfig, cbNeeded, &cbNeeded, &dwStatus)) goto Done; if (dwStatus != ERROR_SUCCESS) { SetLastError(dwStatus); goto Done; } } if (CommConfigDialog(pszPort, hWnd, pCommConfig)) { if (!XcvData( hXcv, L"SetDefaultCommConfig", (PBYTE) pCommConfig, pCommConfig->dwSize, (PBYTE) NULL, 0, &cbNeeded, &dwStatus)) goto Done; if (dwStatus != ERROR_SUCCESS) { SetLastError(dwStatus); goto Done; } bRet = TRUE; } Done: FreeSplMem(pCC); FreeSplStr(pszPort); return bRet; } // // Support routines // /* GetPortName * * Puts up a dialog containing a free entry field. * The dialog allocates a string for the name, if a selection is made. */ LPWSTR GetPortName( HWND hWnd, HANDLE hXcv ) { PORTDIALOG Port; INT Result; LPWSTR pszPort = NULL; // // ZeroMemory (&Port, sizeof (Port)); Result = -1; // // Port.hXcv = hXcv; Result = (INT)DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_PORTNAME), hWnd, PortNameDlg, (LPARAM)&Port); if (Result == ERROR_SUCCESS) { // // DialogBoxParam returns zero if hWnd is invalid. // ERROR_SUCCESS is equal to zero. // => We need to check LastError too. // if (ERROR_SUCCESS == GetLastError ()) { // // DialogBoxParam executed successfully and a port name was retrieved // pszPort = Port.pszPortName; } } else if (Result != -1) { // // DialogBoxParam executed successfully, but the user canceled the dialog // SetLastError(Result); } return pszPort; }