/** * @name _HandleGetDefaultCommConfig * * Gets the default configuration of a legacy port. * The opposite function is _HandleSetDefaultCommConfig. * * @param pInputData * The port name (without colon!) whose default configuration you want to get. * * @param pOutputData * Pointer to a COMMCONFIG structure that will receive the configuration information. * * @param cbOutputData * Size of the variable pointed to by pOutputData. * * @param pcbOutputNeeded * Pointer to a DWORD that contains the required size for pOutputData on return. * * @return * An error code indicating success or failure. */ static DWORD _HandleGetDefaultCommConfig(PBYTE pInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded) { // Sanity checks if (!pInputData || !pcbOutputNeeded) return ERROR_INVALID_PARAMETER; *pcbOutputNeeded = sizeof(COMMCONFIG); // Check if the supplied buffer is large enough. if (cbOutputData < *pcbOutputNeeded) return ERROR_INSUFFICIENT_BUFFER; // Finally get the port configuration. if (!GetDefaultCommConfigW((PCWSTR)pInputData, (LPCOMMCONFIG)pOutputData, pcbOutputNeeded)) return GetLastError(); return ERROR_SUCCESS; }
/************************************************************************** * GetDefaultCommConfigA (KERNEL32.@) * * Acquires the default configuration of the specified communication device. (ascii) * * RETURNS * * True on successful reading of the default configuration, * if the device is not found or the buffer is too small. */ BOOL WINAPI GetDefaultCommConfigA( LPCSTR lpszName, /* [in] The ascii name of the device targeted for configuration. */ LPCOMMCONFIG lpCC, /* [out] The default configuration for the device. */ LPDWORD lpdwSize) /* [in/out] Initially the size of the default configuration buffer, afterwards the number of bytes copied to the buffer or the needed size of the buffer. */ { BOOL ret = FALSE; UNICODE_STRING lpszNameW; TRACE("(%s, %p, %p) *lpdwSize: %u\n", debugstr_a(lpszName), lpCC, lpdwSize, lpdwSize ? *lpdwSize : 0 ); if(lpszName) RtlCreateUnicodeStringFromAsciiz(&lpszNameW,lpszName); else lpszNameW.Buffer = NULL; ret = GetDefaultCommConfigW(lpszNameW.Buffer,lpCC,lpdwSize); RtlFreeUnicodeString(&lpszNameW); return ret; }
/***************************************************** * localmon_XcvDataPort [exported through MONITOREX] * * Execute command through a Communication-Channel * * PARAMS * hXcv [i] The Handle to work with * pszDataName [i] Name of the command to execute * pInputData [i] Buffer for extra Input Data (needed only for some commands) * cbInputData [i] Size in Bytes of Buffer at pInputData * pOutputData [o] Buffer to receive additional Data (needed only for some commands) * cbOutputData [i] Size in Bytes of Buffer at pOutputData * pcbOutputNeeded [o] PTR to receive the minimal Size in Bytes of the Buffer at pOutputData * * RETURNS * Success: ERROR_SUCCESS * Failure: win32 error code * * NOTES * * Minimal List of commands, that every Printmonitor DLL should support: * *| "MonitorUI" : Return the Name of the Userinterface-DLL as WSTR in pOutputData *| "AddPort" : Add a Port (Name as WSTR in pInputData) *| "DeletePort": Delete a Port (Name as WSTR in pInputData) * * */ static DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded) { WCHAR buffer[16]; /* buffer for a decimal number */ LPWSTR ptr; DWORD res; DWORD needed; HKEY hroot; TRACE("(%p, %s, %p, %d, %p, %d, %p)\n", hXcv, debugstr_w(pszDataName), pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded); if (!lstrcmpW(pszDataName, cmd_AddPortW)) { TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData)); res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_PortsW, &hroot); if (res == ERROR_SUCCESS) { if (does_port_exist((LPWSTR) pInputData)) { RegCloseKey(hroot); TRACE("=> %u\n", ERROR_ALREADY_EXISTS); return ERROR_ALREADY_EXISTS; } res = RegSetValueExW(hroot, (LPWSTR) pInputData, 0, REG_SZ, (const BYTE *) emptyW, sizeof(emptyW)); RegCloseKey(hroot); } TRACE("=> %u\n", res); return res; } if (!lstrcmpW(pszDataName, cmd_ConfigureLPTPortCommandOKW)) { TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData)); res = RegCreateKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_WindowsW, &hroot); if (res == ERROR_SUCCESS) { res = RegSetValueExW(hroot, TransmissionRetryTimeoutW, 0, REG_SZ, pInputData, cbInputData); RegCloseKey(hroot); } return res; } if (!lstrcmpW(pszDataName, cmd_DeletePortW)) { TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData)); res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_PortsW, &hroot); if (res == ERROR_SUCCESS) { res = RegDeleteValueW(hroot, (LPWSTR) pInputData); RegCloseKey(hroot); TRACE("=> %u with %u\n", res, GetLastError() ); return res; } return ERROR_FILE_NOT_FOUND; } if (!lstrcmpW(pszDataName, cmd_GetDefaultCommConfigW)) { TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData)); *pcbOutputNeeded = cbOutputData; res = GetDefaultCommConfigW((LPWSTR) pInputData, (LPCOMMCONFIG) pOutputData, pcbOutputNeeded); TRACE("got %u with %u\n", res, GetLastError() ); return res ? ERROR_SUCCESS : GetLastError(); } if (!lstrcmpW(pszDataName, cmd_GetTransmissionRetryTimeoutW)) { * pcbOutputNeeded = sizeof(DWORD); if (cbOutputData >= sizeof(DWORD)) { /* the w2k resource kit documented a default of 90, but that's wrong */ *((LPDWORD) pOutputData) = 45; res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_WindowsW, &hroot); if (res == ERROR_SUCCESS) { needed = sizeof(buffer) - sizeof(WCHAR); res = RegQueryValueExW(hroot, TransmissionRetryTimeoutW, NULL, NULL, (LPBYTE) buffer, &needed); if ((res == ERROR_SUCCESS) && (buffer[0])) { *((LPDWORD) pOutputData) = strtoulW(buffer, NULL, 0); } RegCloseKey(hroot); } return ERROR_SUCCESS; } return ERROR_INSUFFICIENT_BUFFER; } if (!lstrcmpW(pszDataName, cmd_MonitorUIW)) { * pcbOutputNeeded = sizeof(dllnameuiW); if (cbOutputData >= sizeof(dllnameuiW)) { memcpy(pOutputData, dllnameuiW, sizeof(dllnameuiW)); return ERROR_SUCCESS; } return ERROR_INSUFFICIENT_BUFFER; } if (!lstrcmpW(pszDataName, cmd_PortIsValidW)) { TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData)); res = get_type_from_name((LPCWSTR) pInputData); TRACE("detected as %u\n", res); /* names, that we have recognized, are valid */ if (res) return ERROR_SUCCESS; /* ERROR_ACCESS_DENIED, ERROR_PATH_NOT_FOUND or something else */ TRACE("=> %u\n", GetLastError()); return GetLastError(); } if (!lstrcmpW(pszDataName, cmd_SetDefaultCommConfigW)) { /* get the portname from the Handle */ ptr = strchrW(((xcv_t *)hXcv)->nameW, ' '); if (ptr) { ptr++; /* skip the space */ } else { ptr = ((xcv_t *)hXcv)->nameW; } lstrcpynW(buffer, ptr, sizeof(buffer)/sizeof(WCHAR)); if (buffer[0]) buffer[lstrlenW(buffer)-1] = '\0'; /* remove the ':' */ res = SetDefaultCommConfigW(buffer, (LPCOMMCONFIG) pInputData, cbInputData); TRACE("got %u with %u\n", res, GetLastError() ); return res ? ERROR_SUCCESS : GetLastError(); } FIXME("command not supported: %s\n", debugstr_w(pszDataName)); return ERROR_INVALID_PARAMETER; }
/*********************************************************************** * SERIALUI_ConfigDialogProc * * Shows a dialog for configuring a COMM port */ INT_PTR CALLBACK SERIALUI_ConfigDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static const WCHAR szSettings[] = { 'S','e','t','t','i','n','g','s',' ','f','o','r',' ',0 }; WCHAR szTitle[40]; SERIALUI_DialogInfo *info; switch (uMsg) { case WM_INITDIALOG: info = (SERIALUI_DialogInfo*) lParam; if(!info) return FALSE; SetWindowLongPtrW(hWnd, DWLP_USER, lParam); strcpyW( szTitle, szSettings ); strcatW( szTitle, info->lpszDevice ); SetWindowTextW(hWnd, szTitle); SERIALUI_DCBToDialogInfo(hWnd, info); return TRUE; case WM_COMMAND: { WORD wID = LOWORD(wParam); info = (SERIALUI_DialogInfo *) GetWindowLongPtrW(hWnd, DWLP_USER); if(!info) EndDialog(hWnd,0); switch (wID) { case IDOK: SERIALUI_DialogInfoToDCB(hWnd,info); EndDialog(hWnd,1); return TRUE; case IDCANCEL: EndDialog(hWnd,0); return TRUE; /* test code for Get/SetDefaultCommConfig begins */ case ID_GETDEFAULT: { DWORD r,dwConfSize = sizeof (COMMCONFIG); r = GetDefaultCommConfigW(info->lpszDevice, info->lpCommConfig, &dwConfSize); if(!r) MessageBoxA(hWnd,"Failed","GetDefaultCommConfig",MB_OK); } SERIALUI_DCBToDialogInfo(hWnd, info); break; case ID_SETDEFAULT: { DWORD r; SERIALUI_DialogInfoToDCB(hWnd,info); r = SetDefaultCommConfigW(info->lpszDevice, info->lpCommConfig, sizeof (COMMCONFIG)); if(!r) MessageBoxA(hWnd,"Failed","GetDefaultCommConfig",MB_OK); } break; /* test code for Get/SetDefaultCommConfig ends */ } } default: return FALSE; } }