diff options
Diffstat (limited to 'private/tapi/dev/apps')
125 files changed, 44920 insertions, 0 deletions
diff --git a/private/tapi/dev/apps/acd/acdsmpl.c b/private/tapi/dev/apps/acd/acdsmpl.c new file mode 100644 index 000000000..8601bf63f --- /dev/null +++ b/private/tapi/dev/apps/acd/acdsmpl.c @@ -0,0 +1,2495 @@ +////////////////////////////////////////////////////////////////////////////// +// +// ACDSMPL.C +// +// Handles all the UI for ACDSample +// +////////////////////////////////////////////////////////////////////////////// + +#include <windows.h> +#include <commctrl.h> +#include <commdlg.h> +#include <tapi.h> +#include <stdlib.h> +#include "resource.h" +#include "acdsmpl.h" + + +////////////////////////////////////////////////////////////////////////////// +// PROTOTYPES +////////////////////////////////////////////////////////////////////////////// +static BOOL CreateMainWindow (int nCmdShow); + +static LRESULT CALLBACK MainDlgProc (HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); +void MySetWindow(HWND, int); +void MySaveWindow(HWND); +BOOL ResizeWindows(BOOL bSizeBar, DWORD dwBarLocation); +HTREEITEM AddItemToTree(HTREEITEM hParent, + LPTSTR lpszName, + LPARAM lParam, + HTREEITEM * phItem); +BOOL DoPopupMenu(HTREEITEM hItem, POINT pt); +BOOL DeleteLeafAndStruct(HTREEITEM hItem); +BOOL CALLBACK ChangeGroupDlgProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); +BOOL CALLBACK ChangeAgentDlgProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); +BOOL CALLBACK AddGroupDlgProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); +BOOL CALLBACK AddAgentDlgProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); +LRESULT DoCommand(WPARAM wParam, LPARAM lParam); +void AddGroupsToMenu(HTREEITEM hItem, + HMENU hMenu); +BOOL CALLBACK GroupAddToListProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); +BOOL CALLBACK AgentAddToListProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); +BOOL BuildLineList(HWND hWnd, + DWORD dwDeviceID); +BOOL BuildAddressList(HWND hWnd, + HWND hParentWnd, + DWORD dwDeviceID); +BOOL InitializeTapi(); +BOOL CleanUp(); +BOOL UpdateGroupLeaf(PGROUP pGroup); +BOOL DoAgentView(); +BOOL DoGroupView(); +BOOL ReadInFile(); +BOOL WriteToDisk(); + + + +////////////////////////////////////////////////////////////////////////////// +// GLOBALS +////////////////////////////////////////////////////////////////////////////// +ACDGLOBALS g; + +TCHAR gszACDSampleKey[] = TEXT("Software\\Microsoft\\ACDSample"); +TCHAR gszPlacementValue[] = TEXT("WindowPlacement"); +TCHAR gszBarLocation[] = TEXT("BarLocation"); + + + +////////////////////////////////////////////////////////////////////////////// +// +// WinMain() +// +////////////////////////////////////////////////////////////////////////////// +int WINAPI WinMain (HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) +{ + MSG msg; + + // initialize global variables + g.hInstance = hInstance; + g.pAgents = NULL; + g.pGroups = NULL; + + // init tapi stuff + if (!InitializeTapi()) + { + MessageBox(NULL, + TEXT("TAPI could not be initialized.\nVerify that") + TEXT("your machine has TAPI devices installed"), + TEXT("Cannot start ACDSMPL"), + MB_OK); + } + + if (!CreateMainWindow(nCmdShow)) + { + return 0; + } + + // main message loop + while (GetMessage(&msg, NULL, 0, 0)) + { + if (!IsDialogMessage(g.hMainWnd, + &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + return 1; +} + + +///////////////////////////////////////////////////////////////////////////// +// +// CreateMainWindow() +// +////////////////////////////////////////////////////////////////////////////// +BOOL CreateMainWindow (int nCmdShow) +{ + + // InitCommonControls for TreeView control + InitCommonControls(); + + // Create the main window + g.hMainWnd = CreateDialog(g.hInstance, + MAKEINTRESOURCE(IDD_MAINDLG), + NULL, + MainDlgProc); + + if (g.hMainWnd == NULL) + { + return FALSE; + } + + // restore default location + MySetWindow(g.hMainWnd, nCmdShow); + + // store global hwnds + g.hTreeWnd = GetDlgItem(g.hMainWnd, + IDC_TREEWND); + + g.hLogWnd = GetDlgItem(g.hMainWnd, + IDC_EDITWND); + + if ((g.hTreeWnd == FALSE) || (g.hLogWnd == FALSE)) + { + return FALSE; + } + + ResizeWindows(FALSE, 0); + + return TRUE; +} + + +///////////////////////////////////////////////////////////////////////////// +// +// MainDlgProc() +// +////////////////////////////////////////////////////////////////////////////// +LRESULT CALLBACK MainDlgProc (HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + static BOOL bButtonDown = FALSE; + + switch (uMsg) + { + case WM_INITDIALOG: + return TRUE; + + case WM_COMMAND: + { + LRESULT lResult; + + lResult = DoCommand(wParam, lParam); + return lResult; + } + + // button and mousemove messages tracked to move + // the bar between the treeview control and the + // edit control + case WM_LBUTTONDOWN: + { + bButtonDown = TRUE; + SetCapture(hWnd); + return 0; + } + + case WM_LBUTTONUP: + { + bButtonDown = FALSE; + ReleaseCapture(); + return 0; + } + + case WM_MOUSEMOVE: + { + if (bButtonDown) + { + ResizeWindows(TRUE, (DWORD)LOWORD(lParam)); + return 1; + } + break; + } + + case WM_SIZE: + { + ResizeWindows(FALSE, 0); + return 1; + } + + // catch right click in tree view to make + // popup menu + case WM_NOTIFY: + { + LPNMHDR pnmhdr; + POINT pt; + HTREEITEM hItem; + TV_HITTESTINFO hittestinfo; + RECT rc; + + pnmhdr = (LPNMHDR)lParam; + + // make sure it's a right click and it's in the treeview + if ((pnmhdr->code != NM_RCLICK) || (pnmhdr->hwndFrom != g.hTreeWnd)) + { + break; + } + + GetCursorPos(&pt); + GetWindowRect(g.hTreeWnd, + &rc); + + hittestinfo.pt.x = pt.x - rc.left; + hittestinfo.pt.y = pt.y - rc.top; + + // hittest to get the tree view item + hItem = TreeView_HitTest(g.hTreeWnd, + &hittestinfo); + + // only display a menu if the mouse is actually + // over the item (TVHT_ONITEM) + if (hItem == NULL || (!(hittestinfo.flags & TVHT_ONITEM)) ) + { + return TRUE; + } + + // select that item (right clicking will not select + // by default + TreeView_Select(g.hTreeWnd, + hItem, + TVGN_CARET); + + // create the menu + DoPopupMenu(hItem, pt); + + return TRUE; + + + } + + case WM_CLOSE: + + // save the current window location + WriteToDisk(); + CleanUp(); + MySaveWindow(hWnd); + PostQuitMessage(0); + return 1; + + default: + break; + } + return 0; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// ResizeWindows - Handles resizing the two child windows of the +// main window. If bSizeBar is true, then the sizing is happening +// because the user is moving the bar. if bSizeBar is false, the sizing +// is happening because of the WM_SIZE or something like that. +// +//////////////////////////////////////////////////////////////////////////////// +BOOL ResizeWindows(BOOL bSizeBar, DWORD dwBarLocation) +{ + RECT rc, rc2; + int x; + + // is the user moving the bar? + if (!bSizeBar) + { + dwBarLocation = g.dwBarLocation; + } + + GetClientRect(g.hMainWnd, &rc); + + // make sure the bar is in a OK location + if (bSizeBar) + { + if ((LONG)dwBarLocation < GetSystemMetrics(SM_CXSCREEN)/WINDOWSCALEFACTOR) + return FALSE; + + if ((LONG)(rc.right - dwBarLocation) < GetSystemMetrics(SM_CXSCREEN)/WINDOWSCALEFACTOR) + return FALSE; + } + + // save the bar location + g.dwBarLocation = dwBarLocation; + + // get the size of the frame + x = GetSystemMetrics(SM_CXFRAME); + + // move tree windows + MoveWindow(g.hTreeWnd, + 0, + 0, + dwBarLocation, + rc.bottom, + TRUE); + + // get the size of the window (in case move window failed + GetClientRect(g.hTreeWnd, &rc2); + + // move the edit window with respect to the tree window + MoveWindow(g.hLogWnd, + rc2.right-rc2.left+x+SIZEBAR, + 0, + rc.right-(rc2.right-rc2.left)-x-SIZEBAR, + rc.bottom, + TRUE); + + return TRUE; +} + +////////////////////////////////////////////////////////////////////////////// +// +// MySetWindow - reads in the window placement from registry +// and sets the window and bar. +// +////////////////////////////////////////////////////////////////////////////// +void MySetWindow(HWND hWnd, int nCmdShow) +{ + WINDOWPLACEMENT pwp; + HKEY hKey; + DWORD dwDataSize; + DWORD dwDataType; + RECT rc; + + pwp.length = sizeof(WINDOWPLACEMENT); + + // open the key and read in the WINDOWPLACEMENT structure + RegOpenKeyEx(HKEY_CURRENT_USER, + gszACDSampleKey, + 0, + KEY_ALL_ACCESS, + &hKey); + + dwDataSize = sizeof(pwp); + + if ( RegQueryValueEx(hKey, + gszPlacementValue, + 0, + &dwDataType, + (LPBYTE)&pwp, + &dwDataSize) ) + { + // if it fails, default + ShowWindow(g.hMainWnd, nCmdShow); + GetWindowRect(g.hMainWnd, &rc); + g.dwBarLocation = (rc.right - rc.left) / 2; + } + else + { + // if it succeeds, set the window and bar + dwDataSize = sizeof(DWORD); + + if (RegQueryValueEx(hKey, + gszBarLocation, + 0, + &dwDataType, + (LPBYTE)&g.dwBarLocation, + &dwDataSize)) + { + g.dwBarLocation = (pwp.rcNormalPosition.right - pwp.rcNormalPosition.left) / 2; + } + + SetWindowPlacement(g.hMainWnd, &pwp); + } + + + RegCloseKey( hKey ); +} + +////////////////////////////////////////////////////////////////////////////// +// +// MySaveWindow() - save the current window placement and bar +// +////////////////////////////////////////////////////////////////////////////// +void MySaveWindow(HWND hWnd) +{ + WINDOWPLACEMENT pwp; + HKEY hKey; + DWORD dwDisposition; + + + pwp.length = sizeof(WINDOWPLACEMENT); + + // get and save + GetWindowPlacement(hWnd, &pwp); + + RegCreateKeyEx(HKEY_CURRENT_USER, + gszACDSampleKey, + 0, + TEXT(""), + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + 0, + &hKey, + &dwDisposition); + + RegSetValueEx(hKey, + gszPlacementValue, + 0, + REG_BINARY, + (LPBYTE)&pwp, + sizeof(WINDOWPLACEMENT)); + + RegSetValueEx(hKey, + gszBarLocation, + 0, + REG_DWORD, + (LPBYTE)&g.dwBarLocation, + sizeof(DWORD)); + + RegCloseKey( hKey ); + +} + + +////////////////////////////////////////////////////////////////////////////// +// +// AddItemToTree +// +// add a new leaf to the tree +// +////////////////////////////////////////////////////////////////////////////// +HTREEITEM AddItemToTree(HTREEITEM hParent, + LPTSTR lpszName, + LPARAM lParam, + HTREEITEM * phItem) +{ + TV_ITEM tvi; + TV_INSERTSTRUCT tvins; + HTREEITEM hti; + + tvi.mask = TVIF_TEXT | TVIF_PARAM; + + // Set the text of the item. + tvi.pszText = lpszName; + tvi.cchTextMax = lstrlen(lpszName) * sizeof(TCHAR); + + // Save the pointer to the buffer + tvi.lParam = lParam; + + tvins.item = tvi; + tvins.hInsertAfter = TVI_SORT; + + // Set the parent item + tvins.hParent = hParent; + + // Add the item to the tree-view control. + hti = (HTREEITEM) SendMessage(g.hTreeWnd, + TVM_INSERTITEM, + 0, + (LPARAM) (LPTV_INSERTSTRUCT) &tvins); + + // save hitem + if (phItem) + { + *phItem = hti; + } + + // select the item so it has focus + TreeView_Select(g.hTreeWnd, + hti, + TVGN_CARET); + + return hti; +} + +////////////////////////////////////////////////////////////////////////////// +// +// DoPopupMenu(HTREEITEM hItem, +// POINT pt) +// +// hItem - item to create menu for +// pt - location of mouse so we can create menu where it is +// +// creates a popup menu, depending on what kind of item is selected +// +////////////////////////////////////////////////////////////////////////////// +BOOL DoPopupMenu(HTREEITEM hItem, POINT pt) +{ + + HMENU hMenu; + TV_ITEM tvi; + TCHAR szNewGroup[] = TEXT("&New Group..."); + TCHAR szNewAgent[] = TEXT("New &Agent..."); + TCHAR szAddAgent[] = TEXT("A&dd Agent..."); + TCHAR szGroupProperties[] = TEXT("&Group Properties..."); + TCHAR szAgentStatus[] = TEXT("Agent Status..."); + TCHAR szAddGroup[] = TEXT("Add Group..."); + TCHAR szAgentProperties[] = TEXT("Agent Properties..."); + TCHAR szGroupDelete[] = TEXT("Group Delete"); + TCHAR szAgentDelete[] = TEXT("Agent Delete"); + TCHAR szSignIn[] = TEXT("Agent Sign In"); + TCHAR szSignOut[] = TEXT("Agent Sign Out"); + + // get the selected item + g.hTreeItemWithMenu = hItem; + + // create the menu + hMenu = CreatePopupMenu(); + + // get the lParam, which is a pointer to the item + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + tvi.hItem = hItem; + + TreeView_GetItem(g.hTreeWnd, + &tvi); + + if (!tvi.lParam) + { + return TRUE; + } + + switch (((PGROUP)tvi.lParam)->dwKey) + { + // root item + case GROUPROOTKEY: + + AppendMenu(hMenu, + MF_ENABLED | MF_STRING, + IDM_NEWGROUP, + szNewGroup); + break; + + // root item + case AGENTROOTKEY: + + AppendMenu(hMenu, + MF_ENABLED | MF_STRING, + IDM_NEWAGENT, + szNewAgent); + break; + // group leaf + case GROUPKEY: + + AppendMenu(hMenu, + MF_ENABLED | MF_STRING, + (UINT)IDM_GROUPADDTOLIST, + szAddAgent); + + AppendMenu(hMenu, + MF_ENABLED | MF_STRING, + (UINT)IDM_GROUPAGENTSTATUS, + szAgentStatus); + + AppendMenu(hMenu, + MF_ENABLED | MF_STRING, + IDM_GROUPPROPERTIES, + szGroupProperties); + + AppendMenu(hMenu, + MF_ENABLED | MF_STRING, + IDM_GROUPDELETE, + szGroupDelete); + + break; + // agent leaf + case AGENTKEY: + + AppendMenu(hMenu, + MF_ENABLED | MF_STRING, + (UINT)IDM_AGENTADDTOLIST, + szAddGroup); + + AppendMenu(hMenu, + MF_ENABLED | MF_STRING, + IDM_AGENTPROPERTIES, + szAgentProperties); + + AppendMenu(hMenu, + MF_ENABLED | MF_STRING, + IDM_AGENTDELETE, + szAgentDelete); + + break; + + default: + break; + } + + // actually show menu + TrackPopupMenu(hMenu, + TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, + pt.x, + pt.y, + 0, + g.hMainWnd, + NULL); + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// LRESULT DoCommand(WPARAM wParam, LPARAM lParam) +// handle WM_COMMAND messages for MainDlgProc +// +/////////////////////////////////////////////////////////////////////////////// +LRESULT DoCommand(WPARAM wParam, LPARAM lParam) +{ + switch (LOWORD(wParam)) + { + // New - create a new tree, so just init + // the items and return + case ID_FILE_NEW: + DoGroupView(); + return 1; + + // Open - read in a file + case ID_FILE_OPEN: + ReadInFile(); + return 1; + + case ID_FILE_EXIT: + // save the current window location + WriteToDisk(); + CleanUp(); + MySaveWindow(g.hMainWnd); + PostQuitMessage(0); + return 1; + + // new group + case ID_EDIT_ADDGROUP: + case IDM_NEWGROUP: + DialogBox(g.hInstance, + MAKEINTRESOURCE(IDD_ADD), + g.hTreeWnd, + AddGroupDlgProc); + + return 1; + + // new agent + case ID_EDIT_ADDAGENT: + case IDM_NEWAGENT: + DialogBox(g.hInstance, + MAKEINTRESOURCE(IDD_ADDAGENT), + g.hTreeWnd, + AddAgentDlgProc); + return 1; + + // properties + case IDM_GROUPPROPERTIES: + DialogBox(g.hInstance, + MAKEINTRESOURCE(IDD_ADD), + g.hMainWnd, + ChangeGroupDlgProc); + + return 1; + + // properties + case IDM_AGENTPROPERTIES: + DialogBox(g.hInstance, + MAKEINTRESOURCE(IDD_ADDAGENT), + g.hMainWnd, + ChangeAgentDlgProc); + + return 1; + + // delete + case IDM_GROUPDELETE: + case IDM_AGENTDELETE: + { + DeleteLeafAndStruct(g.hTreeItemWithMenu); + + return 1; + } + + + // add to list + case IDM_GROUPADDTOLIST: + DialogBoxParam(g.hInstance, + MAKEINTRESOURCE(IDD_ADDTOLIST), + g.hMainWnd, + GroupAddToListProc, + TRUE); + + return 1; + + // add to list + case IDM_AGENTADDTOLIST: + DialogBoxParam(g.hInstance, + MAKEINTRESOURCE(IDD_ADDTOLIST), + g.hMainWnd, + AgentAddToListProc, + FALSE); + + return 1; + + case ID_VIEW_GROUP: + DoGroupView(); + return 1; + + case ID_VIEW_AGENT: + DoAgentView(); + return 1; + + default: + break; + + } + + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// +// AddGroupDlgProc - Window proc for the add agent/group dialog box +// +///////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL CALLBACK AddGroupDlgProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + + // set text appropriately + SetWindowText(hWnd, + TEXT("Add Group")); + + BuildLineList(GetDlgItem(hWnd, + IDC_LINECOMBO), + 0); + + BuildAddressList(GetDlgItem(hWnd, + IDC_ADDRESSCOMBO), + hWnd, + 0); + + // set focus on first control + SetFocus(GetDlgItem(hWnd, + IDC_NAME)); + + return 0; + + case WM_COMMAND: + + switch (LOWORD(wParam)) + { + case IDC_LINECOMBO: + { + if (HIWORD(wParam) == CBN_SELENDOK) + { + // need to redo addresses + BuildAddressList(GetDlgItem(hWnd, + IDC_ADDRESSCOMBO), + hWnd, + 0); + + return 1; + } + + return 0; + } + case IDOK: + { + TCHAR szName[128]; + PGROUP pGroup; + DWORD dwLine, dwAddress; + int item; + + // get info + SendDlgItemMessage(hWnd, + IDC_NAME, + WM_GETTEXT, + 128, + (LPARAM)szName); + + item = SendDlgItemMessage(hWnd, + IDC_LINECOMBO, + CB_GETCURSEL, + 0, + 0); + + dwLine = (DWORD)SendDlgItemMessage(hWnd, + IDC_LINECOMBO, + CB_GETITEMDATA, + item, + 0); + + dwAddress = (DWORD)SendDlgItemMessage(hWnd, + IDC_ADDRESSCOMBO, + CB_GETCURSEL, + 0, + 0); + + // create a structure + pGroup = AddGroup(szName, + dwLine, + dwAddress); + + if (!pGroup) + { + return 1; + } + + if (g.bGroupView) + { + // add it to the tree + AddItemToTree(g.hGroupParent, + pGroup->lpszName, + (LPARAM)pGroup, + &pGroup->hItem); + } + + EndDialog(hWnd, 1); + return 1; + } + + case IDCANCEL: + { + EndDialog(hWnd, 0); + return 1; + } + + default: + return 0; + + } + + } + + return 0; +} + + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// +// AddAgentDlgProc - Window proc for the add agent/group dialog box +// +///////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL CALLBACK AddAgentDlgProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + + BuildLineList(GetDlgItem(hWnd, + IDC_LINECOMBO), + 0); + + // set focus on first control + SetFocus(GetDlgItem(hWnd, + IDC_NAME)); + + return 0; + + case WM_COMMAND: + + switch (LOWORD(wParam)) + { + case IDOK: + { + TCHAR szName[128]; + TCHAR szNumber[128]; + PAGENT pAgent; + DWORD dwLine; + int item; + + // get info + SendDlgItemMessage(hWnd, + IDC_NAME, + WM_GETTEXT, + 128, + (LPARAM)szName); + + SendDlgItemMessage(hWnd, + IDC_DESTADDRESS, + WM_GETTEXT, + 128, + (LPARAM)szNumber); + + item = SendDlgItemMessage(hWnd, + IDC_LINECOMBO, + CB_GETCURSEL, + 0, + 0); + + dwLine = (DWORD)SendDlgItemMessage(hWnd, + IDC_LINECOMBO, + CB_GETITEMDATA, + item, + 0); + + // create a structure + pAgent = AddAgent(szName, + szNumber, + dwLine); + + if (!pAgent) + { + return 1; + } + + + if (!g.bGroupView) + { + // add it to the tree + AddItemToTree(g.hAgentParent, + pAgent->lpszName, + (LPARAM)pAgent, + &pAgent->hItem); + } + + EndDialog(hWnd, 1); + return 1; + } + + case IDCANCEL: + { + EndDialog(hWnd, 0); + return 1; + } + + default: + return 0; + + } + } + return 0; +} + +////////////////////////////////////////////////////////////////////////////////// +// +// ChangeGroupDlgProc - Window proc for the change (properties) dialog box +// for agents/groups +// +////////////////////////////////////////////////////////////////////////////////// +BOOL CALLBACK ChangeGroupDlgProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + static TV_ITEM tvi; + + switch (uMsg) + { + case WM_INITDIALOG: + + // set text appropriately + SetWindowText(hWnd, + TEXT("Change Group")); + + // get PGROUP and set edit controls + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + tvi.hItem = g.hTreeItemWithMenu; + + TreeView_GetItem(g.hTreeWnd, + &tvi); + + SendDlgItemMessage(hWnd, + IDC_NAME, + WM_SETTEXT, + 0, + (LPARAM)((PGROUP)tvi.lParam)->lpszName); + + BuildLineList(GetDlgItem(hWnd, + IDC_LINECOMBO), + (((PGROUP)tvi.lParam)->dwDeviceID)); + + + BuildAddressList(GetDlgItem(hWnd, + IDC_ADDRESSCOMBO), + hWnd, + (((PGROUP)tvi.lParam)->dwAddress)); + + SetFocus(GetDlgItem(hWnd, + IDC_NAME)); + + return 0; + + case WM_COMMAND: + + switch (LOWORD(wParam)) + { + case IDC_LINECOMBO: + { + if (HIWORD(wParam) == CBN_SELENDOK) + { + // need to redo addresses + BuildAddressList(GetDlgItem(hWnd, + IDC_ADDRESSCOMBO), + hWnd, + 0); + + return 1; + } + + return 0; + } + case IDOK: + { + TCHAR szName[128]; + PGROUP pGroup; + + // get info + SendDlgItemMessage(hWnd, + IDC_NAME, + WM_GETTEXT, + 128, + (LPARAM)szName); + + // get struct + pGroup = (PGROUP)tvi.lParam; + + /// get device and address + pGroup->dwDeviceID = SendDlgItemMessage(hWnd, + IDC_LINECOMBO, + CB_GETCURSEL, + 0, + 0); + + pGroup->dwDeviceID = SendDlgItemMessage(hWnd, + IDC_LINECOMBO, + CB_GETITEMDATA, + (WPARAM)pGroup->dwDeviceID, + 0); + + pGroup->dwAddress = SendDlgItemMessage(hWnd, + IDC_ADDRESSCOMBO, + CB_GETCURSEL, + 0, + 0); + + // save new info and free old info + ACDFree(pGroup->lpszName); + pGroup->lpszName = ACDAlloc((lstrlen(szName) + 1) * sizeof(TCHAR)); + lstrcpy(pGroup->lpszName, szName); + + // update item name + tvi.mask = TVIF_TEXT; + tvi.pszText = szName; + tvi.cchTextMax = lstrlen(szName) * sizeof(TCHAR); + TreeView_SetItem(g.hTreeWnd, + &tvi); + + EndDialog(hWnd, 1); + return 1; + } + + case IDCANCEL: + { + EndDialog(hWnd, 0); + return 1; + } + + default: + return 0; + + } + } + return 0; +} + + +////////////////////////////////////////////////////////////////////////////////// +// +// ChangeGroupDlgProc - Window proc for the change (properties) dialog box +// for agents/groups +// +////////////////////////////////////////////////////////////////////////////////// +BOOL CALLBACK ChangeAgentDlgProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + static TV_ITEM tvi; + + switch (uMsg) + { + case WM_INITDIALOG: + + // set text appropriately + SetWindowText(hWnd, + TEXT("Change Agent")); + + // get PGROUP and set edit controls + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + tvi.hItem = g.hTreeItemWithMenu; + + TreeView_GetItem(g.hTreeWnd, + &tvi); + + SendDlgItemMessage(hWnd, + IDC_NAME, + WM_SETTEXT, + 0, + (LPARAM)((PAGENT)tvi.lParam)->lpszName); + + SendDlgItemMessage(hWnd, + IDC_DESTADDRESS, + WM_SETTEXT, + 0, + (LPARAM)((PAGENT)tvi.lParam)->lpszNumber); + + BuildLineList(GetDlgItem(hWnd, + IDC_LINECOMBO), + (((PAGENT)tvi.lParam)->dwDeviceID)); + + SetFocus(GetDlgItem(hWnd, + IDC_NAME)); + + return 0; + + case WM_COMMAND: + + switch (LOWORD(wParam)) + { + case IDOK: + { + TCHAR szName[128]; + TCHAR szNumber[128]; + PAGENT pAgent; + + // get info + SendDlgItemMessage(hWnd, + IDC_NAME, + WM_GETTEXT, + 128, + (LPARAM)szName); + + SendDlgItemMessage(hWnd, + IDC_DESTADDRESS, + WM_GETTEXT, + 128, + (LPARAM)szNumber); + + // get struct + pAgent = (PAGENT)tvi.lParam; + + /// get device and address + pAgent->dwDeviceID = SendDlgItemMessage(hWnd, + IDC_LINECOMBO, + CB_GETCURSEL, + 0, + 0); + + pAgent->dwDeviceID = SendDlgItemMessage(hWnd, + IDC_LINECOMBO, + CB_GETITEMDATA, + (WPARAM)pAgent->dwDeviceID, + 0); + + // save new info and free old info + ACDFree(pAgent->lpszName); + pAgent->lpszName = ACDAlloc((lstrlen(szName) + 1) * sizeof(TCHAR)); + lstrcpy(pAgent->lpszName, szName); + + + ACDFree(pAgent->lpszNumber); + pAgent->lpszNumber = ACDAlloc((lstrlen(szNumber) + 1) * sizeof(TCHAR)); + lstrcpy(pAgent->lpszNumber, szNumber); + + // update item name + tvi.mask = TVIF_TEXT; + tvi.pszText = szName; + tvi.cchTextMax = lstrlen(szName) * sizeof(TCHAR); + TreeView_SetItem(g.hTreeWnd, + &tvi); + + EndDialog(hWnd, 1); + return 1; + } + + case IDCANCEL: + { + EndDialog(hWnd, 0); + return 1; + } + + default: + return 0; + + } + } + return 0; +} + +////////////////////////////////////////////////////////////////////////////////////// +// +// AddToList() - Window proc for Add Agent To Group and Add Group To Agent +// dialog box +// +////////////////////////////////////////////////////////////////////////////////////// +BOOL CALLBACK GroupAddToListProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + static PGROUP pGroup; + PAGENT pAgent; + PLISTITEM pList; + TV_ITEM tvi; + DWORD dwListBox; + BOOL bFound; + int item; + TCHAR szBuffer[128]; + + + switch (uMsg) + { + case WM_INITDIALOG: + + // get the item in question + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + tvi.hItem = g.hTreeItemWithMenu; + + TreeView_GetItem(g.hTreeWnd, + &tvi); + + pGroup = (PGROUP)tvi.lParam; + + // init lists + if (pGroup) + { + // initialize text in dialog + wsprintf(szBuffer, TEXT("Add To %s"), pGroup->lpszName); + + SetWindowText(hWnd, + TEXT("Add To Group")); + + SetDlgItemText(hWnd, + IDC_STATICNOTINLIST, + TEXT("Not in Group")); + SetDlgItemText(hWnd, + IDC_STATICINLIST, + TEXT("Group Members")); + + pAgent = g.pAgents; + + // walk list and initialize list boxes + while (pAgent) + { + pList = pGroup->pAgentList; + + bFound = FALSE; + + while (pList) + { + if (pList->pAgent == pAgent) + { + bFound = TRUE; + break; + } + + pList = pList->pNext; + } + + // if it was found, it is already a member of + // the group + if (bFound) + { + dwListBox = IDC_LIST2; + } + else + { + dwListBox = IDC_LIST1; + } + + // add to correct list box + item = SendDlgItemMessage(hWnd, + dwListBox, + LB_ADDSTRING, + 0, + (LPARAM)pAgent->lpszName); + + // set the item data to be the item so we can get back it. + if (item != LB_ERR) + { + SendDlgItemMessage(hWnd, + dwListBox, + LB_SETITEMDATA, + (WPARAM)item, + (LPARAM)pAgent); + } + + pAgent = pAgent->pNext; + } + } + + + + return 1; + + case WM_COMMAND: + + switch (LOWORD(wParam)) + { + case IDC_ADD: + { + // get the item + item = SendDlgItemMessage(hWnd, + IDC_LIST1, + LB_GETCURSEL, + 0, + 0); + + if (item == 0) + { + if (!SendDlgItemMessage(hWnd, + IDC_LIST1, + LB_GETSEL, + (WPARAM)item, + 0)) + { + item == -1; + } + } + + if (item != -1) + { + // get the PAGENT associated with it + pAgent = (PAGENT)SendDlgItemMessage(hWnd, + IDC_LIST1, + LB_GETITEMDATA, + (WPARAM)item, + 0); + + // delete it from this listbox + SendDlgItemMessage(hWnd, + IDC_LIST1, + LB_DELETESTRING, + (WPARAM)item, + 0); + + // add it to this list box + item = SendDlgItemMessage(hWnd, + IDC_LIST2, + LB_ADDSTRING, + 0, + (LPARAM)pAgent->lpszName); + + // set the item data again + SendDlgItemMessage(hWnd, + IDC_LIST2, + LB_SETITEMDATA, + item, + (WPARAM)pAgent); + + // add it to the group's list + InsertIntoGroupList(pGroup, + pAgent); + + return 1; + + } + } + break; + + case IDC_REMOVE: + { + // get the item + item = SendDlgItemMessage(hWnd, + IDC_LIST2, + LB_GETCURSEL, + 0, + 0); + + if (item == 0) + { + if (!SendDlgItemMessage(hWnd, + IDC_LIST2, + LB_GETSEL, + (WPARAM)item, + 0)) + { + item == -1; + } + } + + if (item != -1) + { + // get the struct associated with it + pAgent = (PAGENT)SendDlgItemMessage(hWnd, + IDC_LIST2, + LB_GETITEMDATA, + (WPARAM)item, + 0); + + // delete it from this list + SendDlgItemMessage(hWnd, + IDC_LIST2, + LB_DELETESTRING, + (WPARAM)item, + 0); + + // add it to this list + item = SendDlgItemMessage(hWnd, + IDC_LIST1, + LB_ADDSTRING, + 0, + (LPARAM)pAgent->lpszName); + + // set the item data + SendDlgItemMessage(hWnd, + IDC_LIST1, + LB_SETITEMDATA, + item, + (WPARAM)pAgent); + + // remove it from the lists + RemoveFromGroupList(pGroup, + pAgent); + + return 1; + + } + + } + break; + + + // bug idcancel doesn't cancel + case IDOK: + case IDCANCEL: + { + UpdateGroupLeaf(pGroup); + + EndDialog(hWnd, 1); + return 1; + } + + default: + return 0; + + } + + } + + return 0; +} + + +BOOL CALLBACK AgentAddToListProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + static PAGENT pAgent; + PGROUP pGroup; + PLISTITEM pList; + TV_ITEM tvi; + DWORD dwListBox; + BOOL bFound; + int item; + TCHAR szBuffer[128]; + + + switch (uMsg) + { + case WM_INITDIALOG: + + // get the item in question + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + tvi.hItem = g.hTreeItemWithMenu; + + TreeView_GetItem(g.hTreeWnd, + &tvi); + + pAgent = (PAGENT)tvi.lParam; + + // init lists + if (pAgent) + { + // initialize text in dialog + wsprintf(szBuffer, TEXT("Add To %s"), pAgent->lpszName); + + SetWindowText(hWnd, + TEXT("Add To Agent")); + + SetDlgItemText(hWnd, + IDC_STATICNOTINLIST, + TEXT("Not Member Of")); + SetDlgItemText(hWnd, + IDC_STATICINLIST, + TEXT("Member Of")); + + pGroup = g.pGroups; + + // walk list and initialize list boxes + while (pGroup) + { + pList = pGroup->pAgentList; + + bFound = FALSE; + + while (pList) + { + if (pList->pAgent == pAgent) + { + bFound = TRUE; + break; + } + + pList = pList->pNext; + } + + // if it was found, it is already a member of + // the group + if (bFound) + { + dwListBox = IDC_LIST2; + } + else + { + dwListBox = IDC_LIST1; + } + + // add to correct list box + item = SendDlgItemMessage(hWnd, + dwListBox, + LB_ADDSTRING, + 0, + (LPARAM)pGroup->lpszName); + + // set the item data to be the item so we can get back it. + if (item != LB_ERR) + { + SendDlgItemMessage(hWnd, + dwListBox, + LB_SETITEMDATA, + (WPARAM)item, + (LPARAM)pGroup); + } + + pGroup = pGroup->pNext; + } + } + + + + return 1; + + case WM_COMMAND: + + switch (LOWORD(wParam)) + { + case IDC_ADD: + { + // get the item + item = SendDlgItemMessage(hWnd, + IDC_LIST1, + LB_GETCURSEL, + 0, + 0); + + if (item == 0) + { + if (!SendDlgItemMessage(hWnd, + IDC_LIST1, + LB_GETSEL, + (WPARAM)item, + 0)) + { + item == -1; + } + } + + if (item != -1) + { + // get the PGROUP associated with it + pGroup = (PGROUP)SendDlgItemMessage(hWnd, + IDC_LIST1, + LB_GETITEMDATA, + (WPARAM)item, + 0); + + // delete it from this listbox + SendDlgItemMessage(hWnd, + IDC_LIST1, + LB_DELETESTRING, + (WPARAM)item, + 0); + + // add it to this list box + item = SendDlgItemMessage(hWnd, + IDC_LIST2, + LB_ADDSTRING, + 0, + (LPARAM)pGroup->lpszName); + + // set the item data again + SendDlgItemMessage(hWnd, + IDC_LIST2, + LB_SETITEMDATA, + item, + (WPARAM)pGroup); + + // add it to the item's list + InsertIntoGroupList(pGroup, + pAgent); + + return 1; + + } + } + break; + + case IDC_REMOVE: + { + // get the item + item = SendDlgItemMessage(hWnd, + IDC_LIST2, + LB_GETCURSEL, + 0, + 0); + + if (item == 0) + { + if (!SendDlgItemMessage(hWnd, + IDC_LIST2, + LB_GETSEL, + (WPARAM)item, + 0)) + { + item == -1; + } + } + + if (item != -1) + { + // get the struct associated with it + pGroup = (PGROUP)SendDlgItemMessage(hWnd, + IDC_LIST2, + LB_GETITEMDATA, + (WPARAM)item, + 0); + + // delete it from this list + SendDlgItemMessage(hWnd, + IDC_LIST2, + LB_DELETESTRING, + (WPARAM)item, + 0); + + // add it to this list + item = SendDlgItemMessage(hWnd, + IDC_LIST1, + LB_ADDSTRING, + 0, + (LPARAM)pGroup->lpszName); + + // set the item data + SendDlgItemMessage(hWnd, + IDC_LIST1, + LB_SETITEMDATA, + item, + (WPARAM)pGroup); + + // remove it from the lists + RemoveFromGroupList(pGroup, + pAgent); + + return 1; + + } + + } + break; + + + // bug idcancel doesn't cancel + case IDOK: + case IDCANCEL: + { + EndDialog(hWnd, 1); + return 1; + } + + default: + return 0; + } + } + return 0; +} + +////////////////////////////////////////////////////////////// +// +// BOOL DeleteLeafAndStruct(HTREEITEM hItem) +// delete hItem from the tree and deleted associated +// structure +// +////////////////////////////////////////////////////////////// +BOOL DeleteLeafAndStruct(HTREEITEM hItem) +{ + TV_ITEM tvi; + + // get the item + tvi.mask = TVIF_PARAM; + tvi.hItem = hItem; + + TreeView_GetItem(g.hTreeWnd, + &tvi); + + // delete the structure + if (((PGENERICSTRUCT)tvi.lParam)->dwKey == GROUPKEY) + { + DeleteGroup((PGROUP)tvi.lParam); + } + else + { + DeleteAgent((PAGENT)tvi.lParam); + } + + // remove it from the tree + TreeView_DeleteItem(g.hTreeWnd, + hItem); + + return TRUE; +} + + +//////////////////////////////////////////////////////////////////// +// +// BOOL BuildLineList(HWND hWnd, +// DWORD dwDeviceID) +// +// Fill in ComboBox with names of all available TAPI +// devices +// +//////////////////////////////////////////////////////////////////// +BOOL BuildLineList(HWND hWnd, + DWORD dwDeviceID) +{ + DWORD dwDev; + LPLINEDEVCAPS pLineDevCaps; + int item; + BOOL bSet = FALSE; + + // clear dropdown box + SendMessage(hWnd, + CB_RESETCONTENT, + 0, + 0); + + // loop through all devices + for (dwDev = 0; dwDev < g.dwNumDevs; dwDev++) + { + pLineDevCaps = LineGetDevCaps(g.hLineApp, + dwDev); + + // add the string to to list + if (pLineDevCaps == NULL || pLineDevCaps->dwLineNameSize == 0) + { + item = SendMessage(hWnd, + CB_ADDSTRING, + 0, + (LPARAM)TEXT("NoName")); + } + else + { + item = SendMessage(hWnd, + CB_ADDSTRING, + 0, + (LPARAM)((LPTSTR)((LPBYTE)pLineDevCaps + pLineDevCaps->dwLineNameOffset))); + } + + // save the device ID + SendMessage(hWnd, + CB_SETITEMDATA, + item, + dwDev); + + // if this is the device we are looking for + // set it to be selected + if (dwDev == dwDeviceID) + { + SendMessage(hWnd, + CB_SETCURSEL, + (WPARAM)item, + 0); + + bSet = TRUE; + } + + if (pLineDevCaps != NULL) + { + ACDFree((HLOCAL)pLineDevCaps); + } + } + + // if we didn't set the selection, default + if (!bSet) + { + SendMessage(hWnd, + CB_SETCURSEL, + 0, + 0); + } + + return TRUE; +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// BOOL BuildAddressList() +// +// Fill combo box with list of addresses on selected device ID +// +/////////////////////////////////////////////////////////////////////////////// +BOOL BuildAddressList(HWND hWnd, + HWND hParentWnd, + DWORD dwAddress) +{ + TCHAR szBuffer[32]; + LPLINEDEVCAPS pLineDevCaps; + LPLINEADDRESSCAPS pLineAddressCaps; + DWORD dwCurAddress, dwDeviceID; + int iCurSel; + + // clear box + SendMessage(hWnd, + CB_RESETCONTENT, + 0, + 0); + + // get the current selected device + iCurSel = SendDlgItemMessage(hParentWnd, + IDC_LINECOMBO, + CB_GETCURSEL, + 0, + 0); + + // get associated deviceid + dwDeviceID = (DWORD)SendDlgItemMessage(hParentWnd, + IDC_LINECOMBO, + CB_GETITEMDATA, + (WPARAM)iCurSel, + 0); + + pLineDevCaps = LineGetDevCaps(g.hLineApp, + dwDeviceID); + + // loop through all addresses + for (dwCurAddress = 0; dwCurAddress < pLineDevCaps->dwNumAddresses; dwCurAddress++) + { + pLineAddressCaps = LineGetAddressCaps(g.hLineApp, + dwDeviceID, + dwCurAddress); + + // add name to list box + if (pLineAddressCaps == NULL || pLineAddressCaps->dwAddressSize == 0) + { + wsprintf(szBuffer, TEXT("Address %d"), dwCurAddress); + + SendMessage(hWnd, + CB_ADDSTRING, + 0, + (LPARAM)szBuffer); + } + else + { + SendMessage(hWnd, + CB_ADDSTRING, + 0, + (LPARAM)((LPTSTR)((LPBYTE)pLineAddressCaps + pLineAddressCaps->dwAddressOffset))); + } + + ACDFree((HLOCAL)pLineAddressCaps); + } + + SendMessage(hWnd, + CB_SETCURSEL, + (WPARAM)dwAddress, + 0); + + ACDFree(pLineDevCaps); + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////// +// +// BOOL UpdateGroupLeaf(PGROUP pStruct) +// +// Updates a group in the tree view when a new agent is added to that +// group +// +/////////////////////////////////////////////////////////////////////////// +BOOL UpdateGroupLeaf(PGROUP pStruct) +{ + HTREEITEM hItem; + PLISTITEM pItem; + TV_ITEM tvi; + + // get the item's first child + hItem = TreeView_GetChild(g.hTreeWnd, + pStruct->hItem); + + + while (hItem) + { + // delete all childre + TreeView_DeleteItem(g.hTreeWnd, + hItem); + hItem = TreeView_GetChild(g.hTreeWnd, + pStruct->hItem); + + } + + pItem = pStruct->pAgentList; + + // walk the agent list + while (pItem) + { + // add all the agents + hItem = AddItemToTree(pStruct->hItem, + ((PAGENT)pItem->pAgent)->lpszName, + (LPARAM)NULL, + (HTREEITEM *)NULL); + + + // if currently logged into that group + /// bold that item + if (pItem->bLoggedIn) + { + tvi.mask = TVIF_STATE | TVIF_HANDLE; + tvi.hItem = hItem; + tvi.state = TVIS_BOLD; + tvi.stateMask = TVIS_BOLD; + + TreeView_SetItem(g.hTreeWnd, + &tvi); + } + + pItem = pItem->pNext; + } + + + return TRUE; +} + + +/////////////////////////////////////////////////////////////////////// +// +// BOOL DoGroupView() +// +// Display the tree in a "group view" (show groups, and under the +// group, the agents that can log into that group) +// +/////////////////////////////////////////////////////////////////////// +BOOL DoGroupView() +{ + PGROUP pGroupParent, pGroup; + TCHAR szGroupParentName[] = TEXT("Groups"); + HTREEITEM hItem; + TV_ITEM tvi; + + g.bGroupView = TRUE; + + // get the root + hItem = TreeView_GetRoot(g.hTreeWnd); + + // free resources allocated for root + if (hItem) + { + tvi.mask = TVIF_PARAM | TVIF_HANDLE; + tvi.hItem = hItem; + TreeView_GetItem(g.hTreeWnd, + &tvi); + + ACDFree((PAGENT)tvi.lParam); + } + + // clear tree + TreeView_DeleteAllItems(g.hTreeWnd); + + // alloc memory for the structure for the Group parent + pGroupParent = (PGROUP)ACDAlloc(sizeof(GROUP)); + + // alloc memory and copy the fixed name + pGroupParent->lpszName = (LPTSTR)ACDAlloc((lstrlen(szGroupParentName) + 1) * sizeof(TCHAR)); + pGroupParent->dwKey = GROUPROOTKEY; + + lstrcpy(pGroupParent->lpszName, szGroupParentName); + + // add it to the tree + g.hGroupParent = AddItemToTree(TVI_ROOT, + pGroupParent->lpszName, + (LPARAM)pGroupParent, + &pGroupParent->hItem); + + pGroup = g.pGroups; + + // walk groups and add them to tree + while (pGroup) + { + AddItemToTree(g.hGroupParent, + pGroup->lpszName, + (LPARAM)pGroup, + &pGroup->hItem); + + UpdateGroupLeaf(pGroup); + + pGroup = pGroup->pNext; + } + + return TRUE; +} + + +//////////////////////////////////////////////////////////////////// +// +// BOOL DoAgentView() +// +// Displays the tree in an "agent view" +// +//////////////////////////////////////////////////////////////////// +BOOL DoAgentView() +{ + PAGENT pAgentParent,pAgent; + TCHAR szAgentParentName[] = TEXT("Agents"); + HTREEITEM hItem; + TV_ITEM tvi; + + g.bGroupView = TRUE; + + // get root, free resources + // and clear tree + hItem = TreeView_GetRoot(g.hTreeWnd); + + if (hItem) + { + tvi.mask = TVIF_PARAM | TVIF_HANDLE; + tvi.hItem = hItem; + TreeView_GetItem(g.hTreeWnd, + &tvi); + + ACDFree((PGROUP)tvi.lParam); + } + + TreeView_DeleteAllItems(g.hTreeWnd); + + // alloc memory for the structure for the Agent parent + pAgentParent = (PAGENT)ACDAlloc(sizeof(AGENT)); + + // alloc memory and copy the fixed name + pAgentParent->lpszName = (LPTSTR)ACDAlloc((lstrlen(szAgentParentName) + 1) * sizeof(TCHAR)); + pAgentParent->dwKey = GROUPROOTKEY; + + lstrcpy(pAgentParent->lpszName, szAgentParentName); + + // add it to the tree + g.hAgentParent = AddItemToTree(TVI_ROOT, + pAgentParent->lpszName, + (LPARAM)pAgentParent, + &pAgentParent->hItem); + + pAgent = g.pAgents; + + // walk agents and add all of them + while (pAgent) + { + AddItemToTree(g.hAgentParent, + pAgent->lpszName, + (LPARAM)pAgent, + &pAgent->hItem); + + pAgent = pAgent->pNext; + } + + return TRUE; +} + +////////////////////////////////////////////////////////////////////////////////////// +// +// FOLLOWING ARE ROUTINES TO SAVE AND RESTORE GROUP / AGENT INFORMATION +// +// An INI file has been used for this implementation. +// +// This format is used to make it easy for users to create an INI file that can be +// read in +// +// However, a real implementation +// may want to use the registry, or a private data file to store more detailed and/or +// secure information +// +// + +#define SZGROUPS TEXT("Groups") +#define SZAGENTS TEXT("Agents") +#define SZGROUP TEXT("GROUP") +#define SZAGENT TEXT("AGENT") +#define SZINIFILE TEXT("ACDSMPL.INI") +#define SZGENERAL TEXT("General") +#define SZNUMAGENTS TEXT("NumAgents") +#define SZNUMGROUPS TEXT("NumGroups") + +////////////////////////////////////////////////////////////////////////////// +// +// void MakeAgentIndex(PAGENT * ppAgents) +// +// creates an array of pagents +// +////////////////////////////////////////////////////////////////////////////// +void MakeAgentIndex(PAGENT * ppAgents) +{ + PAGENT pAgent; + + pAgent = g.pAgents; + + while (pAgent) + { + *ppAgents = pAgent; + pAgent = pAgent->pNext; + ppAgents++; + } + +} + +/////////////////////////////////////////////////////////////////////////////// +// +// int GetAgentIndex() +// +// retreives agent index +// +/////////////////////////////////////////////////////////////////////////////// +int GetAgentIndex(PAGENT * ppAgents, + PAGENT pAgent) +{ + DWORD dwCount; + + for (dwCount = 0; dwCount < g.dwNumAgents; dwCount++) + { + if (ppAgents[dwCount] == pAgent) + { + return dwCount; + } + } + + return -1; + +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// BOOL WriteToDisk() +// +// save current group/agent config to acdsmpl.ini +// +/////////////////////////////////////////////////////////////////////////////// +BOOL WriteToDisk() +{ + int i; + PGROUP pGroup; + PAGENT pAgent; + PLISTITEM pEntry; + TCHAR szGroupName[32], szAgentName[32], szLineBuffer[512]; + PAGENT * ppAgents; + + // create an index of agents + ppAgents = (PAGENT *)ACDAlloc(sizeof(PAGENT) * g.dwNumAgents); + MakeAgentIndex(ppAgents); + + pGroup = g.pGroups; + + i = 0; + + // walk groups + while (pGroup) + { + wsprintf(szGroupName, + TEXT("%s%d"), + SZGROUP, + i); + + wsprintf(szLineBuffer, + TEXT("%s,%d,%d"), + pGroup->lpszName, + g.pdwPermIDs[pGroup->dwDeviceID], + pGroup->dwAddress); + + // add group to [groups] section + WritePrivateProfileString(SZGROUPS, + szGroupName, + szLineBuffer, + SZINIFILE); + + pEntry = pGroup->pAgentList; + + // walk agents in group + while (pEntry) + { + wsprintf(szAgentName, + TEXT("%s%d"), + SZAGENT, + GetAgentIndex(ppAgents, + pEntry->pAgent)); + + // write agent index to [groupx] section + WritePrivateProfileString(szGroupName, + szAgentName, + TEXT("1"), + SZINIFILE); + + pEntry = pEntry->pNext; + } + + pGroup = pGroup->pNext; + + i++; + } + + pAgent = g.pAgents; + + i = 0; + + //walk agents + while (pAgent) + { + wsprintf(szAgentName, + TEXT("%s%d"), + SZAGENT, + i); + + wsprintf(szLineBuffer, + TEXT("%s,%s,%lu"), + pAgent->lpszName, + pAgent->lpszNumber, + g.pdwPermIDs[pAgent->dwDeviceID]); + + // write agent to [agents] section + WritePrivateProfileString(SZAGENTS, + szAgentName, + szLineBuffer, + SZINIFILE); + + pAgent = pAgent->pNext; + + i++; + + } + + // save # of agents and groups + wsprintf(szLineBuffer, + TEXT("%lu"), + g.dwNumGroups); + + WritePrivateProfileString(SZGENERAL, + SZNUMGROUPS, + szLineBuffer, + SZINIFILE); + + wsprintf(szLineBuffer, + TEXT("%lu"), + g.dwNumAgents); + + WritePrivateProfileString(SZGENERAL, + SZNUMAGENTS, + szLineBuffer, + SZINIFILE); + + ACDFree(ppAgents); + + return TRUE; +} + + +//////////////////////////////////////////////////////////////////////////////////// +// +// BOOL ReadInFile() +// +// Read in ACDSMPL.INI +// +//////////////////////////////////////////////////////////////////////////////////// +BOOL ReadInFile() +{ + TCHAR szAgentLabel[32], + szGroupLabel[32]; + DWORD dwID, dwAddress, dwNumAgents, dwNumGroups; + DWORD dwCount, dwCount2; + PAGENT * ppAgents = NULL; + LPTSTR lpszName, lpszNumber, lpszDeviceID; + LPTSTR lpszHold, szLineBuffer = NULL; + PGROUP pGroup; + + dwNumAgents = GetPrivateProfileInt(SZGENERAL, + SZNUMAGENTS, + 0, + SZINIFILE); + + dwNumGroups = GetPrivateProfileInt(SZGENERAL, + SZNUMGROUPS, + 0, + SZINIFILE); + + ppAgents = (PAGENT *)ACDAlloc(sizeof(PAGENT) * dwNumAgents); + szLineBuffer = (LPTSTR)ACDAlloc(512 * sizeof(WCHAR)); + + if (!ppAgents || !szLineBuffer) + { + ACDFree(ppAgents); + ACDFree(szLineBuffer); + return FALSE; + } + + lpszHold = szLineBuffer; + + for (dwCount = 0; dwCount < dwNumAgents; dwCount++) + { + wsprintf(szAgentLabel, + TEXT("%s%lu"), + SZAGENT, + dwCount); + + GetPrivateProfileString(SZAGENTS, + szAgentLabel, + TEXT(""), + szLineBuffer, + 512, + SZINIFILE); + + lpszName = (LPTSTR)szLineBuffer; + + while (szLineBuffer && *szLineBuffer) + { + if (*szLineBuffer == TEXT(',')) + { + *szLineBuffer = TEXT('\0'); + szLineBuffer++; + break; + } + + szLineBuffer++; + } + + lpszNumber = (LPTSTR)szLineBuffer; + + while (szLineBuffer && *szLineBuffer) + { + if (*szLineBuffer == TEXT(',')) + { + *szLineBuffer = TEXT('\0'); + szLineBuffer++; + dwID = _wtol(szLineBuffer); + dwID = GetDeviceID(dwID); + + ppAgents[dwCount] = AddAgent(lpszName, + lpszNumber, + dwID); + + break; + } + + szLineBuffer++; + } + + } + + for (dwCount = 0; dwCount < dwNumGroups; dwCount++) + { + wsprintf(szGroupLabel, + TEXT("%s%lu"), + SZGROUP, + dwCount); + + GetPrivateProfileString(SZGROUPS, + szGroupLabel, + TEXT(""), + szLineBuffer, + 512, + SZINIFILE); + + lpszName = (LPTSTR)szLineBuffer; + + while (szLineBuffer && *szLineBuffer) + { + if (*szLineBuffer == TEXT(',')) + { + *szLineBuffer = TEXT('\0'); + szLineBuffer++; + lpszDeviceID = szLineBuffer; + break; + } + + szLineBuffer++; + } + + while (szLineBuffer && *szLineBuffer) + { + if (*szLineBuffer == TEXT(',')) + { + *szLineBuffer = TEXT('\0'); + szLineBuffer++; + + dwAddress = _wtol(szLineBuffer); + + break; + } + + szLineBuffer++; + } + + dwID = _wtol(lpszDeviceID); + dwID = GetDeviceID(dwID); + + + pGroup = AddGroup(lpszName, + dwID, + dwAddress); + + if (!pGroup) + { + continue; + } + + for (dwCount2 = 0; dwCount2 < dwNumAgents; dwCount2++) + { + wsprintf(szAgentLabel, + TEXT("%s%lu"), + SZAGENT, + dwCount2); + + if (GetPrivateProfileString(szGroupLabel, + szAgentLabel, + TEXT(""), + szLineBuffer, + 512, + SZINIFILE) != 0) + { + InsertIntoGroupList(pGroup, + ppAgents[dwCount2]); + } + + } // for dwcount2 + + } // for dwcount + + ACDFree(ppAgents); + ACDFree(lpszHold); + + DoGroupView(); + + return TRUE; +} + + + diff --git a/private/tapi/dev/apps/acd/acdsmpl.h b/private/tapi/dev/apps/acd/acdsmpl.h new file mode 100644 index 000000000..10e93dbbe --- /dev/null +++ b/private/tapi/dev/apps/acd/acdsmpl.h @@ -0,0 +1,192 @@ +#ifndef _ACDSMPL_ +#define _ACDSMPL_ + +#include <windows.h> +#include <commdlg.h> +#include <commctrl.h> +#include <tapi.h> + +/////////////////////////////////////////////////////////////////////////// +// +// STRUCTURES +// +/////////////////////////////////////////////////////////////////////////// + +typedef struct _tagLISTITEM; + +typedef struct +{ + DWORD dwState; + DWORD dwNextState; + DWORD dwActivity; + +} ADDRESSINFO, * PADDRESSINFO; + +typedef struct _tagAGENT +{ + DWORD dwKey; + DWORD dwSize; + struct _tagAGENT * pNext; + struct _tagAGENT * pPrev; + LPTSTR lpszName; + LPTSTR lpszNumber; + HTREEITEM hItem; + DWORD dwDeviceID; + DWORD dwPermID; + HLINE hLine; + DWORD dwNumAddresses; + PADDRESSINFO pAddressInfo; + +} AGENT, * PAGENT; + +typedef struct _tagGROUP +{ + DWORD dwKey; + DWORD dwSize; + struct _tagGROUP * pNext; + struct _tagGROUP * pPrev; + LPTSTR lpszName; + HTREEITEM hItem; + HLINE hLine; + DWORD dwDeviceID; + DWORD dwAddress; + struct _tagLISTITEM * pAgentList; + +} GROUP, * PGROUP; + +typedef struct _tagGENERICSTRUCT +{ + DWORD dwKey; + DWORD dwSize; + struct _tagGENERICSTRUCT * pNext; + struct _tagGENERICSTRUCT * pPrev; + +} GENERICSTRUCT, * PGENERICSTRUCT; + +typedef struct _tagLISTITEM +{ + DWORD dwKey; + DWORD dwSize; + struct _tagLISTITEM * pNext; + struct _tagLISTITEM * pPrev; + PAGENT pAgent; + BOOL bLoggedIn; + DWORD dwAddress; + +} LISTITEM, * PLISTITEM; + + +typedef struct _tagACDGLOBALS +{ + PAGENT pAgents; + PGROUP pGroups; + DWORD dwNumAgents; + DWORD dwNumGroups; + LPDWORD pdwPermIDs; + HINSTANCE hInstance; + HLINEAPP hLineApp; + DWORD dwNumDevs; + HWND hMainWnd; + HWND hTreeWnd; + HWND hLogWnd; + BOOL bGroupView; + DWORD dwBarLocation; + HTREEITEM hAgentParent; + HTREEITEM hGroupParent; + HTREEITEM hTreeItemWithMenu; + +} ACDGLOBALS, * LPACDGLOBALS; + + +//////////////////////////////////////////////////////////////////////////////////////////////// +// +// PROTOTYPES +// +//////////////////////////////////////////////////////////////////////////////////////////////// + +// memory +LPVOID ACDAlloc(DWORD dwSize); + +void ACDFree(LPVOID pBuf); + +LPVOID ACDReAlloc(LPVOID pBuf, + DWORD dwSize); + +// tapi utils +LINEADDRESSCAPS * LineGetAddressCaps (HLINEAPP hLineApp, + DWORD dwDeviceID, + DWORD dwAddressID); + +LINECALLINFO * LineGetCallInfo (HCALL hCall); + +LINEDEVCAPS * LineGetDevCaps (HLINEAPP hLineApp, + DWORD dwDeviceID); + +VARSTRING * LineGetID (HLINE hLine, + DWORD dwAddressID, + HCALL hCall, + DWORD dwSelect, + LPCTSTR lpszDeviceClass); + +LINECALLSTATUS * LineGetCallStatus (HCALL hCall); + +// list utils +BOOL InsertStruct(PGENERICSTRUCT * ppRoot, + PGENERICSTRUCT pStruct); + +BOOL DeleteStruct(PGENERICSTRUCT * ppRoot, + PGENERICSTRUCT pStruct); + +PGROUP AddGroup(LPTSTR lpszName, + DWORD dwDeviceID, + DWORD dwAddress); + +PAGENT AddAgent(LPTSTR lpszName, + LPTSTR lpszNumber, + DWORD dwDeviceID); + +BOOL DeleteAgent(PAGENT pAgent); + +BOOL DeleteGroup(PGROUP pGroup); + +BOOL InsertIntoGroupList(PGROUP pGroup, + PAGENT pAgent); + +BOOL RemoveFromGroupList(PGROUP pGroup, + PAGENT pAgent); + +DWORD GetDeviceID(DWORD dwPermID); + +PAGENT GetAgentFromhLine(HLINE hLine); + +PAGENT GetAgentFromName(LPTSTR lpszName); + +PLISTITEM IsAgentInList(PLISTITEM pList, + PAGENT pAgent); + +/////////////////////////////////////////////////////////////////////////// +// +// DEFINES +// +/////////////////////////////////////////////////////////////////////////// + +#define TOTALACTIVITIES 10 +#define NUMGROUPENTRIES 10 +#define NAMESIZE 128 + +// structure keys +#define GROUPROOTKEY 'GRRT' +#define AGENTROOTKEY 'AGRT' +#define AGENTKEY 'AGNT' +#define GROUPKEY 'GROU' +#define LISTKEY 'LIST' + + +// window control defines +#define SIZEBAR 3 +#define WINDOWSCALEFACTOR 15 + +#define SZAPPNAME TEXT("ACD Sample") + +#endif + diff --git a/private/tapi/dev/apps/acd/acdsmpl.rc b/private/tapi/dev/apps/acd/acdsmpl.rc new file mode 100644 index 000000000..f3cc9d10e --- /dev/null +++ b/private/tapi/dev/apps/acd/acdsmpl.rc @@ -0,0 +1,158 @@ +#include <windows.h> +#include <commctrl.h> +#include "resource.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_MAINDLG DIALOGEX 0, 0, 420, 230 +STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION | + WS_SYSMENU | WS_THICKFRAME +CAPTION "ACD Sample" +MENU IDR_MAINMENU +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "",IDC_TREEWND,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | + WS_BORDER | WS_TABSTOP | TVS_DISABLEDRAGDROP ,7,7,125,216, + WS_EX_CLIENTEDGE + EDITTEXT IDC_EDITWND,139,7,274,216,ES_AUTOHSCROLL | ES_READONLY | + ES_WANTRETURN +END + + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ADD DIALOG DISCARDABLE 0, 0, 148, 134 +STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "Add Group" +FONT 8, "MS Sans Serif" +BEGIN + EDITTEXT IDC_NAME,7,17,134,14,ES_AUTOHSCROLL + COMBOBOX IDC_LINECOMBO,7,50,134,54,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_ADDRESSCOMBO,7,85,134,51,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,7,113,50,14 + PUSHBUTTON "Cancel",IDCANCEL,91,113,50,14 + LTEXT "&Name",IDC_STATIC,7,7,20,8 + LTEXT "Line",IDC_STATIC,7,39,14,8 + LTEXT "Address",IDC_STATIC,7,74,26,8 +END + +IDD_ADDAGENT DIALOG DISCARDABLE 0, 0, 146, 137 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Add Agent" +FONT 8, "MS Sans Serif" +BEGIN + EDITTEXT IDC_NAME,7,20,132,14,ES_AUTOHSCROLL + COMBOBOX IDC_LINECOMBO,7,54,132,83,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_DESTADDRESS,7,90,132,14,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,7,116,50,14 + PUSHBUTTON "Cancel",IDCANCEL,89,116,50,14 + LTEXT "Agent Name",IDC_STATIC,7,8,82,8 + LTEXT "Line",IDC_STATIC,7,42,14,8 + LTEXT "Transfer Number",IDC_STATIC,7,75,54,8 +END + + +IDD_ADDTOLIST DIALOG DISCARDABLE 0, 0, 222, 142 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Add To" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,41,121,50,14 + PUSHBUTTON "Cancel",IDCANCEL,127,121,50,14 + LISTBOX IDC_LIST1,7,23,68,87,LBS_SORT | LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + LISTBOX IDC_LIST2,147,23,68,87,LBS_SORT | LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "&Add >>>",IDC_ADD,84,41,50,14 + PUSHBUTTON "<<< &Remove",IDC_REMOVE,84,78,50,14 + LTEXT "Static",IDC_STATICNOTINLIST,7,7,98,8 + LTEXT "Static",IDC_STATICINLIST,147,7,68,8 +END + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MAINMENU MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Open", ID_FILE_OPEN + MENUITEM "&New", ID_FILE_NEW + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_FILE_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "Add &Agent", ID_EDIT_ADDAGENT + MENUITEM "Add &Group", ID_EDIT_ADDGROUP + END + POPUP "&View" + BEGIN + MENUITEM "&Group View", ID_VIEW_GROUP + MENUITEM "&Agent View", ID_VIEW_AGENT + END +END + +//////////////////////////////////////////////////////////////////// +// +// Version Info +// + +//#if WINNT +//#include <ntverp.h> +//#else +//#include <version.h> +//#endif +#include <winver.h> + + +#ifdef RC_INVOKED + +VS_VERSION_INFO VERSIONINFO +FILEVERSION 4,00,01,001 +PRODUCTVERSION 4,00,01,001 +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +FILEFLAGS (VS_FF_PRERELEASE|VS_FF_DEBUG) +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +FILESUBTYPE VFT2_UNKNOWN + +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */ + BEGIN + VALUE "CompanyName", "Microsoft Corporation\0" + VALUE "FileDescription", "TAPI ACD Sample Application\0" + VALUE "FileVersion", "1.0\0" + VALUE "InternalName", "ACDSmple\0" + VALUE "LegalCopyright", "Copyright (C) Microsoft Corp. 1996\0" + VALUE "LegalTrademarks", "Microsoft(R) is a registered trademark of Microsoft Corporation. Windows(TM) is a trademark of Microsoft Corporation\0" + VALUE "ProductName", "ACDSmpl\0" + VALUE "ProductVersion", "1.0\0" + + END + + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04B0 + END +END + +#endif + + diff --git a/private/tapi/dev/apps/acd/acdtapi.c b/private/tapi/dev/apps/acd/acdtapi.c new file mode 100644 index 000000000..1a03899d5 --- /dev/null +++ b/private/tapi/dev/apps/acd/acdtapi.c @@ -0,0 +1,1208 @@ +/////////////////////////////////////////////////////////////////////////////////// +// +// ACDTAPI.C +// +// This file handles all tapi functionality in the ACD sample +// +// +// +//////////////////////////////////////////////////////////////////////////////////// +#include <windows.h> +#include <tapi.h> +#include "acdsmpl.h" + +VOID CALLBACK LineCallback (DWORD hDevice, + DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); + + +#define LogTapiError(__lResult__, __szString__) +#define LogError(__szString__) + +extern ACDGLOBALS g; + + +//////////////////////////////////////////////////////////////////////////////////// +// +// BOOL InitializeTapi() +// +// Whatever is needed to init TAPI for the application. This is called +// before the main window is created. +// +//////////////////////////////////////////////////////////////////////////////////// +BOOL InitializeTapi() +{ + DWORD dwAPIVersion; + LINEINITIALIZEEXPARAMS exparams; + LONG lResult; + DWORD i; + LPLINEDEVCAPS pLDC; + + + // fill in lineinitex parameters + exparams.dwTotalSize = sizeof(LINEINITIALIZEEXPARAMS); + exparams.dwOptions = LINEINITIALIZEEXOPTION_USEHIDDENWINDOW; + + dwAPIVersion = TAPI_CURRENT_VERSION; + + // line init + if ((lResult = lineInitializeEx(&g.hLineApp, + g.hInstance, + LineCallback, + SZAPPNAME, + &g.dwNumDevs, + &dwAPIVersion, + &exparams)) < 0) + { + LogTapiError(lResult, "lineInitializeEx"); + return FALSE; + } + + // if there are no tapi devices, should probably + // not continue + if (g.dwNumDevs == 0) + { + LogError("No TAPI devices installed"); + lineShutdown(g.hLineApp); + return FALSE; + } + + // need to get the permanent device IDs to map from + // an .ini file being read in + g.pdwPermIDs = (LPDWORD)ACDAlloc(g.dwNumDevs * sizeof(DWORD)); + + if (!g.pdwPermIDs) + { + return FALSE; + } + + for (i = 0; i < g.dwNumDevs; i++) + { + pLDC = LineGetDevCaps(g.hLineApp, + i); + + if (pLDC) + { + g.pdwPermIDs[i] = pLDC->dwPermanentLineID; + ACDFree(pLDC); + } + } + + return TRUE; +} + + +////////////////////////////////////////////////////////////////////// +// +// BOOL CleanUp() +// +// Called while shutting down. free memory, close down tapi +// +////////////////////////////////////////////////////////////////////// +BOOL CleanUp() +{ + PAGENT pAgent, pAgentNext; + PGROUP pGroup, pGroupNext; + + // remove agents + pAgent = g.pAgents; + while(pAgent) + { + pAgentNext = pAgent->pNext; + DeleteAgent(pAgent); + pAgent = pAgentNext; + } + + // remove groups + pGroup = g.pGroups; + while (pGroup) + { + pGroupNext = pGroup->pNext; + DeleteGroup(pGroup); + pGroup = pGroupNext; + } + + // free id array + ACDFree(g.pdwPermIDs); + + // shutdown + lineShutdown(g.hLineApp); + + return TRUE; + +} +//////////////////////////////////////////////////////////////////////////////// +// +// LRESULT MakeGroupList(PAGENT pAgent, +// LPLINEAGENTGROUPLIST pGroupList) +// +// Creates a LINEAGENTGROUPLIST for pAgent - group that the agent +// is allowed to log into +// Assumption: don't care about address for group list +// +//////////////////////////////////////////////////////////////////////////////// +LRESULT MakeGroupList(PAGENT pAgent, + LPLINEAGENTGROUPLIST pGroupList) +{ + PGROUP pGroup; + DWORD dwTotalSizeNeeded, dwNameOffset, dwNumEntries; + LPLINEAGENTGROUPENTRY pEntry; + LPTSTR pName; + + + pGroup = g.pGroups; + dwTotalSizeNeeded = sizeof(LINEAGENTGROUPLIST); + pGroupList->dwNumEntries = 0; + dwNumEntries = 0; + + // walk list of groups + while (pGroup) + { + if (IsAgentInList(pGroup->pAgentList, + pAgent)) + // if found the agent, add the group to the group list + { + // incrememt number of entries + dwNumEntries++; + + // add to total size needed + dwTotalSizeNeeded += sizeof(LINEAGENTGROUPENTRY); + dwTotalSizeNeeded += (lstrlen(pGroup->lpszName) + 1) * sizeof(TCHAR); + } + + pGroup = pGroup->pNext; + } + + pGroupList->dwNeededSize = dwTotalSizeNeeded; + + if (pGroupList->dwTotalSize < dwTotalSizeNeeded) + { + pGroupList->dwUsedSize = sizeof(LINEAGENTGROUPLIST); + + return 0; +// return LINEERR_STRUCTURETOOSMALL; + } + + pGroupList->dwNumEntries = dwNumEntries; + + // set the list info + pGroupList->dwListSize = sizeof(LINEAGENTGROUPENTRY) * pGroupList->dwNumEntries; + pGroupList->dwListOffset = sizeof(LINEAGENTGROUPLIST); + + // get the first agentgroup entry struct + pEntry = (LPLINEAGENTGROUPENTRY)(((LPBYTE)pGroupList) + pGroupList->dwListOffset); + + dwNameOffset = pGroupList->dwListOffset + pGroupList->dwListSize; + pGroup = g.pGroups; + + // loop through the groups again, and fill in the structure + while (pGroup) + { + if (IsAgentInList(pGroup->pAgentList, + pAgent)) + { + // ID is just PGROUP + pEntry->GroupID.dwGroupID1 = (DWORD)pGroup; + pEntry->GroupID.dwGroupID2 = 0; + pEntry->GroupID.dwGroupID3 = 0; + pEntry->GroupID.dwGroupID4 = 0; + + // set name of group + pName = (LPTSTR)(((LPBYTE)pGroupList) + dwNameOffset); + + pEntry->dwNameSize = (lstrlen(pGroup->lpszName) + 1) * sizeof(TCHAR); + pEntry->dwNameOffset = dwNameOffset; + lstrcpy(pName, + pGroup->lpszName); + + dwNameOffset += pEntry->dwNameSize; + + // get next entry + pEntry++; + } + + pGroup = pGroup->pNext; + } + + pGroupList->dwUsedSize = dwTotalSizeNeeded; + + return 0; +} + + + +//////////////////////////////////////////////////////////////////////////// +// +// LRESULT SetGroupList() +// +// Sets the groups that the agent is logged into. +// This does not change the groups that the agent _can_ log into +// +//////////////////////////////////////////////////////////////////////////// +LRESULT SetGroupList(PAGENT pAgent, + DWORD dwAddress, + LPLINEAGENTGROUPLIST pGroupList) +{ + LPLINEAGENTGROUPENTRY pGroupEntry; + PLISTITEM pListEntry; + DWORD i; + PGROUP * ppGroups = NULL; + PGROUP pGroup; + + ppGroups = (PGROUP*)ACDAlloc(sizeof(PGROUP) * pGroupList->dwNumEntries); + + // get to the group entry struct + pGroupEntry = (LPLINEAGENTGROUPENTRY)(((LPBYTE)pGroupList) + pGroupList->dwListOffset); + + // loop through all entries + for (i = 0; i < pGroupList->dwNumEntries; i++) + { + // get the group in entry + // NOTE! NOTE! NOTE! + // should protect here against bad pointers !!! + pGroup = (PGROUP)pGroupEntry->GroupID.dwGroupID1; + + if (pGroup->dwKey != GROUPKEY) + { + return LINEERR_INVALAGENTGROUP; + } + + pListEntry = pGroup->pAgentList; + + // walk list of agents in that group + if (!IsAgentInList(pGroup->pAgentList, + pAgent)) + { + ACDFree(ppGroups); + return LINEERR_INVALAGENTGROUP; + } + + // save group for easy access + ppGroups[i] = pGroup; + + // get the next entry (after the variable portion of + // the previous entry struct) + pGroupEntry++; + } + + // now we know that the groups to be set are valid + // walk through the list of groups again, and + // set the status to logged in/ not logged in + // for every group that the agent is a member of + + pGroup = g.pGroups; + + // walk list of all groups + while (pGroup) + { + if (pListEntry = IsAgentInList(pGroup->pAgentList, + pAgent)) + { + // default to not logged in + pListEntry->bLoggedIn = FALSE; + + // loop through groups being set + for (i = 0; i < pGroupList->dwNumEntries; i++) + { + // if this group is in list, set agent to logged in + if (pGroup == ppGroups[i]) + { + pListEntry->bLoggedIn = TRUE; + // assumption: agent can only log into a group on one address. + pListEntry->dwAddress = dwAddress; + break; + } + + } // for + + } // agent in list + + // next group + pGroup = pGroup->pNext; + + } // while + + + ACDFree(ppGroups); + + return 0; +} + + +///////////////////////////////////////////////////////////////////////// +// +// BOOL MakeAgentActivityList() +// +// Creates a LINEAGENTACTIVITYLIST for pAgent +// +// for the sample, just generic names are used +// "Activity 1", "Activity 2".... +// +///////////////////////////////////////////////////////////////////////// +LRESULT MakeAgentActivityList(PAGENT pAgent, + LPLINEAGENTACTIVITYLIST pActivityList) +{ + TCHAR szBuffer[64]; + DWORD dwTotalSize, dwNameOffset, i, dwNumEntries; + LPTSTR pName; + LPLINEAGENTACTIVITYENTRY pEntry; + + // init + dwTotalSize = sizeof(LINEAGENTACTIVITYLIST); + pActivityList->dwNumEntries = 0; + dwNumEntries = 0; + + // just a static list of activities + for (i = 0; i < TOTALACTIVITIES; i++) + { + dwNumEntries++; + + // create a name + wsprintf(szBuffer, TEXT("Activity %lu"), i); + + // determine size of this entry + dwTotalSize += sizeof(LINEAGENTACTIVITYENTRY); + dwTotalSize += (lstrlen(szBuffer) + 1) * sizeof(TCHAR); + } + + pActivityList->dwNeededSize = dwTotalSize; + + // verify size + if (pActivityList->dwTotalSize < dwTotalSize) + { + pActivityList->dwUsedSize = sizeof(LINEAGENTACTIVITYLIST); + + return 0; +// return LINEERR_STRUCTURETOOSMALL; + } + + pActivityList->dwNumEntries = dwNumEntries; + + // set list stuff + pActivityList->dwListSize = sizeof(LINEAGENTACTIVITYENTRY) * pActivityList->dwNumEntries; + pActivityList->dwListOffset = sizeof(LINEAGENTACTIVITYLIST); + + // get first activityentry + pEntry = (LPLINEAGENTACTIVITYENTRY)(((LPBYTE)pActivityList) + pActivityList->dwListOffset); + dwNameOffset = pActivityList->dwListOffset + pActivityList->dwListSize; + + // loop through activities again + for (i = 0; i < TOTALACTIVITIES; i++) + { + // fill in members + pEntry->dwID = i; + + // create a name + wsprintf(szBuffer, TEXT("Activity %lu"), i); + + pName = (LPTSTR)(((LPBYTE)pActivityList) + dwNameOffset); + + pEntry->dwNameSize = (lstrlen(szBuffer) + 1) * sizeof(TCHAR); + pEntry->dwNameOffset = dwNameOffset; + lstrcpy(pName, + szBuffer); + + dwNameOffset += pEntry->dwNameSize; + + pEntry++; + + } // for + + // fill in used size + pActivityList->dwUsedSize = dwTotalSize; + + return 0; +} + + +#define DWAGENTFEATURES LINEAGENTFEATURE_SETAGENTGROUP | \ + LINEAGENTFEATURE_SETAGENTSTATE | \ + LINEAGENTFEATURE_SETAGENTACTIVITY | \ + LINEAGENTFEATURE_GETAGENTACTIVITYLIST | \ + LINEAGENTFEATURE_GETAGENTGROUP + +#define DWSTATES LINEAGENTSTATE_LOGGEDOFF | \ + LINEAGENTSTATE_NOTREADY | \ + LINEAGENTSTATE_READY | \ + LINEAGENTSTATE_BUSYACD | \ + LINEAGENTSTATE_BUSYINCOMING | \ + LINEAGENTSTATE_BUSYOUTBOUND | \ + LINEAGENTSTATE_BUSYOTHER | \ + LINEAGENTSTATE_WORKINGAFTERCALL | \ + LINEAGENTSTATE_UNKNOWN | \ + LINEAGENTSTATE_UNAVAIL + +#define DWNEXTSTATES LINEAGENTSTATE_LOGGEDOFF | \ + LINEAGENTSTATE_NOTREADY | \ + LINEAGENTSTATE_READY | \ + LINEAGENTSTATE_BUSYACD | \ + LINEAGENTSTATE_BUSYINCOMING | \ + LINEAGENTSTATE_BUSYOUTBOUND | \ + LINEAGENTSTATE_BUSYOTHER | \ + LINEAGENTSTATE_WORKINGAFTERCALL | \ + LINEAGENTSTATE_UNKNOWN | \ + LINEAGENTSTATE_UNAVAIL + +#define DWSTATUSMESSAGES LINEAGENTSTATUS_GROUP | \ + LINEAGENTSTATUS_STATE | \ + LINEAGENTSTATUS_NEXTSTATE | \ + LINEAGENTSTATUS_ACTIVITY | \ + LINEAGENTSTATUS_ACTIVITYLIST | \ + LINEAGENTSTATUS_GROUPLIST | \ + LINEAGENTSTATUS_CAPSCHANGE | \ + LINEAGENTSTATUS_VALIDSTATES | \ + LINEAGENTSTATUS_VALIDNEXTSTATES + + +//////////////////////////////////////////////////////////////////// +// +// BOOL IsValidState(DWORD dwState) +// +//////////////////////////////////////////////////////////////////// +BOOL IsValidState(DWORD dwState) +{ + if (!dwState) + { + return TRUE; + } + + if ((dwState) & (dwState - 1)) + { + // more than one bit set + return FALSE; + } + + // make sure it's one of the valid states + return (dwState & DWSTATES); + +} + + +//////////////////////////////////////////////////////////////////// +// +// BOOL IsValidNextState(DWORD dwState) +// +//////////////////////////////////////////////////////////////////// +BOOL IsValidNextState(DWORD dwState) +{ + if (!dwState) + { + return TRUE; + } + + if ((dwState) & (dwState - 1)) + { + // more than one bit set + return FALSE; + } + + // make sure it's one of the valid states + return (dwState & DWNEXTSTATES); + +} + + +/////////////////////////////////////////////////////////////////////// +// +// BOOL IsValidActivityID(DWORD dwActivityID) +// +/////////////////////////////////////////////////////////////////////// +BOOL IsValidActivityID(DWORD dwActivityID) +{ + return (dwActivityID <= TOTALACTIVITIES); +} + + + +//////////////////////////////////////////////////////////////////////// +// +// LRESULT MakeAgentCaps(PAGENT pAgent, +// LPLINEAGENTCAPS pAgentCaps) +// +// Creates a LINEAGENTCAPS for pAgent +// Features/states/messages are hardcoded +// for this example +// +//////////////////////////////////////////////////////////////////////// +LRESULT MakeAgentCaps(PAGENT pAgent, + LPLINEAGENTCAPS pAgentCaps) +{ + DWORD dwStringSize; + + dwStringSize = (lstrlen(SZAPPNAME) + 1) * sizeof(TCHAR); + + pAgentCaps->dwNeededSize = sizeof(LINEAGENTCAPS) + dwStringSize; + + if (pAgentCaps->dwTotalSize < pAgentCaps->dwNeededSize) + { + pAgentCaps->dwUsedSize = sizeof(LINEAGENTCAPS); + return 0; +// return LINEERR_STRUCTURETOOSMALL; + } + + + pAgentCaps->dwAgentHandlerInfoSize = dwStringSize; + pAgentCaps->dwAgentHandlerInfoOffset = sizeof(LINEAGENTCAPS); + + pAgentCaps->dwCapsVersion = TAPI_CURRENT_VERSION; + + // these features are hardcoded here. + // a real implementation may set specific features + // per agent or line or address + pAgentCaps->dwFeatures = DWAGENTFEATURES; + pAgentCaps->dwStates = DWSTATES; + pAgentCaps->dwNextStates = DWNEXTSTATES; + pAgentCaps->dwMaxNumGroupEntries = NUMGROUPENTRIES; + pAgentCaps->dwAgentStatusMessages = DWSTATUSMESSAGES; + + // no extensions + pAgentCaps->dwNumAgentExtensionIDs = 0; + pAgentCaps->dwAgentExtensionIDListSize = 0; + pAgentCaps->dwAgentExtensionIDListOffset = 0; + + + pAgentCaps->dwUsedSize = pAgentCaps->dwNeededSize; + + return 0; +} + + +////////////////////////////////////////////////////////////////////////// +// +// LRESULT GetAgentStatus() +// +// Creates a LINEAGENTSTATUS for pAgent +// +////////////////////////////////////////////////////////////////////////// +LRESULT GetAgentStatus(PAGENT pAgent, + DWORD dwAddress, + LPLINEAGENTSTATUS pAgentStatus) +{ + PGROUP pGroup; + LPLINEAGENTGROUPENTRY pGroupEntry; + DWORD dwTotalSize, dwNameOffset, dwCount; + TCHAR szActivityName[NAMESIZE]; + PGROUP * ppGroups; + PLISTITEM pEntry; + + // init total size + dwTotalSize = sizeof(LINEAGENTSTATUS); + + if (dwAddress >= pAgent->dwNumAddresses) + { + return LINEERR_INVALADDRESSID; + } + + // set know members + // for valid states / next states / agent features, just setting it to + // generic stuff. a real implementation may want to set these + // field depending on current state / agent / hline + pAgentStatus->dwState = pAgent->pAddressInfo[dwAddress].dwState; + pAgentStatus->dwNextState = pAgent->pAddressInfo[dwAddress].dwNextState; + pAgentStatus->dwActivityID = pAgent->pAddressInfo[dwAddress].dwActivity; + pAgentStatus->dwAgentFeatures = DWAGENTFEATURES; + pAgentStatus->dwValidStates = DWSTATES; + pAgentStatus->dwValidNextStates = DWNEXTSTATES; + + // create the activity name + wsprintf(szActivityName, TEXT("Activity %lu"), pAgent->pAddressInfo[dwAddress].dwActivity); + dwTotalSize += (lstrlen(szActivityName) + 1) * sizeof(TCHAR); + + ppGroups = (PGROUP *)ACDAlloc(sizeof(PGROUP) * g.dwNumGroups); + + pGroup = g.pGroups; + + pAgentStatus->dwNumEntries = 0; + + // walk list of groups + while (pGroup) + { + pEntry = pGroup->pAgentList; + + // walk each agent in each group + while (pEntry) + { + if (pEntry->pAgent == pAgent) + { + if ((!pEntry->bLoggedIn) || + (pEntry->dwAddress != dwAddress)) + { + break; + } + + // save group + ppGroups[pAgentStatus->dwNumEntries] = pGroup; + + // adjust total size / entries + pAgentStatus->dwNumEntries++; + dwTotalSize += sizeof(LINEAGENTGROUPENTRY); + dwTotalSize += (lstrlen(pGroup->lpszName) + 1) * sizeof(TCHAR); + + break; + } + + pEntry = pEntry->pNext; + + } // while (pEntry) + + pGroup = pGroup->pNext; + + } // while (pGroup) + + // set needed size + pAgentStatus->dwNeededSize = dwTotalSize; + + // do we have enough room? + if (pAgentStatus->dwTotalSize < dwTotalSize) + { + // if not, return + pAgentStatus->dwUsedSize = sizeof(LINEAGENTSTATUS); + ACDFree(ppGroups); + + return 0; +// return LINEERR_STRUCTURETOOSMALL; + } + + + // set the group entries... + + // first get the offset to the first entry + pGroupEntry = (LPLINEAGENTGROUPENTRY)(((LPBYTE)pAgentStatus) + sizeof(LINEAGENTSTATUS)); + pAgentStatus->dwGroupListOffset = sizeof(LINEAGENTSTATUS); + + // figure out where the names can go (after all the fixed structures) + dwNameOffset = sizeof(LINEAGENTSTATUS) + + sizeof(LINEAGENTGROUPENTRY) * pAgentStatus->dwNumEntries; + + // loop through all the group that the agent is logged into + for (dwCount = 0; dwCount < pAgentStatus->dwNumEntries; dwCount++) + { + // set the it (just the pGroup) + pGroupEntry->GroupID.dwGroupID1 = (DWORD)ppGroups[dwCount]; + pGroupEntry->GroupID.dwGroupID2 = 0; + pGroupEntry->GroupID.dwGroupID3 = 0; + pGroupEntry->GroupID.dwGroupID4 = 0; + + // set name size and offset + pGroupEntry->dwNameSize = (lstrlen(ppGroups[dwCount]->lpszName) + 1) * sizeof(TCHAR); + pGroupEntry->dwNameOffset = dwNameOffset; + + // copy name + lstrcpy((LPTSTR)(((LPBYTE)pAgentStatus) + dwNameOffset), + ppGroups[dwCount]->lpszName); + + // fix the name offset + dwNameOffset += pGroupEntry->dwNameSize; + + // next entry + pGroupEntry++; + + } + + pAgentStatus->dwGroupListSize = dwNameOffset - pAgentStatus->dwGroupListOffset; + + // put the activity name at the end + pAgentStatus->dwActivitySize = (lstrlen(szActivityName) + 1) * sizeof(TCHAR); + pAgentStatus->dwActivityOffset = dwNameOffset; + + lstrcpy((LPTSTR)(((LPBYTE)pAgentStatus) + dwNameOffset), + szActivityName); + + + ACDFree(ppGroups); + + pAgentStatus->dwUsedSize = pAgentStatus->dwNeededSize; + // return success + return 0; +} + + +///////////////////////////////////////////////////////////////////// +// +// LRESULT SetAgentState() +// +// Sets the current and next state for pAgent +// on that specific address +// +// +///////////////////////////////////////////////////////////////////// +LRESULT SetAgentState(PAGENT pAgent, + DWORD dwAddress, + DWORD dwState, + DWORD dwNextState) +{ + // make sure valid + if ((!IsValidState(dwState)) || + (!IsValidNextState(dwNextState))) + { + return LINEERR_INVALAGENTSTATE; + } + + // check address + if (dwAddress >= pAgent->dwNumAddresses) + { + return LINEERR_INVALADDRESSID; + } + + // set the state if specified + if (dwState) + { + pAgent->pAddressInfo[dwAddress].dwState = dwState; + } + + if (dwNextState) + { + pAgent->pAddressInfo[dwAddress].dwNextState = dwNextState; + } + + return 0; +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// LRESULT SetAgentActivity() +// +// Sets the activity for pAgent +// +/////////////////////////////////////////////////////////////////////////////// +LRESULT SetAgentActivity(PAGENT pAgent, + DWORD dwAddress, + DWORD dwActivityID) +{ + if (dwAddress >= pAgent->dwNumAddresses) + { + return LINEERR_INVALADDRESSID; + } + + if (!IsValidActivityID(dwActivityID)) + { + return LINEERR_INVALAGENTACTIVITY; + } + + pAgent->pAddressInfo[dwAddress].dwActivity = dwActivityID; + + return 0; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// BOOL HandleOffering(HCALL hCall) +// +// Handles a LINECALLSTATE_OFFERING message +// Determines the group associated with the address +// that the call came in on, finds an available +// agent in that group, and transfers the call to that +// agent. +// +//////////////////////////////////////////////////////////////////////////////// +BOOL HandleOffering(HCALL hCall) +{ + LPLINECALLINFO pLCI; + PGROUP pGroup; + PLISTITEM pEntry; + LONG lResult; + + pLCI = LineGetCallInfo(hCall); + + if (!pLCI) + { + return FALSE; + } + + pGroup = g.pGroups; + + // find the group that this call came in on + // walk all the groups + while (pGroup) + { + // if the line and address match, it's the + // correct address + if ((pGroup->hLine == pLCI->hLine) && + (pGroup->dwAddress == pLCI->dwAddressID)) + { + break; + } + + pGroup = pGroup->pNext; + } + + // couldn't find the group + if (!pGroup) + { + // error! + ACDFree(pLCI); + return FALSE; + } + + // OK - found the group that this call is for. Now transfer to + // an agent that is available. + pEntry = pGroup->pAgentList; + + while (pEntry) + { + if (pEntry->bLoggedIn && + (pEntry->pAgent->pAddressInfo[pEntry->dwAddress].dwState == + LINEAGENTSTATE_READY)) + { + // found someone + // doing a blind transfer here + // other implementations may need to + // do lineSetupTransfer / lineDial / lineCompleteTransfer + if (lResult = lineBlindTransfer(hCall, + (LPCWSTR)pEntry->pAgent->lpszNumber, + 0)) + { + //LogTapiError(TEXT("lineBlindTransfer"), lResult); + // don't break - try the next agent + } + else + { + // set the state to reflect that + // a call is being handled + SetAgentState(pEntry->pAgent, + pEntry->dwAddress, + LINEAGENTSTATE_BUSYACD, + LINEAGENTSTATE_READY); + + break; + } + + } + + pEntry = pEntry->pNext; + } + + if (!pEntry) + { + // couldn't find an available agent + + // NOTE! NOTE! NOTE! NOTE! NOTE! + // something should be done here with this call. put into + // a queue on hold or something. For this sample, we are just + // ignoring it + } + + ACDFree(pLCI); + + return TRUE; +} + + +////////////////////////////////////////////////////////////////////////// +// +// BOOL HandleIdle(HCALL hCall) +// +// Handles LINECALLSTATE_IDLE +// Should always always always deallocate when +// getting an IDLE message. Also, determine if this is a call +// that we know about and set the agent state appropriatly +// +////////////////////////////////////////////////////////////////////////// +BOOL HandleIdle(HCALL hCall) +{ + LPLINECALLINFO pLCI; + PAGENT pAgent; + + pLCI = LineGetCallInfo(hCall); + + // always deallocate the call + lineDeallocateCall(hCall); + + if (!pLCI) + { + return FALSE; + } + + // get the agent associated with the line + pAgent = GetAgentFromhLine(pLCI->hLine); + + if (!pAgent) + { + ACDFree(pLCI); + return FALSE; + } + + + // set that agent to their next state + // Assumption: only calls that the ACD app know about + // occur. For example, if an agent made an outgoing call + // and it transitioned to idle, this code would still be executed. + // May make more sense to not handle NextState in the ACD app, and let + // the client app handle it. + SetAgentState(pAgent, + pLCI->dwAddressID, + pAgent->pAddressInfo[pLCI->dwAddressID].dwNextState, + 0); + + ACDFree(pLCI); + + return TRUE; + +} + + +//////////////////////////////////////////////////////////////////////////// +// +// void HandleLineProxyRequest(HLINE hLine, +// LPLINEPROXYREQUEST pProxyRequest) +// +// Handles LINE_PROXYREQUEST message +// Just dispatches to appropriate functions +// +//////////////////////////////////////////////////////////////////////////// +void HandleLineProxyRequest(HLINE hLine, + LPLINEPROXYREQUEST pProxyRequest) +{ + PAGENT pAgent; + LRESULT lResult; + + pAgent = GetAgentFromName((LPTSTR)(((LPBYTE)pProxyRequest) + + pProxyRequest->dwClientUserNameOffset)); + + if (!pAgent) + { + lineProxyResponse(hLine, + pProxyRequest, + LINEERR_INVALAGENTID); + + return; + } + + switch (pProxyRequest->dwRequestType) + { + case LINEPROXYREQUEST_SETAGENTGROUP: + + lResult = SetGroupList(pAgent, + pProxyRequest->SetAgentGroup.dwAddressID, + &pProxyRequest->SetAgentGroup.GroupList); + + lineProxyResponse(hLine, + pProxyRequest, + lResult); + + return; + + case LINEPROXYREQUEST_SETAGENTSTATE: + + lResult = SetAgentState(pAgent, + pProxyRequest->SetAgentState.dwAddressID, + pProxyRequest->SetAgentState.dwAgentState, + pProxyRequest->SetAgentState.dwNextAgentState); + + lineProxyResponse(hLine, + pProxyRequest, + lResult); + + break; + + case LINEPROXYREQUEST_SETAGENTACTIVITY: + + lResult = SetAgentActivity(pAgent, + pProxyRequest->SetAgentActivity.dwAddressID, + pProxyRequest->SetAgentActivity.dwActivityID); + + lineProxyResponse(hLine, + pProxyRequest, + lResult); + + break; + + case LINEPROXYREQUEST_GETAGENTSTATUS: + + lResult = GetAgentStatus(pAgent, + pProxyRequest->GetAgentStatus.dwAddressID, + &pProxyRequest->GetAgentStatus.AgentStatus); + + lineProxyResponse(hLine, + pProxyRequest, + lResult); + + break; + + case LINEPROXYREQUEST_GETAGENTCAPS: + + if ((hLine == pAgent->hLine) && + (pProxyRequest->GetAgentCaps.dwAddressID < pAgent->dwNumAddresses)) + { + lResult = MakeAgentCaps(pAgent, + &pProxyRequest->GetAgentCaps.AgentCaps); + } + else + { + lResult = LINEERR_BADDEVICEID; + } + + lineProxyResponse(hLine, + pProxyRequest, + lResult); + break; + + case LINEPROXYREQUEST_GETAGENTACTIVITYLIST: + + lResult = MakeAgentActivityList(pAgent, + &pProxyRequest->GetAgentActivityList.ActivityList); + + lineProxyResponse(hLine, + pProxyRequest, + lResult); + + break; + + case LINEPROXYREQUEST_GETAGENTGROUPLIST: + + lResult = MakeGroupList(pAgent, + &pProxyRequest->GetAgentGroupList.GroupList); + + lineProxyResponse(hLine, + pProxyRequest, + lResult); + return; + + + } + return; +} + +///////////////////////////////////////////////////////////// +// +// void HandleLineCallState(DWORD dwDevice, +// +// Handles callstate messages we are interested in +// +///////////////////////////////////////////////////////////// +void HandleLineCallState(DWORD dwDevice, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + switch (dwParam1) + { + case LINECALLSTATE_OFFERING: + { + LPLINECALLSTATUS pLCS; + + // get the call privilege. + // NOTE: the new LINE_APPNEWCALL message notifies applications + // of their priv for new calls not created by app + pLCS = LineGetCallStatus((HCALL)dwDevice); + if (!pLCS) + { + break; + } + + if (pLCS->dwCallPrivilege & LINECALLPRIVILEGE_OWNER) + { + HandleOffering((HCALL)dwDevice); + } + + ACDFree(pLCS); + + break; + } + case LINECALLSTATE_CONNECTED: + break; + + case LINECALLSTATE_DISCONNECTED: + break; + + case LINECALLSTATE_IDLE: + + HandleIdle((HCALL)dwDevice); + + break; + + case LINECALLSTATE_BUSY: + break; + + default: + break; + } +} + + +/////////////////////////////////////////////////////////////////////// +// TAPI message handlers. For this sample, they don't +// do anything +/////////////////////////////////////////////////////////////////////// +void HandleLineDevState(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ +} + + +void HandleLineReply(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ +} +void HandleLineCallInfo(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ +} + +void HandleLineClose(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ +} + + +////////////////////////////////////////////////////////////////////////////////// +// +// LineCallback() - TAPI callback function +// +////////////////////////////////////////////////////////////////////////////////// +VOID CALLBACK LineCallback (DWORD hDevice, + DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + switch(dwMsg) + { + case LINE_PROXYREQUEST: + HandleLineProxyRequest((HLINE) hDevice, + (LPLINEPROXYREQUEST)dwParam1); + return; + + case LINE_LINEDEVSTATE: + HandleLineDevState(dwParam1, + dwParam2, + dwParam3); + return; + case LINE_REPLY: + HandleLineReply(dwParam1, + dwParam2, + dwParam3); + return; + case LINE_CALLSTATE: + HandleLineCallState(hDevice, + dwParam1, + dwParam2, + dwParam3); + return; + case LINE_CALLINFO: + HandleLineCallInfo(dwParam1, + dwParam2, + dwParam3); + return; + case LINE_CLOSE: + HandleLineClose(dwParam1, + dwParam2, + dwParam3); + return; + + default: + return; + } +} + + diff --git a/private/tapi/dev/apps/acd/acdutils.c b/private/tapi/dev/apps/acd/acdutils.c new file mode 100644 index 000000000..4406c554e --- /dev/null +++ b/private/tapi/dev/apps/acd/acdutils.c @@ -0,0 +1,817 @@ +////////////////////////////////////////////////////////////////// +// +// ACDUTILS.C +// +// Some utility functions used in ACDSMPL +// +////////////////////////////////////////////////////////////////// + + + +#include <windows.h> +#include "acdsmpl.h" + +extern ACDGLOBALS g; + +////////////////////////////////////////////////////////////////// +// +// LPVOID ACDAlloc(DWORD dwSize) +// +////////////////////////////////////////////////////////////////// +LPVOID ACDAlloc(DWORD dwSize) +{ + LPVOID pBuf; + + pBuf = GlobalAlloc(GPTR, dwSize); + + return pBuf; +} + +/////////////////////////////////////////////////////////////////// +// +// void ACDFree(LPVOID pBuf) +// +/////////////////////////////////////////////////////////////////// +void ACDFree(LPVOID pBuf) +{ + if (pBuf) + GlobalFree(pBuf); +} + +/////////////////////////////////////////////////////////////////// +// +// LPVOID ACDReAlloc() +// +/////////////////////////////////////////////////////////////////// +LPVOID ACDReAlloc(LPVOID pBuf, + DWORD dwSize) +{ + if (pBuf) + { + pBuf = GlobalReAlloc(pBuf, + dwSize, + GMEM_MOVEABLE); + } + + return pBuf; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// BOOL InsertStruct(PGENERICSTRUCT * ppRoot, +// PGENERICSTRUCT pStruct) +// +// Adds a structure to the end of a linked list +// +/////////////////////////////////////////////////////////////////////////////// +BOOL InsertStruct(PGENERICSTRUCT * ppRoot, + PGENERICSTRUCT pStruct) +{ + PGENERICSTRUCT pHold = NULL; + + if (!*ppRoot) + { + *ppRoot = pStruct; + } + else + { + pHold = *ppRoot; + } + + if (pHold) + { + while (pHold->pNext) + { + pHold = pHold->pNext; + } + + pHold->pNext = pStruct; + pStruct->pPrev = pHold; + } + + return TRUE; +} + +////////////////////////////////////////////////////////////// +// +// BOOL DeleteStruct +// Delete structure +// +// Delete a structure from a linked list and +// frees memory associated with it. +// +////////////////////////////////////////////////////////////// +BOOL DeleteStruct(PGENERICSTRUCT * ppRoot, + PGENERICSTRUCT pStruct) +{ + if (pStruct->pPrev) + { + pStruct->pPrev->pNext = pStruct->pNext; + } + else + { + *ppRoot = pStruct->pNext; + } + + if (pStruct->pNext) + { + pStruct->pNext->pPrev = pStruct->pPrev; + } + + ACDFree(pStruct); + + return TRUE; +} + + +////////////////////////////////////////////////////////////// +// +// PGROUP AddGroup +// +// Adds a group to the global group list +// +////////////////////////////////////////////////////////////// +PGROUP AddGroup(LPTSTR lpszName, + DWORD dwDeviceID, + DWORD dwAddress) +{ + PGROUP pGroup, pHold = NULL; + LONG lResult; + + // alloc memory + pGroup = (PGROUP)ACDAlloc(sizeof(GROUP)); + + if (!pGroup) + { + return NULL; + } + + pGroup->lpszName = (LPTSTR)ACDAlloc((lstrlen(lpszName) + 1) * sizeof(TCHAR)); + + // bail if there is a problem + if (!pGroup->lpszName) + { + ACDFree(pGroup); + return NULL; + } + + // init stuff + lstrcpy(pGroup->lpszName, lpszName); + + pGroup->dwKey = GROUPKEY; + pGroup->dwSize = sizeof(GROUP); + pGroup->dwDeviceID = dwDeviceID; + + + // open the line in owner mode, so we can + // get the incoming calls + lResult = lineOpen(g.hLineApp, + dwDeviceID, + &pGroup->hLine, + TAPI_CURRENT_VERSION, + 0, + 0, + LINECALLPRIVILEGE_OWNER, + LINEMEDIAMODE_INTERACTIVEVOICE, + NULL); + + if (lResult < 0) + { +// LogTapiError(lResult, "lineOpen line %lu", dwDeviceID); + ACDFree(pGroup->lpszName); + ACDFree(pGroup); + + return NULL; + } + + // insert into global list + InsertStruct((PGENERICSTRUCT *)&g.pGroups, + (PGENERICSTRUCT)pGroup); + + // increment + g.dwNumGroups++; + + return pGroup; +} + +////////////////////////////////////////////////////////////// +// +// PAGENT AddAgent +// +// Adds an agent to the global agent list +// +// NOTE: There is a ton of verification type stuff that can +// be put in here for a real implementation. For example, +// might want to restrict a user to a single line, or restrict +// a single line to have one person. +// +////////////////////////////////////////////////////////////// +PAGENT AddAgent(LPTSTR lpszName, + LPTSTR lpszNumber, + DWORD dwDeviceID) +{ + PAGENT pAgent, pHold = NULL; + LPLINEDEVCAPS pLDC; + LPLINECALLPARAMS pLCP; + LONG lResult; + LPDWORD pdwProxyRequests; + + // alloc memory + pAgent = (PAGENT)ACDAlloc(sizeof(AGENT)); + + if (!pAgent) + { + return NULL; + } + + pAgent->lpszName = (LPTSTR)ACDAlloc((lstrlen(lpszName) + 1) * sizeof(TCHAR)); + pAgent->lpszNumber = (LPTSTR)ACDAlloc((lstrlen(lpszNumber) + 1) * sizeof(TCHAR)); + + // bail if there is a problem + if (!pAgent->lpszName || !pAgent->lpszNumber) + { + ACDFree(pAgent); + return NULL; + } + + + // init stuff + lstrcpy(pAgent->lpszName, lpszName); + lstrcpy(pAgent->lpszNumber, lpszNumber); + + pAgent->dwKey = AGENTKEY; + pAgent->dwSize = sizeof(AGENT); + pAgent->dwDeviceID = dwDeviceID; + pAgent->dwPermID = g.pdwPermIDs[dwDeviceID]; + + // insert into global agent list + InsertStruct((PGENERICSTRUCT *)&g.pAgents, + (PGENERICSTRUCT)pAgent); + + // lineOpen is where the application lets TAPI know that it is a Proxy Request handler + // for this line. The LINEOPENOPTION_PROXY is added to the privileges. Also, + // the dev specific portion of LINECALLPARAMS contains the proxy request constants + // that indicate which requests this app can handle + + // This sample handles 7 types of proxy requests - all the ones that are defined + // except for AGENTSPECIFIC + pLCP = (LPLINECALLPARAMS)ACDAlloc(sizeof(LINECALLPARAMS) + 7*sizeof(DWORD)); + + pLCP->dwTotalSize = sizeof(LINECALLPARAMS) + 7*sizeof(DWORD); + pLCP->dwDevSpecificOffset = sizeof(LINECALLPARAMS); + pLCP->dwDevSpecificSize = sizeof(DWORD) * 7; + + pdwProxyRequests = (LPDWORD)((LPBYTE)pLCP + sizeof(LINECALLPARAMS)); + // each constant is in a DWORD at the end of LINECALLPARAMS + *pdwProxyRequests++ = LINEPROXYREQUEST_SETAGENTGROUP; + *pdwProxyRequests++ = LINEPROXYREQUEST_SETAGENTSTATE; + *pdwProxyRequests++ = LINEPROXYREQUEST_SETAGENTACTIVITY; + *pdwProxyRequests++ = LINEPROXYREQUEST_GETAGENTSTATUS; + *pdwProxyRequests++ = LINEPROXYREQUEST_GETAGENTCAPS; + *pdwProxyRequests++ = LINEPROXYREQUEST_GETAGENTACTIVITYLIST; + *pdwProxyRequests = LINEPROXYREQUEST_GETAGENTGROUPLIST; + + lResult = lineOpen(g.hLineApp, + dwDeviceID, + &pAgent->hLine, + TAPI_CURRENT_VERSION, + 0, + 0, + LINEOPENOPTION_PROXY | LINECALLPRIVILEGE_MONITOR, + LINEMEDIAMODE_INTERACTIVEVOICE, + pLCP); + + ACDFree(pLCP); + + if (lResult) + { + // + ACDFree(pAgent->lpszName); + ACDFree(pAgent); + + } + + pLDC = LineGetDevCaps(g.hLineApp, + pAgent->dwDeviceID); + + if (!pLDC) + { + return FALSE; + } + + // alloc memory for address specific info + pAgent->pAddressInfo = (PADDRESSINFO)ACDAlloc(sizeof(ADDRESSINFO) * pLDC->dwNumAddresses); + pAgent->dwNumAddresses = pLDC->dwNumAddresses; + + ACDFree(pLDC); + + // increment number of agents + g.dwNumAgents++; + + return pAgent; +} + + +////////////////////////////////////////////////////////////////////////// +// +// BOOL DeleteAgent(PAGENT pAgent) +// +// Frees all memory associated with pAgent, removes +// agent from group lists, and remove pAgent from +// global agent list +// +////////////////////////////////////////////////////////////////////////// +BOOL DeleteAgent(PAGENT pAgent) +{ + PGROUP pGroup; + + + lineClose(pAgent->hLine); + + // free name + ACDFree(pAgent->lpszName); + ACDFree(pAgent->lpszNumber); + + // free address info + ACDFree(pAgent->pAddressInfo); + + pGroup = g.pGroups; + + // walk through groups and remove from + // group list if in group list + while (pGroup) + { + if (IsAgentInList(pGroup->pAgentList, + pAgent)) + { + RemoveFromGroupList(pGroup, + pAgent); + } + + pGroup = pGroup->pNext; + + } + + // finally, remove pAgent from global list + DeleteStruct((PGENERICSTRUCT *)&g.pAgents, + (PGENERICSTRUCT)pAgent); + + return TRUE; +} + + +////////////////////////////////////////////////////////////////////////// +// +// BOOL DeleteGroup(PGROUP pGroup) +// +// Frees memory assocated with pGroup, and removes the structure from +// the global list +// +////////////////////////////////////////////////////////////////////////// +BOOL DeleteGroup(PGROUP pGroup) +{ + PLISTITEM pList, pListNext; + + lineClose(pGroup->hLine); + + ACDFree(pGroup->lpszName); + + pList = pGroup->pAgentList; + + while (pList) + { + pListNext = pList->pNext; + ACDFree(pList); + pList = pListNext; + } + + DeleteStruct((PGENERICSTRUCT *)&g.pGroups, + (PGENERICSTRUCT)pGroup); + + return TRUE; +} + + +////////////////////////////////////////////////////////////////////////// +// +// BOOL InsertIntoGroupList(PGROUP pGroup, +// PAGENT pAgent) +// +// Insert an agent in a group +// +////////////////////////////////////////////////////////////////////////// +BOOL InsertIntoGroupList(PGROUP pGroup, + PAGENT pAgent) +{ + PLISTITEM pListItem; + + pListItem = (PLISTITEM)ACDAlloc(sizeof(LISTITEM)); + + pListItem->dwKey = LISTKEY; + pListItem->dwSize = sizeof(LISTITEM); + pListItem->pAgent = pAgent; + + InsertStruct((PGENERICSTRUCT *)&pGroup->pAgentList, + (PGENERICSTRUCT)pListItem); + + return TRUE; +} + +////////////////////////////////////////////////////////////////////////// +// +// BOOL RemoveFromGroupList(PGROUP pGroup, +// +// remove an agent from a group's list +// +////////////////////////////////////////////////////////////////////////// +BOOL RemoveFromGroupList(PGROUP pGroup, + PAGENT pAgent) +{ + PLISTITEM pList; + + pList = pGroup->pAgentList; + + while (pList) + { + if (pList->pAgent == pAgent) + { + break; + } + + pList = pList->pNext; + } + + if (!pList) + { + return FALSE; + } + + DeleteStruct((PGENERICSTRUCT *)&pGroup->pAgentList, + (PGENERICSTRUCT)pList); + + return TRUE; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +//PLISTITEM IsAgentInList(PLISTITEM pList, +// PAGENT pAgent) +// +//////////////////////////////////////////////////////////////////////////////// +PLISTITEM IsAgentInList(PLISTITEM pList, + PAGENT pAgent) +{ + while (pList) + { + if (pList->pAgent == pAgent) + { + return pList; + } + + pList = pList->pNext; + } + + return NULL; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// PAGENT GetAgentFromName(LPTSTR lpszName) +// +//////////////////////////////////////////////////////////////////////////////// +PAGENT GetAgentFromName(LPTSTR lpszName) +{ + PAGENT pHold; + + pHold = g.pAgents; + + while (pHold) + { + if (!lstrcmpi(pHold->lpszName, + lpszName)) + { + return pHold; + } + + pHold = pHold->pNext; + } + + return NULL; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// PAGENT GetAgentFromhLine(HLINE hLine) +// +/////////////////////////////////////////////////////////////////////////////// +PAGENT GetAgentFromhLine(HLINE hLine) +{ + PAGENT pAgent; + + pAgent = g.pAgents; + + while (pAgent) + { + if (pAgent->hLine == hLine) + { + return pAgent; + } + + pAgent = pAgent->pNext; + } + + return NULL; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// DWORD GetDeviceID(DWORD dwPermID) +// +/////////////////////////////////////////////////////////////////////////////// +DWORD GetDeviceID(DWORD dwPermID) +{ + DWORD dwCount; + + for (dwCount = 0; dwCount < g.dwNumDevs; dwCount++) + { + if (g.pdwPermIDs[dwCount] == dwPermID) + { + return dwCount; + } + } + + return (DWORD)-1; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// **************TAPI WRAPPER FUNCTIONS************** +// +/////////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetAddressCaps() +// +/////////////////////////////////////////////////////////////////////////////// +LINEADDRESSCAPS * LineGetAddressCaps (HLINEAPP hLineApp, + DWORD dwDeviceID, + DWORD dwAddressID) +{ + LONG lRetVal; + LINEADDRESSCAPS * pLineAddressCaps; + static DWORD dwMaxNeededSize = sizeof(LINEADDRESSCAPS); + + // Allocate an initial block of memory for the LINEADDRESSCAPS structure, + // which may or may not be big enough to hold all of the information. + // + pLineAddressCaps = ACDAlloc(dwMaxNeededSize); + + for (;;) + { + if (pLineAddressCaps == NULL) + { + return NULL; + } + pLineAddressCaps->dwTotalSize = dwMaxNeededSize; + + // Try (or retry) to get the LINEADDRESSCAPS information + // + lRetVal = lineGetAddressCaps(hLineApp, + dwDeviceID, + dwAddressID, + TAPI_CURRENT_VERSION, + 0, + pLineAddressCaps); + if (lRetVal < 0) + { + ACDFree((HLOCAL)pLineAddressCaps); + return NULL; + } + + // If the currently allocated LINEADDRESSCAPS memory block was big + // enough, we're all done, else we need to realloc the memory block + // and try again. + // + if (pLineAddressCaps->dwNeededSize <= dwMaxNeededSize) + { + return pLineAddressCaps; + } + else + { + dwMaxNeededSize = pLineAddressCaps->dwNeededSize; + pLineAddressCaps = ACDReAlloc((HLOCAL)pLineAddressCaps, + dwMaxNeededSize); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetCallInfo() +// +/////////////////////////////////////////////////////////////////////////////// +LINECALLINFO * LineGetCallInfo (HCALL hCall) +{ + LONG lRetVal; + LINECALLINFO * pLineCallInfo; + static DWORD dwMaxNeededSize = sizeof(LINECALLINFO); + + // Allocate an initial block of memory for the LINECALLINFO structure, + // which may or may not be big enough to hold all of the information. + // + pLineCallInfo = ACDAlloc(dwMaxNeededSize); + + for (;;) + { + if (pLineCallInfo == NULL) + { + return NULL; + } + pLineCallInfo->dwTotalSize = dwMaxNeededSize; + + // Try (or retry) to get the LINECALLINFO information + // + lRetVal = lineGetCallInfo(hCall, + pLineCallInfo); + if (lRetVal < 0) + { + ACDFree((HLOCAL)pLineCallInfo); + return NULL; + } + + // If the currently allocated LINECALLINFO memory block was big + // enough, we're all done, else we need to realloc the memory block + // and try again. + // + if (pLineCallInfo->dwNeededSize <= dwMaxNeededSize) + { + return pLineCallInfo; + } + else + { + dwMaxNeededSize = pLineCallInfo->dwNeededSize; + pLineCallInfo = ACDReAlloc((HLOCAL)pLineCallInfo, + dwMaxNeededSize); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetDevCaps() +// +/////////////////////////////////////////////////////////////////////////////// +LINEDEVCAPS * LineGetDevCaps (HLINEAPP hLineApp, + DWORD dwDeviceID) +{ + LONG lRetVal; + LINEDEVCAPS * pLineDevCaps; + static DWORD dwMaxNeededSize = sizeof(LINEDEVCAPS); + + pLineDevCaps = ACDAlloc(dwMaxNeededSize); + for (;;) + { + if (pLineDevCaps == NULL) + { + return NULL; + } + pLineDevCaps->dwTotalSize = dwMaxNeededSize; + lRetVal = lineGetDevCaps(hLineApp, + dwDeviceID, + TAPI_CURRENT_VERSION, + 0, + pLineDevCaps); + if (lRetVal < 0) + { + ACDFree((HLOCAL)pLineDevCaps); + return NULL; + } + if (pLineDevCaps->dwNeededSize <= dwMaxNeededSize) + { + return pLineDevCaps; + } + else + { + dwMaxNeededSize = pLineDevCaps->dwNeededSize; + pLineDevCaps = ACDReAlloc((HLOCAL)pLineDevCaps, + dwMaxNeededSize); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetID() +// +/////////////////////////////////////////////////////////////////////////////// +VARSTRING * LineGetID (HLINE hLine, + DWORD dwAddressID, + HCALL hCall, + DWORD dwSelect, + LPCTSTR lpszDeviceClass) +{ + LONG lRetVal; + VARSTRING * pVarString; + static DWORD dwMaxNeededSize = sizeof(VARSTRING); + + // Allocate an initial block of memory for the VARSTRING structure, + // which may or may not be big enough to hold all of the information. + // + pVarString = ACDAlloc(dwMaxNeededSize); + + for (;;) + { + if (pVarString == NULL) + { + return NULL; + } + pVarString->dwTotalSize = dwMaxNeededSize; + + // Try (or retry) to get the VARSTRING information + // + lRetVal = lineGetID(hLine, + dwAddressID, + hCall, + dwSelect, + pVarString, + lpszDeviceClass); + if (lRetVal < 0) + { + ACDFree(pVarString); + return NULL; + } + + // If the currently allocated VARSTRING memory block was big + // enough, we're all done, else we need to realloc the memory block + // and try again. + // + if (pVarString->dwNeededSize <= dwMaxNeededSize) + { + return pVarString; + } + else + { + dwMaxNeededSize = pVarString->dwNeededSize; + pVarString = ACDReAlloc((HLOCAL)pVarString, + dwMaxNeededSize); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetCallStatus() +// +/////////////////////////////////////////////////////////////////////////////// +LINECALLSTATUS * LineGetCallStatus (HCALL hCall) +{ + LONG lRetVal; + LINECALLSTATUS * pLineCallStatus; + static DWORD dwMaxNeededSize = sizeof(LINECALLSTATUS); + + // Allocate an initial block of memory for the LINECALLSTATUS structure, + // which may or may not be big enough to hold all of the information. + // + pLineCallStatus = ACDAlloc(dwMaxNeededSize); + + while (TRUE) + { + if (pLineCallStatus == NULL) + { + return NULL; + } + pLineCallStatus->dwTotalSize = dwMaxNeededSize; + + // Try (or retry) to get the LINECALLSTATUS information + // + lRetVal = lineGetCallStatus(hCall, + pLineCallStatus); + if (lRetVal < 0) + { + ACDFree((HLOCAL)pLineCallStatus); + return NULL; + } + + // If the currently allocated LINECALLSTATUS memory block was big + // enough, we're all done, else we need to realloc the memory block + // and try again. + // + if (pLineCallStatus->dwNeededSize <= dwMaxNeededSize) + { + return pLineCallStatus; + } + else + { + dwMaxNeededSize = pLineCallStatus->dwNeededSize; + pLineCallStatus = ACDReAlloc((HLOCAL)pLineCallStatus, + dwMaxNeededSize); + } + } +} + diff --git a/private/tapi/dev/apps/acd/clntapp.cpp b/private/tapi/dev/apps/acd/clntapp.cpp new file mode 100644 index 000000000..7f1732750 --- /dev/null +++ b/private/tapi/dev/apps/acd/clntapp.cpp @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +#include <windows.h> + +////////////////////////////////////////////////////////////////////////////// +// PROTOTYPES +////////////////////////////////////////////////////////////////////////////// +static BOOL CreateMainWindow (int nCmdShow); + +static LRESULT CALLBACK MainWndProc (HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); + +////////////////////////////////////////////////////////////////////////////// +// GLOBALS +////////////////////////////////////////////////////////////////////////////// +HINSTANCE ghInstance; +HWND ghMainWnd; + +////////////////////////////////////////////////////////////////////////////// +// +// WinMain() +// +////////////////////////////////////////////////////////////////////////////// + +int WINAPI WinMain (HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) +{ + MSG msg; + + ghInstance = hInstance; + + if (!CreateMainWindow(nCmdShow)) + { + return 0; + } + + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return 1; +} + + +//***************************************************************************** +// CreateMainWindow() +//***************************************************************************** + +BOOL CreateMainWindow (int nCmdShow) +{ + WNDCLASS wc; + static char szClassName[] = "TapiClientWndClass"; + + wc.style = 0; + wc.lpfnWndProc = MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = ghInstance; + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.lpszMenuName = NULL; + wc.lpszClassName = szClassName; + + + if (!RegisterClass(&wc)) + { + return FALSE; + } + + ghMainWnd = CreateWindow(szClassName, + "Tapi Client App", + WS_OVERLAPPEDWINDOW, + 0, + 0, + GetSystemMetrics(SM_CXSCREEN)/2, + GetSystemMetrics(SM_CYSCREEN)/2, + NULL, + NULL, + ghInstance, + NULL); + + if (ghMainWnd == NULL) + { + return FALSE; + } + + ShowWindow(ghMainWnd, nCmdShow); + UpdateWindow(ghMainWnd); + return TRUE; +} + + +//***************************************************************************** +// MainWndProc() +//***************************************************************************** + +LRESULT CALLBACK MainWndProc (HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) + { + case WM_DESTROY: + PostQuitMessage(0); + break; + + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + return 0; +} + diff --git a/private/tapi/dev/apps/acd/makefile b/private/tapi/dev/apps/acd/makefile new file mode 100644 index 000000000..f1084966b --- /dev/null +++ b/private/tapi/dev/apps/acd/makefile @@ -0,0 +1,29 @@ +!if "$(OS)" == "Windows_NT" + +!INCLUDE $(NTMAKEENV)\makefile.def + +!else + +############################################################################## +# +# Dialer.exe Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\.. + +VERSIONLIST=debug retail + +DEPENDNAME=depend.mk + +COMMONMKFILE=makefile.def + +IS_OEM=TRUE +IS_32 = TRUE + +!include $(ROOT)\dev\master.mk + +!endif + diff --git a/private/tapi/dev/apps/acd/makefile.sdk b/private/tapi/dev/apps/acd/makefile.sdk new file mode 100644 index 000000000..0d3c5a56e --- /dev/null +++ b/private/tapi/dev/apps/acd/makefile.sdk @@ -0,0 +1,35 @@ +# Define NODEBUG to build ACDSMPL without debugging information. +# Define UNICODE to build ACDSMPL with UNICODE characters. + +TARGETOS=WINNT + +!include <ntwin32.mak> + +unicode = -DUNICODE + +cflags=$(cflags) -DWIN32_LEAN_AND_MEAN + +all: acdsmpl.exe + +# Update the resource if necessary + +acdsmpl.res: acdsmpl.rc resource.h + $(rc) $(rcvars) -r acdsmpl.rc + +# Update the object files if necessary + +acdsmpl.obj: acdsmpl.c resource.h acdsmpl.h + $(cc) $(cdebug) $(cflags) $(cvars) $(unicode) acdsmpl.c + +acdtapi.obj: acdtapi.c resource.h acdsmpl.h + $(cc) $(cdebug) $(cflags) $(cvars) $(unicode) acdtapi.c + +acdutils.obj: acdutils.c resource.h acdsmpl.h + $(cc) $(cdebug) $(cflags) $(cvars) $(unicode) acdutils.c + +# Update the executable file if necessary, and if so, add the resource back in. + +acdsmpl.exe: acdsmpl.obj acdtapi.obj acdutils.obj acdsmpl.res makefile.sdk + $(link) $(linkdebug) $(guiflags) -out:acdsmpl.exe\ + acdsmpl.obj acdtapi.obj acdutils.obj acdsmpl.res\ + version.lib tapi32.lib comctl32.lib $(guilibsmt) diff --git a/private/tapi/dev/apps/acd/resource.h b/private/tapi/dev/apps/acd/resource.h new file mode 100644 index 000000000..5499d6d80 --- /dev/null +++ b/private/tapi/dev/apps/acd/resource.h @@ -0,0 +1,43 @@ +//////////////////////////////////////////////////////////////////////// +// +// resource.h +// +//////////////////////////////////////////////////////////////////////// +#define IDD_MAINDLG 101 +#define IDD_ADD 102 +#define IDD_ADDTOLIST 103 +#define IDD_ADDAGENT 104 +#define IDC_TREEWND 1000 +#define IDC_EDITWND 1001 +#define IDM_NEWGROUP 1002 +#define IDM_NEWAGENT 1003 +#define IDM_GROUPPROPERTIES 1004 +#define IDM_GROUPDELETE 1005 +#define IDM_AGENTPROPERTIES 1006 +#define IDM_AGENTDELETE 1007 +#define IDM_SIGNIN 1008 +#define IDC_NAME 1009 +#define IDC_NUMBER 1010 +#define IDC_LIST1 1011 +#define IDC_LIST2 1012 +#define IDC_ADD 1013 +#define IDC_REMOVE 1014 +#define IDM_GROUPADDTOLIST 1015 +#define IDM_AGENTADDTOLIST 1016 +#define IDC_STATICNOTINLIST 1017 +#define IDC_STATICINLIST 1018 +#define IDR_MAINMENU 1019 +#define ID_FILE_OPEN 1020 +#define ID_FILE_EXIT 1021 +#define ID_FILE_NEW 1022 +#define ID_EDIT_ADDAGENT 1023 +#define ID_EDIT_ADDGROUP 1024 +#define IDC_LINECOMBO 1025 +#define IDC_ADDRESSCOMBO 1026 +#define IDM_GROUPAGENTSTATUS 1027 +#define ID_VIEW_GROUP 1028 +#define ID_VIEW_AGENT 1029 +#define IDC_DESTADDRESS 1030 + +#define IDC_STATIC -1 + diff --git a/private/tapi/dev/apps/acd/sources b/private/tapi/dev/apps/acd/sources new file mode 100644 index 000000000..9412ca2ac --- /dev/null +++ b/private/tapi/dev/apps/acd/sources @@ -0,0 +1,59 @@ +!IF 0 + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + +Author: + + John Rogers (JohnRo) 25-Oct-1991 + +Notes: + + Commented description of this file is in \nt\public\oak\bin\sources.tpl + +Revision History: + +!ENDIF + + +MAJORCOMP=net +MINORCOMP=tapi + +TARGETNAME=acdsmpl +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=PROGRAM + +TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\comdlg32.lib \ + $(BASEDIR)\public\sdk\lib\*\shell32.lib \ + $(BASEDIR)\public\sdk\lib\*\tapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\comctl32.lib + +INCLUDES=.;$(BASEDIR)\public\sdk\inc + +USE_CRTDLL=1 + +SOURCES=acdsmpl.c \ + acdtapi.c \ + acdutils.c \ + acdsmpl.rc + +C_DEFINES=-DWINVER=0x0400 -DUNICODE + +UMTYPE=windows + +UMENTRY=winmain + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF diff --git a/private/tapi/dev/apps/acdclnt/acdclnt.c b/private/tapi/dev/apps/acdclnt/acdclnt.c new file mode 100644 index 000000000..6a1cf1e3c --- /dev/null +++ b/private/tapi/dev/apps/acdclnt/acdclnt.c @@ -0,0 +1,1948 @@ +////////////////////////////////////////////////////////////////////////////// +// +// ACDCLNT.C +// +// ACDClient app +// +////////////////////////////////////////////////////////////////////////////// +#include <windows.h> +#include <tapi.h> +#include "acdclnt.h" +#include "resource.h" + + + +////////////////////////////////////////////////////////////////////////////// +// PROTOTYPES +////////////////////////////////////////////////////////////////////////////// +static BOOL CreateMainWindow (int nCmdShow); + +static LRESULT CALLBACK MainWndProc (HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); + +LRESULT CALLBACK AgentStateDlgProc (HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); + +VOID CALLBACK LineCallback (DWORD hDevice, + DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +BOOL InitTapi(); + +BOOL CloseTapi(); + +BOOL RedoWindow(); + +BOOL SetStatusMessage(LPTSTR lpszMessage); + +BOOL SetButton(DWORD dwAddress, + BOOL bAnswer, + BOOL bEnable); + +LRESULT WaitForLineReply(); + +LONG ThreadRoutine(LPVOID lpv); + +////////////////////////////////////////////////////////////////////////////// +// +// GLOBALS +// +////////////////////////////////////////////////////////////////////////////// +HINSTANCE ghInstance; // main instance +HWND ghMainWnd; // main window +PADDRESSINFO pAddressInfo = NULL; // array of info about each address +HLINEAPP ghLineApp; // hlineapp +DWORD gdwAddresses; // number of addresses on our line +DWORD gdwDeviceID; // our device +HLINE ghLine; // our line + +HANDLE ghCompletionPort; // tapi message completionport +CRITICAL_SECTION csLineReply; + +// using global variables to keep track of line +// replies, since the main thread will only have at most one outstanding +// line reply at a time +BOOL gbReply; +LONG glResult; + + +////////////////////////////////////////////////////////////////////////////// +// +// WinMain() +// +////////////////////////////////////////////////////////////////////////////// +int WINAPI WinMain (HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) +{ + MSG msg; + + ghInstance = hInstance; + + if(!InitTapi()) + { + MessageBox(NULL, + TEXT("Failed to initialize TAPI"), + TEXT("Cannot start ACDClient"), + MB_OK); + + return 0; + } + + if (!CreateMainWindow(nCmdShow)) + { + return 0; + } + + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return 1; +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// CreateMainWindow() +// +/////////////////////////////////////////////////////////////////////////////// +BOOL CreateMainWindow (int nCmdShow) +{ + + // main window + ghMainWnd = CreateDialog(ghInstance, + MAKEINTRESOURCE(IDD_MAINDLG), + NULL, + MainWndProc); + + if (ghMainWnd == NULL) + { + return FALSE; + } + + SetStatusMessage(TEXT("Waiting for call")); + + // create buttons + RedoWindow(); + + ShowWindow(ghMainWnd, nCmdShow); + + UpdateWindow(ghMainWnd); + + return TRUE; +} + + +///////////////////////////////////////////////////////////////////////////////// +// +// BOOL SetStatusMessage(LPTSTR lpszMessage) +// +// Sets text in the static control at the bottom of the main window to +// lpszMessage +// +///////////////////////////////////////////////////////////////////////////////// +BOOL SetStatusMessage(LPTSTR lpszMessage) +{ + return (SetWindowText(GetDlgItem(ghMainWnd, + IDC_STATIC1), + lpszMessage)); + +} + + +///////////////////////////////////////////////////////////////////////////////// +// +// BOOL ClearCall(HCALL hCall) +// +// Called when a CALLSTATE_IDLE message is recieved. Looks for the call in the +// global pAddressInfo array. If it finds it, is clears the appropriate members +// of the structure +// +///////////////////////////////////////////////////////////////////////////////// +BOOL ClearCall(HCALL hCall) +{ + DWORD dwCount; + + for (dwCount = 0; dwCount < gdwAddresses; dwCount++) + { + if (pAddressInfo[dwCount].hCall == hCall) + { + pAddressInfo[dwCount].hCall = NULL; + pAddressInfo[dwCount].bCall = FALSE; + SetButton(dwCount, + TRUE, + FALSE); + return TRUE; + } + } + + return FALSE; +} + + +////////////////////////////////////////////////////////////////////////////////// +// +// BOOL SetButton() +// +// Sets the status and text of the answer/drop button for a specific address +// +////////////////////////////////////////////////////////////////////////////////// +BOOL SetButton(DWORD dwAddress, + BOOL bAnswer, + BOOL bEnable) +{ + if (dwAddress >= gdwAddresses) + return FALSE; + + if (bAnswer) + { + SetWindowText(pAddressInfo[dwAddress].hAnswer, + TEXT("Answer")); + } + else + { + SetWindowText(pAddressInfo[dwAddress].hAnswer, + TEXT("Hang Up")); + } + + EnableWindow(pAddressInfo[dwAddress].hAnswer, + bEnable); + + return TRUE; +} + + + +/////////////////////////////////////////////////////////////////////////////// +// +// VOID CALLBACK LineCallback () +// +// TAPI callback function. Handles all tapi messages +// +/////////////////////////////////////////////////////////////////////////////// +VOID CALLBACK LineCallback (DWORD hDevice, + DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + LPLINECALLINFO pLCI; + LPLINECALLSTATUS pLCS; + TCHAR szBuffer[64]; + + switch (dwMsg) + { + case LINE_REPLY: + { + EnterCriticalSection(&csLineReply); + if (dwParam1 == (DWORD)glResult) + { + gbReply = TRUE; + glResult = dwParam2; + } + LeaveCriticalSection(&csLineReply); + } + break; + + case LINE_CALLSTATE: + { + if (dwParam1 == LINECALLSTATE_OFFERING) + { + // get the call privilege + // note note note the new LINE_APPNEWCALL + // give call privilege + pLCS = LineGetCallStatus((HCALL)hDevice); + + if (!pLCS) + return; + + if (!(pLCS->dwCallPrivilege & LINECALLPRIVILEGE_OWNER)) + { + // not our call + GlobalFree(pLCS); + return; + } + + GlobalFree(pLCS); + + // we're getting offered a call + // first get the address + pLCI = LineGetCallInfo((HCALL)hDevice); + + if (!pLCI) + { + // error + return; + } + + // set the status message text + wsprintf(szBuffer, + TEXT("Incoming call on address %lu"), + pLCI->dwAddressID); + + pAddressInfo[pLCI->dwAddressID].hCall = (HCALL)hDevice; + + SetStatusMessage(szBuffer); + + // set the button to answer + SetButton(pLCI->dwAddressID, + TRUE, + TRUE); + + GlobalFree(pLCI); + + break; + } + + if (dwParam1 == LINECALLSTATE_IDLE) + { + // see if we have this call + ClearCall((HCALL)hDevice); + // dealloc no matter what + lineDeallocateCall((HCALL)hDevice); + + break; + } + } + + break; + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// BOOL GetAddressFromhWnd() +// +/////////////////////////////////////////////////////////////////////////////// +BOOL GetAddressFromhWnd(HWND hWnd, + LPDWORD pdwAddress, + LPBOOL pbStatus) +{ + DWORD dwAddress; + + // go through the array of addressinfo and see + // if the hwnd matches + for (dwAddress = 0; dwAddress < gdwAddresses; dwAddress++) + { + if (pAddressInfo[dwAddress].hStatus == hWnd) + { + *pdwAddress = dwAddress; + *pbStatus = TRUE; + + return TRUE; + } + if (pAddressInfo[dwAddress].hAnswer == hWnd) + { + *pdwAddress = dwAddress; + *pbStatus = FALSE; + + return TRUE; + } + } + + return FALSE; +} + +///////////////////////////////////////////////////////////////////////////// +// +// BOOL DoLineAnswerDrop(DWORD dwAddress) +// +// Handles what happens when the answer/drop button is pressed +// +///////////////////////////////////////////////////////////////////////////// +BOOL DoLineAnswerDrop(DWORD dwAddress) +{ + // if we have a call, then we want to drop it + if (pAddressInfo[dwAddress].bCall) + { + + SetStatusMessage(TEXT("Hanging up call ...")); + + EnterCriticalSection(&csLineReply); + glResult = lineDrop(pAddressInfo[dwAddress].hCall, + NULL, + 0); + + if (glResult < 0) + { + LeaveCriticalSection(&csLineReply); + // error + } + + else if (WaitForLineReply()) + { + // error + } + + // error or not, deallocate and set button + lineDeallocateCall(pAddressInfo[dwAddress].hCall); + + SetButton(dwAddress, + TRUE, + FALSE); + + pAddressInfo[dwAddress].hCall = NULL; + pAddressInfo[dwAddress].bCall = FALSE; + + SetStatusMessage(TEXT("Waiting for a call")); + + } + else + { + BOOL bError = FALSE; + + + // answer + SetStatusMessage(TEXT("Answering call...")); + + EnterCriticalSection(&csLineReply); + glResult = lineAnswer(pAddressInfo[dwAddress].hCall, + NULL, + 0); + + if (glResult < 0) + { + LeaveCriticalSection(&csLineReply); + bError = TRUE; + //error + } + else if (WaitForLineReply()) + { + bError = TRUE; + // error + } + + if (bError) + { + SetStatusMessage(TEXT("Hanging up call ...")); + lineDeallocateCall(pAddressInfo[dwAddress].hCall); + pAddressInfo[dwAddress].hCall = NULL; + SetButton(dwAddress, + TRUE, + FALSE); + + SetStatusMessage(TEXT("Waiting for a call")); + return FALSE; + } + + SetStatusMessage(TEXT("On a call")); + + pAddressInfo[dwAddress].bCall = TRUE; + + SetButton(dwAddress, + FALSE, + TRUE); + } + + return TRUE; +} + +////////////////////////////////////////////////////////////////////// +// +// LRESULT DoCommand(WPARAM wParam, +// LPARAM lParam) +// +// Handles WM_COMMAND messages for the main window +// +////////////////////////////////////////////////////////////////////// +LRESULT DoCommand(WPARAM wParam, + LPARAM lParam) +{ + DWORD dwAddress; + BOOL bStatus; + + // check to see if a button is being clicked + if (HIWORD(wParam) == BN_CLICKED) + { + // check to see if it is a button we care about + if (GetAddressFromhWnd((HWND)lParam, + &dwAddress, + &bStatus)) + { + + // if it's the status button, display the status + // dialog + if (bStatus) + { + DialogBoxParam(ghInstance, + MAKEINTRESOURCE(IDD_AGENTSTATE), + ghMainWnd, + AgentStateDlgProc, + (LPARAM)dwAddress); + } + // else it's the answer/drop button + else + { + DoLineAnswerDrop(dwAddress); + } + } + + return 1; + + } + + + return 0; +} + + + +//////////////////////////////////////////////////////////////////////////////// +// +// MainWndProc() +// +//////////////////////////////////////////////////////////////////////////////// +LRESULT CALLBACK MainWndProc (HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + + return 1; + + case WM_COMMAND: + + return DoCommand(wParam, + lParam); + + break; + + case WM_CLOSE: + case WM_DESTROY: + CloseTapi(); + PostQuitMessage(0); + return 1; + } + + return 0; +} + + +/////////////////////////////////////////////////////////////////////// +// +// BOOL InitTapi() +// +// Initializes TAPI. For this sample, we assume that the "agent" (the person +// logged on) can only have access to _one_ hLine. Also, they have access to +// every address on that line. This may not be true for many ACD situations. +// +// As soon as we find a device that the agent has access to, we quit +// looking, and use that device +// +/////////////////////////////////////////////////////////////////////// +BOOL InitTapi() +{ + LONG lResult; + LINEINITIALIZEEXPARAMS exparams; + LPLINEAGENTCAPS pLAC; + LPLINEDEVCAPS pLDC; + DWORD dwDeviceID, dwNumDevs, dwAPIVersion, dwThreadID; + + // initialize completion port to receive TAPI notifications + ghCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, + NULL, + 0, + 0); + + InitializeCriticalSection(&csLineReply); + + // fill in lineinitex parameters + exparams.dwTotalSize = sizeof(LINEINITIALIZEEXPARAMS); + exparams.dwOptions = LINEINITIALIZEEXOPTION_USECOMPLETIONPORT; + exparams.Handles.hCompletionPort = ghCompletionPort; + + dwAPIVersion = TAPI_CURRENT_VERSION; + + lResult = lineInitializeEx(&ghLineApp, + ghInstance, + NULL, + SZAPPNAME, + &dwNumDevs, + &dwAPIVersion, + &exparams); + + if (lResult) + { + return FALSE; + } + + // if no devices, don't continue + if (dwNumDevs == 0) + { + lineShutdown(ghLineApp); + return FALSE; + } + + // kick off completion port thread + CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)ThreadRoutine, + NULL, + 0, + &dwThreadID); + + + // loop through all devices + for (dwDeviceID = 0; dwDeviceID < dwNumDevs; dwDeviceID++) + { + // Get the Agent Caps. If this succeedes, this is + // a device we can use + pLAC = LineGetAgentCaps(ghLineApp, + dwDeviceID, + 0); + + if (pLAC) + { + // this is a device we can use + gdwDeviceID = dwDeviceID; + + // get the number of addresses + pLDC = LineGetDevCaps(ghLineApp, + dwDeviceID); + + if (pLDC) + { + gdwAddresses = pLDC->dwNumAddresses; + GlobalFree(pLDC); + } + + GlobalFree(pLAC); + break; + } + } + + // open the line in owner mode + lResult = lineOpen(ghLineApp, + gdwDeviceID, + &ghLine, + TAPI_CURRENT_VERSION, + 0, + 0, + LINECALLPRIVILEGE_OWNER, + LINEMEDIAMODE_INTERACTIVEVOICE, + NULL); + + // if line failed, don't continue + if (lResult) + { + lineShutdown(ghLineApp); + return FALSE; + } + + + return TRUE; +} + + +////////////////////////////////////////////////////////////////////// +// +// ThreadRoutine +// +// Thread dedicated to checking completion port for TAPI events +// +////////////////////////////////////////////////////////////////////// +LONG ThreadRoutine(LPVOID lpv) +{ + LPLINEMESSAGE pMsg; + DWORD dwNumBytesTransfered, dwCompletionKey; + + + // just wait for tapi notifications + while (GetQueuedCompletionStatus(ghCompletionPort, + &dwNumBytesTransfered, + &dwCompletionKey, + (LPOVERLAPPED *) &pMsg, + INFINITE)) + { + if (pMsg) + { + // when we get one, call the handling function + LineCallback(pMsg->hDevice, + pMsg->dwMessageID, + pMsg->dwCallbackInstance, + pMsg->dwParam1, + pMsg->dwParam2, + pMsg->dwParam3); + + LocalFree (pMsg); + } + else + { + break; + } + } + + ExitThread(0); + return 0; +} + + +/////////////////////////////////////////////////////////////////////////// +// +// BOOL CloseTapi() +// +// Close tapi and free resources +// +/////////////////////////////////////////////////////////////////////////// +BOOL CloseTapi() +{ + GlobalFree(pAddressInfo); + + CloseHandle(ghCompletionPort); + + lineClose(ghLine); + lineShutdown(ghLineApp); + + return TRUE; +} + +// static information for the status dialog +static DWORD dwAgentStates[] = + { + LINEAGENTSTATE_LOGGEDOFF, + LINEAGENTSTATE_NOTREADY, + LINEAGENTSTATE_READY, + LINEAGENTSTATE_BUSYACD, + LINEAGENTSTATE_BUSYINCOMING, + LINEAGENTSTATE_BUSYOUTBOUND, + LINEAGENTSTATE_BUSYOTHER, + LINEAGENTSTATE_WORKINGAFTERCALL, + LINEAGENTSTATE_UNKNOWN, + LINEAGENTSTATE_UNAVAIL, + 0 + }; + +static LPTSTR lpszStates[] = + { + TEXT("Logged Off"), + TEXT("Not Ready"), + TEXT("Ready"), + TEXT("Busy ACD"), + TEXT("Busy Incoming"), + TEXT("Busy Outbound"), + TEXT("Busy Other"), + TEXT("Working after call"), + TEXT("Unknown"), + TEXT("Unavail"), + NULL + }; + +/////////////////////////////////////////////////////////////////////////// +// +// BOOL InitAgentDlg() +// +// Handles initialization of the status dialog +// +// Gets the group list and puts groups in multiselect list box +// these are the groups that the agent _can_ log into +// the groups they are logged into will be selected +// Creates comboboxes of states and nextstates, and select +// the agent's current state/nextstate +// Gets the activity list and puts each item into a combobox +// the current activity will be selected +// +/////////////////////////////////////////////////////////////////////////// +BOOL InitAgentDlg(HWND hwnd, + DWORD dwAddress, + LPLINEAGENTGROUPLIST * ppLAG) +{ + LPLINEAGENTCAPS pLAC; + LPLINEAGENTSTATUS pLAS; + LPLINEAGENTACTIVITYLIST pLAA; + LPLINEAGENTGROUPENTRY pEntry, pLoggedInEntry; + LPLINEAGENTACTIVITYENTRY pActivityEntry; + DWORD dwEntries, dwCount; + LONG item; + + // first, get the status + // this information will be used to know which items to select + // in each of the listbox/comboboxes + pLAS = LineGetAgentStatus(ghLine, + dwAddress); + + if (!pLAS) + { + return FALSE; + } + + // get the group list + if (!(*ppLAG = LineGetAgentGroupList(ghLine, + dwAddress))) + { + return FALSE; + } + + // get the first groupentry + pEntry = (LPLINEAGENTGROUPENTRY)(((LPBYTE)*ppLAG)+(*ppLAG)->dwListOffset); + + // loop through the group entries + for (dwEntries = 0; dwEntries < (*ppLAG)->dwNumEntries; dwEntries++) + { + // add group to list box + item = SendDlgItemMessage(hwnd, + IDC_GROUPS, + LB_ADDSTRING, + 0, + (LPARAM)(LPTSTR)(((LPBYTE)*ppLAG) + pEntry->dwNameOffset)); + + // save the entry + SendDlgItemMessage(hwnd, + IDC_GROUPS, + LB_SETITEMDATA, + (WPARAM)item, + (LPARAM)pEntry); + + // now get list of groups currently logged into from the agent status structure + // loop through them. if any of them match the group we are currently adding + // select that group + pLoggedInEntry = (LPLINEAGENTGROUPENTRY)(((LPBYTE)pLAS) + pLAS->dwGroupListOffset); + for (dwCount = 0; dwCount < pLAS->dwNumEntries; dwCount++) + { + if ((pLoggedInEntry->GroupID.dwGroupID1 == pEntry->GroupID.dwGroupID1) && + (pLoggedInEntry->GroupID.dwGroupID2 == pEntry->GroupID.dwGroupID2) && + (pLoggedInEntry->GroupID.dwGroupID3 == pEntry->GroupID.dwGroupID3) && + (pLoggedInEntry->GroupID.dwGroupID4 == pEntry->GroupID.dwGroupID4)) + { + SendDlgItemMessage(hwnd, + IDC_GROUPS, + LB_SETSEL, + (WPARAM)TRUE, + (LPARAM)item); + } + + pLoggedInEntry++; + } + + pEntry++; + } + + // get the agent caps + if (pLAC = LineGetAgentCaps(ghLineApp, + gdwDeviceID, + dwAddress)) + { + dwCount = 0; + // loop through all possbile agent states. if the agent state + // is selected in the agent caps, add that state to the list box + while (dwAgentStates[dwCount]) + { + if (dwAgentStates[dwCount] & pLAC->dwStates) + { + item = SendDlgItemMessage(hwnd, + IDC_STATE, + CB_ADDSTRING, + 0, + (LPARAM)lpszStates[dwCount]); + SendDlgItemMessage(hwnd, + IDC_STATE, + CB_SETITEMDATA, + (WPARAM)item, + (LPARAM)dwAgentStates[dwCount]); + + // if the state matches the current one from the agent status + // select it + if (pLAS->dwState == dwAgentStates[dwCount]) + { + SendDlgItemMessage(hwnd, + IDC_STATE, + CB_SETCURSEL, + (WPARAM)item, + 0); + } + } + + dwCount ++; + } + + dwCount = 0; + // now do the same for the next states + while (dwAgentStates[dwCount]) + { + if (dwAgentStates[dwCount] & pLAC->dwNextStates) + { + item = SendDlgItemMessage(hwnd, + IDC_NEXTSTATE, + CB_ADDSTRING, + 0, + (LPARAM)lpszStates[dwCount]); + SendDlgItemMessage(hwnd, + IDC_NEXTSTATE, + CB_SETITEMDATA, + (WPARAM)item, + dwAgentStates[dwCount]); + + if (pLAS->dwNextState == dwAgentStates[dwCount]) + { + SendDlgItemMessage(hwnd, + IDC_NEXTSTATE, + CB_SETCURSEL, + (WPARAM)item, + 0); + } + } + + dwCount++; + } + + GlobalFree(pLAC); + } + + // get the activity list + pLAA = LineGetAgentActivityList(ghLine, + gdwDeviceID, + dwAddress); + if (pLAA) + { + dwCount = pLAA->dwNumEntries; + pActivityEntry = (LPLINEAGENTACTIVITYENTRY)(((LPBYTE)pLAA) + pLAA->dwListOffset); + + // go through all the possible activities and add them to the list + while (dwCount) + { + item = SendDlgItemMessage(hwnd, + IDC_ACTIVITY, + CB_ADDSTRING, + 0, + (LPARAM)(LPTSTR)(((LPBYTE)pLAA) + pActivityEntry->dwNameOffset)); + + SendDlgItemMessage(hwnd, + IDC_ACTIVITY, + CB_SETITEMDATA, + (WPARAM)item, + (LPARAM)pActivityEntry->dwID); + + // if this is the current activity (from agent status) + // select it + if (pLAS->dwActivityID == pActivityEntry->dwID) + { + SendDlgItemMessage(hwnd, + IDC_ACTIVITY, + CB_SETCURSEL, + (WPARAM)item, + 0); + } + + dwCount--; + pActivityEntry++; + } + + GlobalFree(pLAA); + + } + +} + +////////////////////////////////////////////////////////////////////////////////////////////// +// +// BOOL SaveAgentStatus(HWND hwnd) +// +// Saves information from the status dialog +// +////////////////////////////////////////////////////////////////////////////////////////////// +BOOL SaveAgentStatus(HWND hwnd, + DWORD dwAddress) +{ + LPLINEAGENTGROUPENTRY pGroupEntry, pNewGroupEntry; + LPLINEAGENTGROUPLIST pNewLAG; + DWORD dwCount; + LPINT pItems; + DWORD item; + DWORD dwState, dwNextState, dwActivity; + + // get the number of groups selected in the group + // list box. each selected group is a group this + // agent will be logged into + dwCount = SendDlgItemMessage(hwnd, + IDC_GROUPS, + LB_GETSELCOUNT, + 0, + 0); + + // allocate an array to hold the selected item's indexes + pItems = (LPINT)GlobalAlloc(GPTR, sizeof(int) * dwCount); + + // get the item's indexes + SendDlgItemMessage(hwnd, + IDC_GROUPS, + LB_GETSELITEMS, + dwCount, + (LPARAM)pItems); + + // alloc a LINEAGENTGROUP array for groups + pNewLAG = (LPLINEAGENTGROUPLIST)GlobalAlloc(GPTR, + sizeof(LINEAGENTGROUPLIST) + + dwCount * sizeof(LINEAGENTGROUPENTRY)); + + // fill in sizes + pNewLAG->dwTotalSize = sizeof(LINEAGENTGROUPLIST) + dwCount * sizeof(LINEAGENTGROUPENTRY); + pNewLAG->dwUsedSize = pNewLAG->dwTotalSize; + pNewLAG->dwNeededSize = pNewLAG->dwTotalSize; + pNewLAG->dwListSize = sizeof(LINEAGENTGROUPENTRY) * dwCount; + pNewLAG->dwListOffset = sizeof(LINEAGENTGROUPLIST); + + // count + pNewLAG->dwNumEntries = dwCount; + + // get pointer to first entry in array + pNewGroupEntry = (LPLINEAGENTGROUPENTRY)(((LPBYTE)pNewLAG) + pNewLAG->dwListOffset); + // loop though all selected item + while (dwCount) + { + // get the item data associated with the item. this data + // is a group entry struct + pGroupEntry = (LPLINEAGENTGROUPENTRY)SendDlgItemMessage(hwnd, + IDC_GROUPS, + LB_GETITEMDATA, + (WPARAM)pItems[dwCount-1], + 0); + + // copy the GroupID to the new array + CopyMemory(&pNewGroupEntry->GroupID, + &pGroupEntry->GroupID, + sizeof(pGroupEntry->GroupID)); + + // these fields are not used + pNewGroupEntry->dwNameSize = 0; + pNewGroupEntry->dwNameOffset = 0; + + // next entry + pNewGroupEntry++; + + dwCount--; + } + + // now that we've created the AGENTGROUPLIST, set it + EnterCriticalSection(&csLineReply); + glResult = lineSetAgentGroup(ghLine, + dwAddress, + pNewLAG); + + if (glResult < 0) + { + LeaveCriticalSection(&csLineReply); + //error + } + else if (WaitForLineReply()) + { + //error + } + + GlobalFree(pNewLAG); + + // now get the current state + item = SendDlgItemMessage(hwnd, + IDC_STATE, + CB_GETCURSEL, + 0, + 0); + + // get item data. this is the state flag + dwState = SendDlgItemMessage(hwnd, + IDC_STATE, + CB_GETITEMDATA, + (WPARAM)item, + 0); + + // same for next state + item = SendDlgItemMessage(hwnd, + IDC_NEXTSTATE, + CB_GETCURSEL, + 0, + 0); + + dwNextState = SendDlgItemMessage(hwnd, + IDC_NEXTSTATE, + CB_GETITEMDATA, + (WPARAM)item, + 0); + + // set it + EnterCriticalSection(&csLineReply); + glResult = lineSetAgentState(ghLine, + dwAddress, + dwState, + dwNextState); + + if (glResult < 0) + { + LeaveCriticalSection(&csLineReply); + //error + } + else if (WaitForLineReply()) + { + //error + } + + // get the activity selected + item = SendDlgItemMessage(hwnd, + IDC_ACTIVITY, + CB_GETCURSEL, + 0, + 0); + + // get the item data. this is the activity ID + dwActivity = SendDlgItemMessage(hwnd, + IDC_ACTIVITY, + CB_GETITEMDATA, + (WPARAM)item, + 0); + + // set it + EnterCriticalSection(&csLineReply); + glResult = lineSetAgentActivity(ghLine, + dwAddress, + dwActivity); + + + + if (glResult < 0) + { + LeaveCriticalSection(&csLineReply); + //error + } + else if (WaitForLineReply()) + { + //error + } + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// LRESULT WaitForLineReply() +// +// waiting for a line reply. +// +// 2 issues: +// - using global variables for line reply information. only recommended +// in the most simple situations +// +// - using completion ports to demonstrate the completion port mechanism. +// since this app has ui, the wait loop has a message loop and a sleep()!! +// +/////////////////////////////////////////////////////////////////////////////// +LRESULT WaitForLineReply() +{ + MSG msg; + + gbReply = FALSE; + + LeaveCriticalSection(&csLineReply); + + while (!gbReply) + { + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + Sleep(5); + } + + return glResult; + +} + +/////////////////////////////////////////////////////////////////////////////////// +// +// LRESULT CALLBACK AgentStateDlgProc () +// +// Dialog proc for the agent status dialog +// +/////////////////////////////////////////////////////////////////////////////////// +LRESULT CALLBACK AgentStateDlgProc (HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + static DWORD dwAddress; + static LPLINEAGENTGROUPLIST pLAG; + + switch (uMsg) + { + case WM_INITDIALOG: + + dwAddress = (DWORD)lParam; + + InitAgentDlg(hwnd, + dwAddress, + &pLAG); + + SetFocus(GetDlgItem(hwnd, + IDC_GROUPS)); + return 1; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK) + { + SaveAgentStatus(hwnd, + dwAddress); + GlobalFree(pLAG); + EndDialog(hwnd, + 1); + return 1; + } + + if (LOWORD(wParam) == IDCANCEL) + { + GlobalFree(pLAG); + EndDialog(hwnd, + 1); + + return 1; + } + } + + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// **************TAPI WRAPPER FUNCTIONS************** +// +/////////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetAgentGroupList() +// +/////////////////////////////////////////////////////////////////////////////// +LINEAGENTGROUPLIST * LineGetAgentGroupList (HLINE hLine, + DWORD dwAddressID) +{ + LINEAGENTGROUPLIST * pLineAgentGroupList; + static DWORD dwMaxNeededSize = sizeof(LINEAGENTGROUPLIST); + + // Allocate an initial block of memory for the LINEAGENTGROUPLIST structure, + // which may or may not be big enough to hold all of the information. + // + pLineAgentGroupList = GlobalAlloc(GPTR, dwMaxNeededSize); + + while (TRUE) + { + BOOL bError = FALSE; + + + if (pLineAgentGroupList == NULL) + { + return NULL; + } + pLineAgentGroupList->dwTotalSize = dwMaxNeededSize; + + // Try (or retry) to get the LINEAGENTGROUPLIST information + // + EnterCriticalSection(&csLineReply); + glResult = lineGetAgentGroupList(hLine, + dwAddressID, + pLineAgentGroupList); + + if (glResult < 0) + { + LeaveCriticalSection(&csLineReply); + bError = TRUE; + //error + } + else if (WaitForLineReply()) + { + bError = TRUE; + //error + } + + + if (bError) + { + GlobalFree((HLOCAL)pLineAgentGroupList); + return NULL; + } + + // If the currently allocated LINEAGENTGROUPLIST memory block was big + // enough, we're all done, else we need to realloc the memory block + // and try again. + // + if (pLineAgentGroupList->dwNeededSize <= dwMaxNeededSize) + { + return pLineAgentGroupList; + } + else + { + dwMaxNeededSize = pLineAgentGroupList->dwNeededSize; + pLineAgentGroupList = GlobalReAlloc((HLOCAL)pLineAgentGroupList, + dwMaxNeededSize, + GMEM_MOVEABLE); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetAgentStatus() +// +/////////////////////////////////////////////////////////////////////////////// +LINEAGENTSTATUS * LineGetAgentStatus (HLINE hLine, + DWORD dwAddressID) +{ + LINEAGENTSTATUS * pLineAgentStatus; + static DWORD dwMaxNeededSize = sizeof(LINEAGENTSTATUS); + + // Allocate an initial block of memory for the LINEAGENTSTATUS structure, + // which may or may not be big enough to hold all of the information. + // + pLineAgentStatus = GlobalAlloc(GPTR, dwMaxNeededSize); + + while (TRUE) + { + BOOL bError = FALSE; + if (pLineAgentStatus == NULL) + { + return NULL; + } + pLineAgentStatus->dwTotalSize = dwMaxNeededSize; + + // Try (or retry) to get the LINEAGENTSTATUS information + // + EnterCriticalSection(&csLineReply); + glResult = lineGetAgentStatus(hLine, + dwAddressID, + pLineAgentStatus); + + if (glResult < 0) + { + LeaveCriticalSection(&csLineReply); + bError = TRUE; + //error + } + else if (WaitForLineReply()) + { + bError = TRUE; + //error + } + + if (bError) + { + GlobalFree((HLOCAL)pLineAgentStatus); + return NULL; + } + + // If the currently allocated LINEAGENTSTATUS memory block was big + // enough, we're all done, else we need to realloc the memory block + // and try again. + // + if (pLineAgentStatus->dwNeededSize <= dwMaxNeededSize) + { + return pLineAgentStatus; + } + else + { + dwMaxNeededSize = pLineAgentStatus->dwNeededSize; + pLineAgentStatus = GlobalReAlloc((HLOCAL)pLineAgentStatus, + dwMaxNeededSize, + GMEM_MOVEABLE); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetAgentCaps() +// +/////////////////////////////////////////////////////////////////////////////// +LINEAGENTCAPS * LineGetAgentCaps (HLINEAPP hLineApp, + DWORD dwDeviceID, + DWORD dwAddressID) +{ + LINEAGENTCAPS * pLineAgentCaps; + static DWORD dwMaxNeededSize = sizeof(LINEAGENTCAPS); + + // Allocate an initial block of memory for the LINEAGENTCAPS structure, + // which may or may not be big enough to hold all of the information. + // + pLineAgentCaps = GlobalAlloc(GPTR, dwMaxNeededSize); + + while (TRUE) + { + BOOL bError = FALSE; + + if (pLineAgentCaps == NULL) + { + return NULL; + } + pLineAgentCaps->dwTotalSize = dwMaxNeededSize; + + // Try (or retry) to get the LINEAGENTCAPS information + // + EnterCriticalSection(&csLineReply); + glResult = lineGetAgentCaps(hLineApp, + dwDeviceID, + dwAddressID, + TAPI_CURRENT_VERSION, + pLineAgentCaps); + + if (glResult < 0) + { + bError = TRUE; + LeaveCriticalSection(&csLineReply); + //error + } + else if (WaitForLineReply()) + { + bError = TRUE; + //error + } + + + if (bError) + { + GlobalFree((HLOCAL)pLineAgentCaps); + return NULL; + } + + // If the currently allocated LINEAGENTCAPS memory block was big + // enough, we're all done, else we need to realloc the memory block + // and try again. + // + if (pLineAgentCaps->dwNeededSize <= dwMaxNeededSize) + { + return pLineAgentCaps; + } + else + { + dwMaxNeededSize = pLineAgentCaps->dwNeededSize; + pLineAgentCaps = GlobalReAlloc((HLOCAL)pLineAgentCaps, + dwMaxNeededSize, + GMEM_MOVEABLE); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetAgentActivityList() +// +/////////////////////////////////////////////////////////////////////////////// +LPLINEAGENTACTIVITYLIST LineGetAgentActivityList (HLINE hLine, + DWORD dwDeviceID, + DWORD dwAddressID) +{ + LINEAGENTACTIVITYLIST * pLineAgentActivityList; + static DWORD dwMaxNeededSize = sizeof(LINEAGENTACTIVITYLIST); + + // Allocate an initial block of memory for the LINEAGENTACTIVITYLIST structure, + // which may or may not be big enough to hold all of the information. + // + pLineAgentActivityList = GlobalAlloc(GPTR, dwMaxNeededSize); + + for (;;) + { + BOOL bError = FALSE; + if (pLineAgentActivityList == NULL) + { + return NULL; + } + pLineAgentActivityList->dwTotalSize = dwMaxNeededSize; + + // Try (or retry) to get the LINEAGENTACTIVITYLIST information + // + EnterCriticalSection(&csLineReply); + glResult = lineGetAgentActivityList(hLine, + dwAddressID, + pLineAgentActivityList); + + if (glResult < 0) + { + LeaveCriticalSection(&csLineReply); + bError = TRUE; + //error + } + else if (WaitForLineReply()) + { + bError = TRUE; + //error + } + + + if (bError) + { + GlobalFree((HLOCAL)pLineAgentActivityList); + return NULL; + } + + + // If the currently allocated LINEAGENTACTIVITYLIST memory block was big + // enough, we're all done, else we need to realloc the memory block + // and try again. + // + if (pLineAgentActivityList->dwNeededSize <= dwMaxNeededSize) + { + return pLineAgentActivityList; + } + else + { + dwMaxNeededSize = pLineAgentActivityList->dwNeededSize; + pLineAgentActivityList = GlobalReAlloc((HLOCAL)pLineAgentActivityList, + dwMaxNeededSize, + GMEM_MOVEABLE); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetAddressCaps() +// +/////////////////////////////////////////////////////////////////////////////// +LINEADDRESSCAPS * LineGetAddressCaps (HLINEAPP hLineApp, + DWORD dwDeviceID, + DWORD dwAddressID) +{ + LONG lRetVal; + LINEADDRESSCAPS * pLineAddressCaps; + static DWORD dwMaxNeededSize = sizeof(LINEADDRESSCAPS); + + // Allocate an initial block of memory for the LINEADDRESSCAPS structure, + // which may or may not be big enough to hold all of the information. + // + pLineAddressCaps = GlobalAlloc(GPTR, dwMaxNeededSize); + + for (;;) + { + if (pLineAddressCaps == NULL) + { + return NULL; + } + pLineAddressCaps->dwTotalSize = dwMaxNeededSize; + + // Try (or retry) to get the LINEADDRESSCAPS information + // + lRetVal = lineGetAddressCaps(hLineApp, + dwDeviceID, + dwAddressID, + TAPI_CURRENT_VERSION, + 0, + pLineAddressCaps); + if (lRetVal < 0) + { + GlobalFree((HLOCAL)pLineAddressCaps); + return NULL; + } + + // If the currently allocated LINEADDRESSCAPS memory block was big + // enough, we're all done, else we need to realloc the memory block + // and try again. + // + if (pLineAddressCaps->dwNeededSize <= dwMaxNeededSize) + { + return pLineAddressCaps; + } + else + { + dwMaxNeededSize = pLineAddressCaps->dwNeededSize; + pLineAddressCaps = GlobalReAlloc((HLOCAL)pLineAddressCaps, + dwMaxNeededSize, + GMEM_MOVEABLE); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetCallInfo() +// +/////////////////////////////////////////////////////////////////////////////// +LINECALLINFO * LineGetCallInfo (HCALL hCall) +{ + LONG lRetVal; + LINECALLINFO * pLineCallInfo; + static DWORD dwMaxNeededSize = sizeof(LINECALLINFO); + + // Allocate an initial block of memory for the LINECALLINFO structure, + // which may or may not be big enough to hold all of the information. + // + pLineCallInfo = GlobalAlloc(GPTR, dwMaxNeededSize); + + for (;;) + { + if (pLineCallInfo == NULL) + { + return NULL; + } + pLineCallInfo->dwTotalSize = dwMaxNeededSize; + + // Try (or retry) to get the LINECALLINFO information + // + lRetVal = lineGetCallInfo(hCall, + pLineCallInfo); + if (lRetVal < 0) + { + GlobalFree((HLOCAL)pLineCallInfo); + return NULL; + } + + // If the currently allocated LINECALLINFO memory block was big + // enough, we're all done, else we need to realloc the memory block + // and try again. + // + if (pLineCallInfo->dwNeededSize <= dwMaxNeededSize) + { + return pLineCallInfo; + } + else + { + dwMaxNeededSize = pLineCallInfo->dwNeededSize; + pLineCallInfo = GlobalReAlloc((HLOCAL)pLineCallInfo, + dwMaxNeededSize, + GMEM_MOVEABLE); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetDevCaps() +// +/////////////////////////////////////////////////////////////////////////////// +LINEDEVCAPS * LineGetDevCaps (HLINEAPP hLineApp, + DWORD dwDeviceID) +{ + LONG lRetVal; + LINEDEVCAPS * pLineDevCaps; + static DWORD dwMaxNeededSize = sizeof(LINEDEVCAPS); + + pLineDevCaps = GlobalAlloc(GPTR, dwMaxNeededSize); + for (;;) + { + if (pLineDevCaps == NULL) + { + return NULL; + } + pLineDevCaps->dwTotalSize = dwMaxNeededSize; + lRetVal = lineGetDevCaps(hLineApp, + dwDeviceID, + TAPI_CURRENT_VERSION, + 0, + pLineDevCaps); + if (lRetVal < 0) + { + GlobalFree((HLOCAL)pLineDevCaps); + return NULL; + } + if (pLineDevCaps->dwNeededSize <= dwMaxNeededSize) + { + return pLineDevCaps; + } + else + { + dwMaxNeededSize = pLineDevCaps->dwNeededSize; + pLineDevCaps = GlobalReAlloc((HLOCAL)pLineDevCaps, + dwMaxNeededSize, + GMEM_MOVEABLE); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetID() +// +/////////////////////////////////////////////////////////////////////////////// +VARSTRING * LineGetID (HLINE hLine, + DWORD dwAddressID, + HCALL hCall, + DWORD dwSelect, + LPCTSTR lpszDeviceClass) +{ + LONG lRetVal; + VARSTRING * pVarString; + static DWORD dwMaxNeededSize = sizeof(VARSTRING); + + // Allocate an initial block of memory for the VARSTRING structure, + // which may or may not be big enough to hold all of the information. + // + pVarString = GlobalAlloc(GPTR, dwMaxNeededSize); + + for (;;) + { + if (pVarString == NULL) + { + return NULL; + } + pVarString->dwTotalSize = dwMaxNeededSize; + + // Try (or retry) to get the VARSTRING information + // + lRetVal = lineGetID(hLine, + dwAddressID, + hCall, + dwSelect, + pVarString, + lpszDeviceClass); + if (lRetVal < 0) + { + GlobalFree((HLOCAL)pVarString); + return NULL; + } + + // If the currently allocated VARSTRING memory block was big + // enough, we're all done, else we need to realloc the memory block + // and try again. + // + if (pVarString->dwNeededSize <= dwMaxNeededSize) + { + return pVarString; + } + else + { + dwMaxNeededSize = pVarString->dwNeededSize; + pVarString = GlobalReAlloc((HLOCAL)pVarString, + dwMaxNeededSize, + GMEM_MOVEABLE); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// LineGetCallStatus() +// +/////////////////////////////////////////////////////////////////////////////// +LINECALLSTATUS * LineGetCallStatus (HCALL hCall) +{ + LONG lRetVal; + LINECALLSTATUS * pLineCallStatus; + static DWORD dwMaxNeededSize = sizeof(LINECALLSTATUS); + + // Allocate an initial block of memory for the LINECALLSTATUS structure, + // which may or may not be big enough to hold all of the information. + // + pLineCallStatus = GlobalAlloc(GPTR, dwMaxNeededSize); + + while (TRUE) + { + if (pLineCallStatus == NULL) + { + return NULL; + } + pLineCallStatus->dwTotalSize = dwMaxNeededSize; + + // Try (or retry) to get the LINECALLSTATUS information + // + lRetVal = lineGetCallStatus(hCall, + pLineCallStatus); + if (lRetVal < 0) + { + GlobalFree((HLOCAL)pLineCallStatus); + return NULL; + } + + // If the currently allocated LINECALLSTATUS memory block was big + // enough, we're all done, else we need to realloc the memory block + // and try again. + // + if (pLineCallStatus->dwNeededSize <= dwMaxNeededSize) + { + return pLineCallStatus; + } + else + { + dwMaxNeededSize = pLineCallStatus->dwNeededSize; + pLineCallStatus = GlobalReAlloc((HLOCAL)pLineCallStatus, + dwMaxNeededSize, + GMEM_MOVEABLE); + } + } +} + +//////////////////////////////////////////////////////////////////////////// +// +// +// constants for creating buttons in the main window +// +#define YSTART 8 +#define XSTART 8 +#define STATICX 57 +#define BUTTONX 50 +#define BUTTONGAP 20 +#define BUTTONY 14 +#define LINEGAP 8 + + +///////////////////////////////////////////////////////////////////////////// +// +// BOOL RedoWindow() +// +// Creates the buttons and static controls in the main window +// For each address on the line, create a static control with the name off +// the address, a button to get/set status, and a button to answer/drop +// +// Right now, this should only be done when the app is starting. It does +// not check to see if pAddressInfo has already been allocated +// +///////////////////////////////////////////////////////////////////////////// +BOOL RedoWindow() +{ + DWORD dwAddress; + LPLINEADDRESSCAPS pLAC; + TCHAR szBuffer[64]; + LONG lBaseUnits, lxbase, lybase; + HFONT hFont; + HWND hWnd; + + int x,y,w,h,xstart,ystart,buttonx,buttony,staticx,buttongap,linegap; + + + // alloc for address info + pAddressInfo = (PADDRESSINFO)GlobalAlloc(GPTR, sizeof(ADDRESSINFO) * gdwAddresses); + + if (!pAddressInfo) + { + return FALSE; + } + + // get conversions + lBaseUnits = GetDialogBaseUnits(); + lxbase = (LONG)LOWORD(lBaseUnits); + lybase = (LONG)HIWORD(lBaseUnits); + + // convert dialog units to pixels + xstart = (XSTART * lxbase) / 4; + ystart = (YSTART * lybase) / 8; + buttonx = (BUTTONX * lxbase) / 4; + buttony = (BUTTONY * lybase) / 8; + staticx = (STATICX * lxbase) / 4; + buttongap = (BUTTONGAP * lxbase) / 4; + linegap = (LINEGAP * lybase) / 8; + + // init + x = xstart; + y = ystart; + w = buttonx; + h = buttony; + + // get the font used by the static control + hFont = (HFONT)SendDlgItemMessage(ghMainWnd, + IDC_STATIC1, + WM_GETFONT, + 0, + 0); + + // loop through all addressed + for (dwAddress = 0; dwAddress < gdwAddresses; dwAddress++) + { + // get the name of the address + pLAC = LineGetAddressCaps(ghLineApp, + gdwDeviceID, + dwAddress); + + if (!pLAC || !pLAC->dwAddressSize) + { + wsprintf(szBuffer, + TEXT("Address %lu"), + dwAddress); + } + else + { + lstrcpy(szBuffer, + (LPTSTR)(((LPBYTE)pLAC)+pLAC->dwAddressOffset)); + } + + if (pLAC) + { + GlobalFree(pLAC); + } + + w = staticx; + x = xstart; + // create the static control + hWnd = CreateWindow(TEXT("STATIC"), + szBuffer, + WS_CHILD | SS_LEFT | WS_VISIBLE, + x,y+(buttony/3),w,h, + ghMainWnd, + NULL, + ghInstance, + NULL); + + // set the font + SendMessage(hWnd, + WM_SETFONT, + (WPARAM)hFont, + 0); + + x += staticx; + w = buttonx; + // create the status button + pAddressInfo[dwAddress].hStatus = CreateWindow(TEXT("BUTTON"), + TEXT("Set Status..."), + WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, + x,y,w,h, + ghMainWnd, + NULL, + ghInstance, + NULL); + + // set the font + SendMessage(pAddressInfo[dwAddress].hStatus, + WM_SETFONT, + (WPARAM)hFont, + 0); + + x += buttonx + buttongap; + + // create the answer/drop button + pAddressInfo[dwAddress].hAnswer = CreateWindow(TEXT("BUTTON"), + TEXT("Answer"), + WS_CHILD | WS_DISABLED | BS_PUSHBUTTON | WS_VISIBLE, + x,y,w,h, + ghMainWnd, + NULL, + ghInstance, + NULL); + + // set the font + SendMessage(pAddressInfo[dwAddress].hAnswer, + WM_SETFONT, + (WPARAM)hFont, + 0); + + y += buttony + linegap; + } + + + // adjust position of message static control + SetWindowPos(GetDlgItem(ghMainWnd, + IDC_STATIC1), + NULL, + xstart,y,0,0, + SWP_NOZORDER | SWP_NOSIZE); + + // adjust the size of th main window + SetWindowPos(ghMainWnd, + NULL, + 0,0,xstart+staticx+buttonx+buttonx+buttongap+50,y+50, + SWP_NOZORDER | SWP_NOMOVE); + + return TRUE; + +} diff --git a/private/tapi/dev/apps/acdclnt/acdclnt.h b/private/tapi/dev/apps/acdclnt/acdclnt.h new file mode 100644 index 000000000..122fc0cc4 --- /dev/null +++ b/private/tapi/dev/apps/acdclnt/acdclnt.h @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////////////////////// +// +// ACDCLNT.H +// +///////////////////////////////////////////////////////////////////////// +#include <windows.h> +#include <tapi.h> + +#define SZAPPNAME TEXT("ACDClient") + +typedef struct _tagADDRESSINFO +{ + HWND hStatus; + HWND hAnswer; + HCALL hCall; + BOOL bCall; + +} ADDRESSINFO, * PADDRESSINFO; + + +LINEAGENTGROUPLIST * LineGetAgentGroupList (HLINE hLine, + DWORD dwAddressID); + +LINEAGENTSTATUS * LineGetAgentStatus (HLINE hLine, + DWORD dwAddressID); + +LINEAGENTCAPS * LineGetAgentCaps (HLINEAPP hLineApp, + DWORD dwDeviceID, + DWORD dwAddressID); + +LPLINEAGENTACTIVITYLIST LineGetAgentActivityList (HLINE hLine, + DWORD dwDeviceID, + DWORD dwAddressID); + +LINEADDRESSCAPS * LineGetAddressCaps (HLINEAPP hLineApp, + DWORD dwDeviceID, + DWORD dwAddressID); + +LINECALLINFO * LineGetCallInfo (HCALL hCall); + +LINEDEVCAPS * LineGetDevCaps (HLINEAPP hLineApp, + DWORD dwDeviceID); + +VARSTRING * LineGetID (HLINE hLine, + DWORD dwAddressID, + HCALL hCall, + DWORD dwSelect, + LPCTSTR lpszDeviceClass); + +LINECALLSTATUS * LineGetCallStatus (HCALL hCall); + diff --git a/private/tapi/dev/apps/acdclnt/acdclnt.rc b/private/tapi/dev/apps/acdclnt/acdclnt.rc new file mode 100644 index 000000000..fd4243e41 --- /dev/null +++ b/private/tapi/dev/apps/acdclnt/acdclnt.rc @@ -0,0 +1,95 @@ +#include <windows.h> +#include "resource.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_MAINDLG DIALOGEX 0, 0, 204, 46 +STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | + WS_SYSMENU | WS_THICKFRAME | WS_SYSMENU +EXSTYLE WS_EX_CLIENTEDGE +CAPTION "ACD Client" +FONT 8, "MS Sans Serif" +BEGIN +// LTEXT "Address 1",IDC_STATIC1,7,9,55,8 +// PUSHBUTTON "Answer",IDC_ANSWER1,147,7,50,14,WS_DISABLED +// PUSHBUTTON "Set Status...",IDC_STATUS1,64,7,50,14 + LTEXT "Incoming call on Address 1",IDC_STATIC1,7,31,190,8 +END + +IDD_AGENTSTATE DIALOG DISCARDABLE 0, 0, 278, 161 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Agent State" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,49,140,50,14 + PUSHBUTTON "Cancel",IDCANCEL,150,140,50,14 + LTEXT "State",IDC_STATIC,153,7,18,8 + COMBOBOX IDC_STATE,152,17,119,61,CBS_DROPDOWN | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + LTEXT "Groups",IDC_STATIC,7,7,24,8 + LISTBOX IDC_GROUPS,7,17,119,116,LBS_SORT | LBS_MULTIPLESEL | + LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | + WS_TABSTOP + COMBOBOX IDC_ACTIVITY,152,95,119,53,CBS_DROPDOWN | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + LTEXT "Activity",IDC_STATIC,153,83,24,8 + COMBOBOX IDC_NEXTSTATE,152,56,119,59,CBS_DROPDOWN | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + LTEXT "Next State",IDC_STATIC,153,45,34,8 +END + + +//////////////////////////////////////////////////////////////////// +// +// Version Info +// + +//#if WINNT +//#include <ntverp.h> +//#else +//#include <version.h> +//#endif +#include <winver.h> + + +#ifdef RC_INVOKED + +VS_VERSION_INFO VERSIONINFO +FILEVERSION 4,00,01,001 +PRODUCTVERSION 4,00,01,001 +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +FILEFLAGS (VS_FF_PRERELEASE|VS_FF_DEBUG) +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +FILESUBTYPE VFT2_UNKNOWN + +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */ + BEGIN + VALUE "CompanyName", "Microsoft Corporation\0" + VALUE "FileDescription", "TAPI ACD Client Sample Application\0" + VALUE "FileVersion", "1.0\0" + VALUE "InternalName", "ACDCLNT\0" + VALUE "LegalCopyright", "Copyright (C) Microsoft Corp. 1996\0" + VALUE "LegalTrademarks", "Microsoft(R) is a registered trademark of Microsoft Corporation. Windows(TM) is a trademark of Microsoft Corporation\0" + VALUE "ProductName", "ACDClient\0" + VALUE "ProductVersion", "1.0\0" + + END + + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04B0 + END +END + +#endif + + diff --git a/private/tapi/dev/apps/acdclnt/makefile b/private/tapi/dev/apps/acdclnt/makefile new file mode 100644 index 000000000..f1084966b --- /dev/null +++ b/private/tapi/dev/apps/acdclnt/makefile @@ -0,0 +1,29 @@ +!if "$(OS)" == "Windows_NT" + +!INCLUDE $(NTMAKEENV)\makefile.def + +!else + +############################################################################## +# +# Dialer.exe Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\.. + +VERSIONLIST=debug retail + +DEPENDNAME=depend.mk + +COMMONMKFILE=makefile.def + +IS_OEM=TRUE +IS_32 = TRUE + +!include $(ROOT)\dev\master.mk + +!endif + diff --git a/private/tapi/dev/apps/acdclnt/makefile.sdk b/private/tapi/dev/apps/acdclnt/makefile.sdk new file mode 100644 index 000000000..f58046d2c --- /dev/null +++ b/private/tapi/dev/apps/acdclnt/makefile.sdk @@ -0,0 +1,33 @@ +# Define NODEBUG to build ACDSMPL without debugging information. +# Define UNICODE to build ACDSMPL with UNICODE characters. + +TARGETOS=WINNT + +!include <ntwin32.mak> + +!ifdef UNICODE +unicode = -DUNICODE +!else +unicode = +!endif + +cflags=$(cflags) -DWIN32_LEAN_AND_MEAN + +all: acdclnt.exe + +# Update the resource if necessary + +acdclnt.res: acdclnt.rc resource.h + $(rc) $(rcvars) -r acdclnt.rc + +# Update the object files if necessary + +acdclnt.obj: acdclnt.c resource.h acdclnt.h + $(cc) $(cdebug) $(cflags) $(cvars) $(unicode) acdclnt.c + +# Update the executable file if necessary, and if so, add the resource back in. + +acdclnt.exe: acdclnt.obj acdclnt.res makefile.sdk + $(link) $(linkdebug) $(guiflags) -out:acdclnt.exe\ + acdclnt.obj acdclnt.res\ + version.lib tapi32.lib comctl32.lib $(guilibsmt) diff --git a/private/tapi/dev/apps/acdclnt/resource.h b/private/tapi/dev/apps/acdclnt/resource.h new file mode 100644 index 000000000..cf8f61dcd --- /dev/null +++ b/private/tapi/dev/apps/acdclnt/resource.h @@ -0,0 +1,22 @@ +// +#define IDD_MAINDLG 101 +#define IDD_AGENTSTATE 102 +#define IDC_ANSWER1 1012 +#define IDC_STATUS1 1016 +#define IDC_STATE 1018 +#define IDC_GROUPS 1019 +#define IDC_ACTIVITY 1020 +#define IDC_NEXTSTATE 1021 +#define IDC_STATIC1 1022 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1022 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/private/tapi/dev/apps/acdclnt/sources b/private/tapi/dev/apps/acdclnt/sources new file mode 100644 index 000000000..1c1963210 --- /dev/null +++ b/private/tapi/dev/apps/acdclnt/sources @@ -0,0 +1,58 @@ +!IF 0 + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + +Author: + + John Rogers (JohnRo) 25-Oct-1991 + +Notes: + + Commented description of this file is in \nt\public\oak\bin\sources.tpl + +Revision History: + +!ENDIF + + +MAJORCOMP=net +MINORCOMP=tapi + +TARGETNAME=acdclnt +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=PROGRAM + +TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\comdlg32.lib \ + $(BASEDIR)\public\sdk\lib\*\shell32.lib \ + $(BASEDIR)\public\sdk\lib\*\tapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\comctl32.lib + +INCLUDES=.;$(BASEDIR)\public\sdk\inc + +USE_CRTDLL=1 + +SOURCES=acdclnt.c \ + acdclnt.rc + +#C_DEFINES=-DWINVER=0x0400 -DUNICODE +C_DEFINES=-DWINVER=0x0400 + +UMTYPE=windows + +UMENTRY=winmain + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF diff --git a/private/tapi/dev/apps/dialer/depend.mk b/private/tapi/dev/apps/dialer/depend.mk new file mode 100644 index 000000000..506be7029 --- /dev/null +++ b/private/tapi/dev/apps/dialer/depend.mk @@ -0,0 +1,4 @@ +.\dialer.obj: ..\dialer.c ..\dialer.h ..\dialhelp.h ..\resource.h + +.\dialer.res: ..\dialer.rc ..\version.rc ..\resource.h + diff --git a/private/tapi/dev/apps/dialer/dialer.c b/private/tapi/dev/apps/dialer/dialer.c new file mode 100644 index 000000000..a517a9a89 --- /dev/null +++ b/private/tapi/dev/apps/dialer/dialer.c @@ -0,0 +1,4345 @@ +/*++ + +Copyright (c) 1996 Microsoft Corporation + +Module Name: + + dialer.c + +--*/ + + +#include "dialer.h" +#include "string.h" +#include "stdlib.h" +#include "shellapi.h" + + +#define ISDIGIT(x) (((x) - '0') >= 0) && (((x) - '0') <= 9) +enum NumberTypes +{ + LOCAL_NUMBER = 7, + EXTENDED_LOCAL_NUMBER, + LONG_DISTANCE_NUMBER = 10, + EXTENDED_LONG_DISTANCE_NUMBER +}; + + +// structs +typedef struct tagLINEINFO +{ + DWORD nAddr; // Number of avail. addresses on the line + BOOL fVoiceLine; // Is this a voice line? + DWORD dwAPIVersion; // API version which the line supports + HLINE hLine; // line handle returned by lineOpen + DWORD dwPermanentLineID; // Permanent line ID retreived from devcaps + char szLineName[MAXBUFSIZE]; // the line's name + +} LINEINFO, *LPLINEINFO; + + +// Global variables + +// window/instance variables +HWND ghWndMain; +HWND ghWndDialing = NULL; +HINSTANCE ghInst = 0; + +// file name vars. +static TCHAR gszAppName[64]; +static TCHAR gszINIfilename [] = "DIALER.INI"; +static TCHAR gszHELPfilename [] = "DIALER.HLP"; +static TCHAR gszDialerClassName[] = "DialerClass"; +TCHAR const gszNULL[] = ""; + +// window item variables +HFONT ghFontBtn; // handle to 1, 2, ..., 0's font +HFONT ghFontBtnText; // handle to number button's text font +HFONT ghFontBtnStar; // handle to * and # button's font +HLINEAPP ghLineApp = NULL; // Dialer's usage handle (regist. w/TAPI) +HCALL ghCall = NULL; // call handle for Dialer's call + +LPSTR gszCurrentNumber = NULL; // number of destination of current call +LPSTR gszCurrentName = NULL; // name of destination of current call + +BOOL gfRegistered; // was lineRegisterRequestRecipient() + // successful? + +//BOOL gfDropping = FALSE; // is Dialer currently dropping a call? +BOOL gfNeedToReinit = FALSE; // does Dialer need to re-initialize? + +BOOL gfCallRequest = FALSE; // Does a Simple TAPI app want a call? +BOOL gfCurrentLineAvail = TRUE; // Simple TAPI requests are only carried + // out if the current chosen line is avail. +BOOL gfMakeCallReplyPending = FALSE; + +LONG gMakeCallRequestID = 0; // request ID returned by async TAPI fns. +LONG gDropCallRequestID = 0; // request ID returned by async TAPI fns. + +DWORD gnAvailDevices = 0; // # of line devices avail. to Dialer +LINEINFO gCurrentLineInfo; +DWORD * gnAddr; + +// global to remember where the cursor is in the edit control +DWORD gdwStartSel; +DWORD gdwEndSel; + +DWORD * gdwPLID; // current line's permanent line ID +DWORD giCurrentLine = (DWORD)-1; // the line selected by the user +DWORD giCurrentAddress = 0; // the address selected by the user + +// + 1 so we can work 1-based rather than 0-based (for convenience only) +// global varibles to hold the names and address of the +TCHAR gszSDNumber[ NSPEEDDIALS + 1 ][ TAPIMAXDESTADDRESSSIZE ]; + + +// Function declarations + +// button related functions +VOID ButtonFontSetup(VOID); +VOID DrawButton(HDC hdc, RECT rcBtn, BOOL fHighlighted); +VOID DrawButtonText(HDC hdc, RECT rcBtn, BOOL fHighlighted, UINT IDD_Btn); +VOID DisableDialButtons(BOOL fDisable); +VOID FitTextToButton( HWND, INT, LPSTR ); + +// Callback functions +BOOL CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK DialingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK AboutProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK ConnectUsingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK LineInUseProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK SpeedDial1Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK SpeedDial2Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +VOID CALLBACK tapiCallback ( + DWORD hDevice, DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, DWORD dwParam2, + DWORD dwParam3 + ); + +// tapi related functions +VOID ManageAssistedTelephony(VOID); +VOID InitiateCall(LPCSTR szNumber, LPCSTR szName); + +VOID DialerLineClose(VOID); +VOID DialerCleanup(VOID); +VOID CloseTAPI(VOID); + +DWORD GetLineInfo(DWORD iLine, LPLINEINFO lpLineInfo); +VOID GetLineInfoFailed ( + DWORD iLine, LPLINEDEVCAPS lpDevCaps, + LPLINEINFO lpLineInfo + ); +LPSTR GetAddressName(DWORD iLine, DWORD iAddress); +BOOL MakeCanonicalNumber( LPCSTR szName, LPSTR szCanNumber ); + +// misc. helper functions +VOID ReadINI(VOID); +int errString(HWND hWnd, UINT errCode, UINT uFlags); +VOID AddToRedialList(LPCSTR szNumber); +BOOL InitializeLineBox(HWND hwndLineBox); +BOOL InitializeAddressBox(HWND hwndLineBox, HWND hwndAddressBox); +BOOL Is911 ( LPLINETRANSLATEOUTPUT lpTransOut ); +VOID AmpersandCompensate( LPCSTR lpszSrc, LPSTR lpszDst ); +VOID AmpersandDeCompensate( LPCSTR lpszSrc, LPSTR lpszDst ); + +// Dialer memory management functions +LPVOID DialerAlloc(size_t cbToAlloc); +LPVOID DialerFree(LPVOID lpMem); + + +// Function definitions + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +DWORD InitializeTAPI (VOID) +{ + INT cvLine; + + DWORD iLine; + DWORD dwPreferredPLID, dwID = (DWORD) -1; + + MSG msg; + + LPLINEINFO lpLineInfo = NULL; // LINEINFO for each available line + + DWORD errCode; + DWORD tc = GetTickCount(); + DWORD dwReturn = ERR_NONE; + + char szBuffer[MAXBUFSIZE]; // to read in dwPreferredPLID as a string first + + + + errCode = lineInitialize ( + &ghLineApp, + ghInst, + (LINECALLBACK) tapiCallback, + gszAppName, + &gnAvailDevices + ); + if ( errCode == LINEERR_REINIT ) + { + // take away dialer functionality + EnableWindow( ghWndMain, FALSE ); + DisableDialButtons(TRUE); + + // keep trying until the user cancels + // or we stop getting LINEERR_REINIT + while ( ( errCode = lineInitialize ( + &ghLineApp, + ghInst, + (LINECALLBACK)tapiCallback, + gszAppName, + &gnAvailDevices + ) ) + == LINEERR_REINIT ) + { + // flush queue & yield + while ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + + // bring up the box if 5 seconds have passed since + if(GetTickCount() > 5000 + tc) + { + if ( errString( ghWndMain, ikszWarningTapiReInit, MB_RETRYCANCEL ) + == IDCANCEL ) + { + break; + } + // reset the relative counter + tc = GetTickCount(); + } + } + + // give back dialer functionality + DisableDialButtons( FALSE ); + EnableWindow( ghWndMain, TRUE ); + } + + if ( errCode ) + { + dwReturn = errCode; + goto tapiinit_exit; + } + + // retrieve preferred line info from INI file + GetPrivateProfileString ( + "Preference", + "Preferred Line", + gszNULL, + szBuffer, + MAXBUFSIZE, + gszINIfilename + ); + + // if szBuffer is not empty. + if ( lstrcmp ( gszNULL, szBuffer ) ) + { + dwPreferredPLID = (DWORD) atoi( szBuffer ); + } + else + { + dwPreferredPLID = (DWORD) -1; + } + + // -1 default - tells us if it ever gets set + giCurrentLine = (DWORD) -1; + + // allocate buffer for storing LINEINFO for all of the available lines + // always allocate space for at least one line + if ( gnAvailDevices == 0 ) + { + gnAddr = (DWORD *) DialerAlloc( sizeof( DWORD ) ); + gdwPLID = (DWORD *) DialerAlloc( sizeof( DWORD ) ); + lpLineInfo = (LPLINEINFO) DialerAlloc( sizeof( LINEINFO ) ); + } + else + { + gnAddr = (DWORD *) DialerAlloc( sizeof( DWORD ) * (int)gnAvailDevices); + gdwPLID = (DWORD *) DialerAlloc( sizeof( DWORD ) * (int)gnAvailDevices); + lpLineInfo = (LPLINEINFO) DialerAlloc( sizeof( LINEINFO ) * (int)gnAvailDevices ); + } + + // if no space was set aside... + if ( lpLineInfo == NULL || gnAddr == NULL ) + { + dwReturn = LINEERR_NOMEM; + goto tapiinit_exit; + } + + // fill lpLineInfo[] and open each line + for ( iLine = 0, cvLine = 0; iLine < gnAvailDevices; ++iLine ) + { + // skip remaining processing for this if it didn't open + if ( GetLineInfo( iLine, &lpLineInfo[iLine] ) != ERR_NONE ) + continue; + + gnAddr [ iLine ] = lpLineInfo[iLine].nAddr; + gdwPLID[ iLine ] = lpLineInfo[iLine].dwPermanentLineID; + + if ( lpLineInfo[iLine].dwPermanentLineID == dwPreferredPLID ) + giCurrentLine = iLine; + + // note number of lines with Interactive voice caps. + // used to select a preferred line by default + if ( lpLineInfo [ iLine ].fVoiceLine ) + { + cvLine++; + dwID = iLine; + } + } + + // if we couldn't find the preferred line, + // try and assign one by default + // else bring up connect using dialog + if ( giCurrentLine == (DWORD)-1 ) + { + // check if there is only one line + // that has interactive voice caps, + // make it default line + if ( cvLine == 1 ) + { + giCurrentLine = dwID; + + // if the preferred address read from the INI file + // was different i.e we are changing setting, inform + // the user + if ( dwPreferredPLID != -1 ) + { + errString( ghWndMain, ERR_NEWDEFAULT, MB_ICONEXCLAMATION | MB_OK ); + } + } + else + { + gCurrentLineInfo = lpLineInfo[0]; + if ( DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CONNECTUSING), + ghWndMain, + (DLGPROC)ConnectUsingProc, + INVALID_LINE + ) + == -1) + { + dwReturn = (DWORD) -1; + } + else + { + dwReturn = ERR_NONE; + } + + goto tapiinit_exit; + } + } + gCurrentLineInfo = lpLineInfo[ giCurrentLine ]; + + + // select default address + giCurrentAddress = 0; + + // get the name of the preferred address from ini file + GetPrivateProfileString ( + "Preference", + "Preferred Address", + gszNULL, + szBuffer, + MAXBUFSIZE, + gszINIfilename + ); + + // if preferred address read from INI file + if ( lstrcmp( gszNULL, szBuffer ) ) + { + giCurrentAddress = (DWORD) atoi( szBuffer ); + + // if the address is invalid, set default + if ( giCurrentAddress >= gCurrentLineInfo.nAddr ) + giCurrentAddress = 0; + } + + +tapiinit_exit: + + if (lpLineInfo) + { + DialerFree(lpLineInfo); + } + + return dwReturn;; +} + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +int WINAPI WinMain ( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow + ) +{ + HACCEL hAccel; + MSG msg; + DWORD errCode; + HANDLE hImHere; + + + ghInst = GetModuleHandle( NULL ); + LoadString( ghInst, ikszAppFriendlyName, gszAppName, sizeof(gszAppName)/sizeof(TCHAR) ); + + // + // Now, let's see if we've already got an instance of ourself + hImHere = CreateMutex(NULL, TRUE, "DialersIveBeenStartedMutex"); + + // + // Is there another one of us already here? + if ( ERROR_ALREADY_EXISTS == GetLastError() ) + { + HWND hDialerWnd; + + hDialerWnd = FindWindow(gszDialerClassName, + NULL); + + SetForegroundWindow(hDialerWnd); + + CloseHandle( hImHere ); + return 0; + } + + + { + WNDCLASS wc; + wc.style = CS_DBLCLKS | CS_SAVEBITS | CS_BYTEALIGNWINDOW; + wc.lpfnWndProc = DefDlgProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = DLGWINDOWEXTRA; + wc.hInstance = ghInst; + wc.hIcon = LoadIcon(ghInst, MAKEINTRESOURCE(IDI_DIALER) ); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = GetStockObject (COLOR_WINDOW + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = gszDialerClassName; + RegisterClass(&wc); + } + + + // create the dialog box and set it with info + // from the .INI file + ghWndMain = CreateDialog ( + ghInst, + (LPCSTR)MAKEINTRESOURCE(IDD_DIALER), + (HWND)NULL, + MainWndProc + ); + + ReadINI(); + ButtonFontSetup(); + + ShowWindow(ghWndMain, SW_SHOW); + UpdateWindow(ghWndMain); + + // limit text in Number field to TAPIMAXDESTADDRESSSIZE + SendDlgItemMessage ( + ghWndMain, + IDD_DCOMBO, + CB_LIMITTEXT, + (WPARAM)TAPIMAXDESTADDRESSSIZE, + 0 + ); + + // 0 (ERR_NONE) error code registers success - otherwise terminate + errCode = InitializeTAPI(); + if(errCode) + { + errString(ghWndMain, errCode, MB_APPLMODAL | MB_ICONEXCLAMATION ); + + DialerCleanup(); + return errCode; + } + + errCode = lineRegisterRequestRecipient ( + ghLineApp, + 0, // registration instance + LINEREQUESTMODE_MAKECALL, + TRUE + ); + + if(errCode) + { + gfRegistered = FALSE; + errString(ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK ); + } + else + { + gfRegistered = TRUE; + } + + + hAccel = LoadAccelerators(ghInst, gszAppName); + + while ( GetMessage( &msg, NULL, 0, 0 ) ) + { + if ( ghWndMain == NULL || !IsDialogMessage( ghWndMain, &msg ) ) + { + if(!TranslateAccelerator(ghWndMain, hAccel, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + // If: 1) Dialer is a call manager (if not, ignore requests) + // 2) the currently chosen line is available + // 3) there is a Simple TAPI request + // Then: process the request + if ( gfCurrentLineAvail && gfCallRequest ) + { + ManageAssistedTelephony(); + } + } + + + + DialerCleanup(); + + CloseHandle( hImHere ); + + return msg.wParam; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +LPVOID DialerAlloc(size_t cbToAlloc) +{ + return LocalAlloc(LPTR, cbToAlloc); +} + + +LPVOID DialerFree(LPVOID lpMem) +{ + return LocalFree( lpMem ); +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID ReadINI( VOID ) +{ + WORD cSDEntry, cLastDialed; + DWORD cComma; + + POINT ptLeftTop; + + char szName[ TAPIMAXCALLEDPARTYSIZE ]; + char szTemp[ TAPIMAXCALLEDPARTYSIZE ]; + + char szNum[MAXBUFSIZE]; + char szFieldName[MAXBUFSIZE]; + char szPt[MAXBUFSIZE]; + + + // get speed dial settings from INI file + for(cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry) + { + + wsprintf(szFieldName, "Name%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + szName, + TAPIMAXCALLEDPARTYSIZE - 1, + gszINIfilename + ); + + wsprintf(szFieldName, "Number%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + gszSDNumber[cSDEntry], + TAPIMAXDESTADDRESSSIZE - 1, + gszINIfilename + ); + + if ( !lstrcmp( gszNULL, szName ) ) + { + lstrcpy( szName, gszSDNumber[ cSDEntry ] ); + } + + FitTextToButton( ghWndMain, IDD_DSPEEDDIAL1 + cSDEntry - 1, szName ); + + AmpersandCompensate( szName, szTemp ); + SetDlgItemText ( + ghWndMain, + IDD_DSPEEDDIAL1 + cSDEntry - 1, + (LPCSTR)szTemp + ); // Label the speed dial button + } + + + // set up last dialed numbers in combo box (read from INI) + for(cLastDialed = 1; cLastDialed <= NLASTDIALED; ++cLastDialed) + { + wsprintf(szFieldName, "Last dialed %d", cLastDialed); + GetPrivateProfileString ( + "Last dialed numbers", + szFieldName, + gszNULL, + szNum, + MAXBUFSIZE - 1, + gszINIfilename + ); + if ( szNum[0] ) // i.e. if szNum isn't simply "" - if we read something + // from the INI - put it in the combo box + SendDlgItemMessage( + ghWndMain, + IDD_DCOMBO, + CB_ADDSTRING, + 0, + (LPARAM)(LPCSTR)szNum + ); + } + + // set defaults + ptLeftTop.x = 100; + ptLeftTop.y = 100; + + // set the window position based on the INI data + GetPrivateProfileString ( + "Preference", + "Main Window Left/Top", + gszNULL, + szPt, + MAXBUFSIZE - 1, + gszINIfilename + ); + + if ( szPt[0] ) + { + cComma = strcspn(szPt, ","); + szPt[cComma] = 0; + ptLeftTop.x = atoi(szPt); + + // a possibly absurd check to see that the string + // wasn't akin to "320," with no second entry + if ( *(szPt + cComma + 1 ) ) + ptLeftTop.y = atoi( szPt + cComma + 1 ); + + // check to see that the box is on the screen - the upper left + // must be on the screen, along with a 50x50 box below and to + // the right of it + if ( ptLeftTop.x < 0 + || ptLeftTop.x + 50 >= GetSystemMetrics(SM_CXSCREEN) + || ptLeftTop.y < 0 + || ptLeftTop.y + 50 >= GetSystemMetrics(SM_CYSCREEN) + ) + { + ptLeftTop.x = 100; // set defaults if the box is off of the screen + ptLeftTop.y = 100; // set defaults if the box is off of the screen + } + } + + SetWindowPos ( + ghWndMain, + NULL, + ptLeftTop.x, + ptLeftTop.y, + 0, + 0, + SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOZORDER + ); +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID ButtonFontSetup(VOID) + { + HDC hdc; + int IDD; + + // define the fonts for the buttons + hdc = GetDC(GetDesktopWindow()); + + ghFontBtn = CreateFont( + (-10)*GetDeviceCaps(hdc, LOGPIXELSY)/72, + 0, + 0, + 0, + FW_BOLD, + FALSE, + FALSE, + FALSE, + ANSI_CHARSET, + OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, + PROOF_QUALITY, + VARIABLE_PITCH | FF_SWISS, + (LPSTR)"Arial" + ); + + ghFontBtnText = CreateFont( + (-6)*GetDeviceCaps(hdc, LOGPIXELSY)/72, + 0, + 0, + 0, + FW_NORMAL, + FALSE, + FALSE, + FALSE, + ANSI_CHARSET, + OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, + PROOF_QUALITY, + VARIABLE_PITCH | FF_SWISS, + NULL + ); + + ghFontBtnStar = CreateFont( + (-18)*GetDeviceCaps(hdc, LOGPIXELSY)/72, + 0, + 0, + 0, + FW_BOLD, + FALSE, + FALSE, + FALSE, + SYMBOL_CHARSET, + OUT_TT_PRECIS, + CLIP_DEFAULT_PRECIS, + PROOF_QUALITY, + VARIABLE_PITCH | FF_DONTCARE, + (LPSTR)"Symbol" + ); + + ReleaseDC(GetDesktopWindow(), hdc); + + + // set the fonts for the buttons + if(ghFontBtn) + { + // set fonts on number buttons + for(IDD = IDD_DBUTTON1; IDD <= IDD_DBUTTON0; ++IDD) + // the order is IDD_DBUTTON1, 2, 3, ..., 0 (thus from 1 to 0) + SendMessage( + GetDlgItem(ghWndMain, IDD), + WM_SETFONT, + (WPARAM)ghFontBtn, + 0L + ); + + // set fonts on * and # buttons + SendMessage( + GetDlgItem(ghWndMain, IDD_DBUTTONSTAR), + WM_SETFONT, + (WPARAM)ghFontBtnStar, + 0L + ); + SendMessage( + GetDlgItem(ghWndMain, IDD_DBUTTONPOUND), + WM_SETFONT, + (WPARAM)ghFontBtnStar, + 0L + ); + } + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +// Draws a 3D button within rcBtn on hDC +VOID DrawButton(HDC hDC, RECT rcBtn, BOOL fHighlighted) + { + HPEN hPenPrev, hPenShadow, hPenHighlight, hPenBlack; + HBRUSH hBrushPrev, hBrushFace; + int RopPrev; + + --rcBtn.right; + --rcBtn.bottom; + + // set up pens/brush + hPenShadow = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DSHADOW)); + hPenHighlight = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DHILIGHT)); + hPenBlack = GetStockObject(BLACK_PEN); + hBrushFace = GetSysColorBrush(COLOR_3DFACE); + + // get current state so we can put it back at the end of DrawButton + hPenPrev = SelectObject(hDC, hPenBlack); + RopPrev = SetROP2(hDC, R2_COPYPEN); + hBrushPrev = SelectObject(hDC, hBrushFace); + + PatBlt( + hDC, + rcBtn.left + 1, + rcBtn.top + 1, + rcBtn.right - rcBtn.left - 1, + rcBtn.bottom - rcBtn.top - 1, + PATCOPY + ); + + if(fHighlighted) + { + SelectObject(hDC, hPenBlack); + MoveToEx(hDC, rcBtn.left, rcBtn.bottom - 1, NULL); + LineTo(hDC, rcBtn.left, rcBtn.top); // _ + LineTo(hDC, rcBtn.right, rcBtn.top); // | + + SelectObject(hDC, hPenHighlight); + MoveToEx(hDC, rcBtn.right, rcBtn.top, NULL); + LineTo(hDC, rcBtn.right, rcBtn.bottom); + LineTo(hDC, rcBtn.left - 1, rcBtn.bottom); // _| + + SelectObject(hDC, hPenShadow); + MoveToEx(hDC, rcBtn.left + 1, rcBtn.bottom - 2, NULL); + LineTo(hDC, rcBtn.left + 1, rcBtn.top + 1); + LineTo(hDC, rcBtn.right - 1, rcBtn.top + 1); + } + else + { + SelectObject(hDC, hPenHighlight); + MoveToEx(hDC, rcBtn.left, rcBtn.bottom - 1, NULL); + LineTo(hDC, rcBtn.left, rcBtn.top); // _ + LineTo(hDC, rcBtn.right, rcBtn.top); // | + + SelectObject(hDC, hPenBlack); + MoveToEx(hDC, rcBtn.right, rcBtn.top, NULL); + LineTo(hDC, rcBtn.right, rcBtn.bottom); + LineTo(hDC, rcBtn.left - 1, rcBtn.bottom); // _| + + SelectObject(hDC, hPenShadow); + MoveToEx(hDC, rcBtn.left + 1, rcBtn.bottom - 1, NULL); + LineTo(hDC, rcBtn.right - 1, rcBtn.bottom - 1); + LineTo(hDC, rcBtn.right - 1, rcBtn.top); + } + + // put everything back how it was + SetROP2(hDC, RopPrev); + SelectObject(hDC, hBrushPrev); + SelectObject(hDC, hPenPrev); + + DeleteObject(hPenBlack); + DeleteObject(hPenShadow); + DeleteObject(hPenHighlight); + DeleteObject(hBrushFace); + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID DrawButtonText(HDC hDC, RECT rcBtn, BOOL fHighlighted, UINT IDD_Btn) + { + char szLine1[MAXBUFSIZE]; // text in button up to '\n' + LPSTR pszLine2; // text in button after '\n' + int BkModePrev; + HFONT hFontPrev = NULL; + TEXTMETRIC tm; + RECT rcText = rcBtn; + + BkModePrev = SetBkMode(hDC, TRANSPARENT); + + GetDlgItemText(ghWndMain, IDD_Btn, szLine1, MAXBUFSIZE); + pszLine2 = strstr(szLine1, "\n"); + if(pszLine2) + { + *pszLine2 = 0; // 1 -> "TEST1 \n TEST2" becomes "TEST 1 \0" + ++pszLine2; // now 2 -> " TEST 2" + } + + // now szLine1 points to the null terminated first string and + // pszLine2 points to either the null terminated second string or NULL + // if there was no second string + + if(szLine1[0]) + { + if(ghFontBtnText && pszLine2) + hFontPrev = SelectObject(hDC, ghFontBtnText); + + GetTextMetrics(hDC, &tm); + rcText.bottom = (rcBtn.bottom + rcBtn.top)/2 - 2; + rcText.top = rcText.bottom - (tm.tmHeight - 1); + + if(pszLine2 == NULL) + OffsetRect(&rcText, 0, (rcText.bottom - rcText.top)/2); + + if(fHighlighted) + OffsetRect(&rcText, 1, 1); + + DrawText(hDC, szLine1, -1, &rcText, DT_SINGLELINE | DT_CENTER); + + if(hFontPrev) + SelectObject(hDC, hFontPrev); + } + if(pszLine2) // recall that pszLine2 == NULL to represent no second string + { + GetTextMetrics(hDC, &tm); + if(IDD_Btn == IDD_DBUTTONSTAR || IDD_Btn == IDD_DBUTTONPOUND) + rcText.top = (rcBtn.bottom + rcBtn.top)/2 - (tm.tmHeight)/2; + else + rcText.top = (rcBtn.bottom + rcBtn.top)/2 - 2; + rcText.bottom = rcText.top + tm.tmHeight; + + if(fHighlighted) + OffsetRect(&rcText, 1, 1); + + DrawText(hDC, pszLine2, -1, &rcText, DT_SINGLELINE | DT_CENTER); + } + + SetBkMode(hDC, BkModePrev); + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID DisableDialButtons(BOOL fDisable) +{ + int IDD; + + // Disable/enable Dial button + EnableWindow( GetDlgItem( ghWndMain, IDD_DDIAL ),!fDisable) ; + + // Disable/enable Speed dial buttons + for ( IDD = IDD_DSPEEDDIAL1; IDD <= IDD_DSPEEDDIAL8; ++IDD ) + { + EnableWindow(GetDlgItem(ghWndMain, IDD),!fDisable); + } +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID DialerCleanup(VOID) + { + RECT rc; + WORD cItem; // count of numbers in combo box + DWORD cLastDialed; + char szPt[MAXBUFSIZE]; + char szNumber[TAPIMAXDESTADDRESSSIZE]; + char szFieldName[MAXBUFSIZE]; + + CloseTAPI(); // unregister and line close + + if(!IsIconic(ghWndMain)) // if the window is not minimized, record position + { + GetWindowRect(ghWndMain, &rc); + wsprintf(szPt, "%ld, %ld", rc.left, rc.top); + WritePrivateProfileString( + "Preference", + "Main Window Left/Top", + szPt, + gszINIfilename + ); + } + + cItem = (WORD)SendDlgItemMessage(ghWndMain, IDD_DCOMBO, CB_GETCOUNT, 0, 0); + + // write out last dialed numbers from combo box (write to INI) + for(cLastDialed = 1; cLastDialed <= NLASTDIALED; ++cLastDialed) + { + if(cLastDialed <= cItem) + SendDlgItemMessage( + ghWndMain, + IDD_DCOMBO, + CB_GETLBTEXT, + cLastDialed - 1, // it's a zero-based count + (LPARAM)(LPCSTR)szNumber); + + else + szNumber[0] = 0; + + wsprintf(szFieldName, "Last dialed %d", cLastDialed); + WritePrivateProfileString( + "Last dialed numbers", + szFieldName, + szNumber, + gszINIfilename + ); + + } + + WinHelp(ghWndMain, gszHELPfilename, HELP_QUIT, 0); // unload help + + DestroyWindow(ghWndMain); + ghWndMain = NULL; + + DeleteObject(ghFontBtn); + DeleteObject(ghFontBtnText); + DeleteObject(ghFontBtnStar); + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +// unregister and line close +VOID CloseTAPI(VOID) +{ + + // unregister as call manager + lineRegisterRequestRecipient ( + ghLineApp, + 0, // registration instance + LINEREQUESTMODE_MAKECALL, + FALSE + ); + + if ( gCurrentLineInfo.hLine ) + { + lineClose ( gCurrentLineInfo.hLine ); + gfCurrentLineAvail = FALSE; + gCurrentLineInfo.hLine = NULL; + } + + lineShutdown(ghLineApp); +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static HICON hIcon; + static const DWORD aMenuHelpIDs[] = + { + IDD_DSPEEDDIALGRP, (DWORD)-1, + IDD_DNUMTODIAL, IDH_DIALER_DIAL_NUMBER, + IDD_DCOMBO, IDH_DIALER_DIAL_NUMBER, + IDD_DDIAL, IDH_DIALER_DIAL_BUTTON, + IDD_DSPEEDDIAL1, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL2, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL3, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL4, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL5, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL6, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL7, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL8, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT1, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT2, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT3, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT4, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT5, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT6, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT7, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT8, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DBUTTON1, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON2, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON3, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON4, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON5, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON6, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON7, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON8, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON9, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTONSTAR, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON0, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTONPOUND, IDH_DIALER_DIAL_KEYPAD, + 0, 0 + }; + + switch (msg) + { + case WM_INITDIALOG: + hIcon = LoadIcon( ghInst, (LPCSTR) MAKEINTRESOURCE( IDI_DIALER ) ); + return TRUE; + + case WM_SYSCOMMAND: + switch( (DWORD) wParam ) + { + case SC_CLOSE: + PostQuitMessage(0); + } + break; + + // processes clicks on controls when + // context mode help is selected + case WM_HELP: + WinHelp ( + ( (LPHELPINFO) lParam)->hItemHandle, + gszHELPfilename, + HELP_WM_HELP, + (DWORD)(LPVOID) aMenuHelpIDs + ); + return TRUE; + + // processes right-clicks on controls + case WM_CONTEXTMENU: + WinHelp ( + (HWND)wParam, + gszHELPfilename, + HELP_CONTEXTMENU, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_INITMENUPOPUP: + // if edit menu + if ( LOWORD(lParam) == 1 ) + { + UINT wEnable; + + if ( GetParent( GetFocus() ) != GetDlgItem( ghWndMain, IDD_DCOMBO ) ) + { + wEnable = MF_GRAYED; + } + else + { + LONG lSelect = SendDlgItemMessage ( + ghWndMain, + IDD_DCOMBO, + CB_GETEDITSEL, + 0, + 0 + ); + + if ( HIWORD( lSelect ) != LOWORD( lSelect ) ) + wEnable = MF_ENABLED; + else + wEnable = MF_GRAYED; + } + + EnableMenuItem((HMENU)wParam, IDM_EDIT_CUT, wEnable); + EnableMenuItem((HMENU)wParam, IDM_EDIT_COPY, wEnable); + EnableMenuItem((HMENU)wParam, IDM_EDIT_DELETE, wEnable); + + // enable paste option is there is data + // in the clipboard + if ( IsClipboardFormatAvailable( CF_TEXT ) ) + { + if ( GetClipboardData ( CF_TEXT ) ) + { + wEnable = MF_ENABLED; + } + else + { + wEnable = MF_GRAYED; + } + } + else + { + wEnable = MF_GRAYED; + } + + } + break; + + + case WM_COMMAND: + { + char szName[TAPIMAXCALLEDPARTYSIZE] = {'\0'}; + char szNumber[TAPIMAXDESTADDRESSSIZE] = {'\0'}; + + switch( LOWORD( (DWORD)wParam ) ) + { + // FILE menu + case IDM_EXIT: + PostQuitMessage(0); + return TRUE; + + + // EDIT menu + case IDM_EDIT_CUT: + SendDlgItemMessage(ghWndMain, IDD_DCOMBO, WM_CUT, 0, 0); + return TRUE; + + case IDM_EDIT_COPY: + SendDlgItemMessage(ghWndMain, IDD_DCOMBO, WM_COPY, 0, 0); + return TRUE; + + case IDM_EDIT_PASTE: + SendDlgItemMessage(ghWndMain, IDD_DCOMBO, WM_PASTE, 0, 0); + return TRUE; + + case IDM_EDIT_DELETE: + SendDlgItemMessage(ghWndMain, IDD_DCOMBO, WM_CLEAR, 0, 0); + return TRUE; + + case IDM_EDIT_SPEEDDIAL: + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_SD1), + ghWndMain, + (DLGPROC)SpeedDial1Proc, + 0 + ); + SetFocus(GetDlgItem(ghWndMain, IDD_DDIAL)); + return TRUE; + + // TOOLS menu + case IDM_CONNECTUSING: + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CONNECTUSING), + ghWndMain, + (DLGPROC)ConnectUsingProc, + MENU_CHOICE + ); + return TRUE; + + case IDM_LOCATION: + { + char szCanNumber[ TAPIMAXDESTADDRESSSIZE ] = ""; + + // fetch the number to be dialed + if ( GetDlgItemText ( + ghWndMain, + IDD_DCOMBO, + szNumber, + TAPIMAXDESTADDRESSSIZE + ) + ) + { + // if a number exists, convert it to + // its canonical form. + if ( !MakeCanonicalNumber ( szNumber, szCanNumber ) ) + { + lstrcpy( szCanNumber, szNumber ); + } + } + + lineTranslateDialog ( + ghLineApp, + 0, + TAPI_CURRENT_VERSION, + ghWndMain, + szCanNumber + ); + return TRUE; + + } + // HELP menu + case IDM_HELP_CONTENTS: + WinHelp(ghWndMain, gszHELPfilename, HELP_CONTENTS, 0); + return TRUE; + + case IDM_HELP_WHATSTHIS: + PostMessage(ghWndMain, WM_SYSCOMMAND, SC_CONTEXTHELP, 0); + return TRUE; + + case IDM_ABOUT: +#ifdef SDKRELEASE + DialogBoxParam( + ghInst, + MAKEINTRESOURCE(IDD_ABOUT), + ghWndMain, + (DLGPROC)AboutProc, + 0 + ); +#else + ShellAbout( + ghWndMain, + gszAppName, + gszNULL, + LoadIcon(ghInst, (LPCSTR)IDI_DIALER) + ); +#endif + return TRUE; + + + // Accelerator processing + case IDM_ACCEL_NUMTODIAL: + if(GetActiveWindow() == ghWndMain) + SetFocus(GetDlgItem(ghWndMain, IDD_DCOMBO)); + return TRUE; + + + // Buttons + case IDD_DDIAL: + + { + DWORD cSDEntry; + char szSDNumber[TAPIMAXDESTADDRESSSIZE]; + char szFieldName[MAXBUFSIZE]; + + // check if number entered is dialable + if ( SendMessage ( + GetDlgItem(ghWndMain, IDD_DCOMBO), + WM_GETTEXTLENGTH, + 0, + 0 + ) > 0 + ) + { + // get the number to be dialed + GetDlgItemText ( + ghWndMain, + IDD_DCOMBO, + (LPSTR)szNumber, + TAPIMAXDESTADDRESSSIZE + ); + + // check if it is a speed dial number. + // If so choose the name to be displayed. + for( cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry) + { + wsprintf(szFieldName, "Number%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + szSDNumber, + TAPIMAXCALLEDPARTYSIZE - 1, + gszINIfilename + ); + + // if the number matches, get the name + if ( lstrcmp(szSDNumber, szNumber) == 0 ) + { + wsprintf( szFieldName, "Name%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + szName, + TAPIMAXCALLEDPARTYSIZE - 1, + gszINIfilename + ); + break; + } + } + + SetFocus( GetDlgItem( ghWndMain, IDD_DDIAL ) ); + + // once the currentline has been set + // using the connect proc + // the user must hit dial again + if ( giCurrentLine == (DWORD)-1 ) + { + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CONNECTUSING), + ghWndMain, + (DLGPROC)ConnectUsingProc, + INVALID_LINE + ); + } + else + { + AddToRedialList(szNumber); + InitiateCall(szNumber, szName); + } + } + return TRUE; + } + + + case IDD_DBUTTON1: + case IDD_DBUTTON2: + case IDD_DBUTTON3: + case IDD_DBUTTON4: + case IDD_DBUTTON5: + case IDD_DBUTTON6: + case IDD_DBUTTON7: + case IDD_DBUTTON8: + case IDD_DBUTTON9: + case IDD_DBUTTON0: + case IDD_DBUTTONSTAR: + case IDD_DBUTTONPOUND: + { + int i; + TCHAR szBuffer[TAPIMAXDESTADDRESSSIZE+1]; + + static const char digits[] = { '1', '2', '3', '4', + '5', '6', '7', '8', + '9', '0', '*', '#' }; + + i = SendDlgItemMessage(ghWndMain, + IDD_DCOMBO, + WM_GETTEXT, + (WPARAM)TAPIMAXDESTADDRESSSIZE+1, + (LPARAM)szBuffer); + + if (i < TAPIMAXDESTADDRESSSIZE) + { + MoveMemory(szBuffer+gdwStartSel+1, + szBuffer+gdwEndSel, + i - ( gdwEndSel ) + 1 ); + + szBuffer[gdwStartSel] = digits[LOWORD(wParam) - IDD_DBUTTON1]; + + SendDlgItemMessage(ghWndMain, + IDD_DCOMBO, + WM_SETTEXT, + 0, + (LPARAM)szBuffer); + + gdwStartSel++; + gdwEndSel = gdwStartSel; + } + + SetFocus(GetDlgItem(ghWndMain, IDD_DDIAL)); + EnableWindow(GetDlgItem(ghWndMain, IDD_DDIAL), TRUE); + + return TRUE; + } + + + case IDD_DCOMBO: + + if (HIWORD(wParam) == CBN_SELENDOK) + { + EnableWindow( GetDlgItem(ghWndMain, IDD_DDIAL), TRUE ); + } + + if ((HIWORD(wParam) == CBN_SELENDOK) || + (HIWORD(wParam) == CBN_SELENDCANCEL)) + { + + (DWORD)SendDlgItemMessage(ghWndMain, + IDD_DCOMBO, + CB_GETEDITSEL, + (WPARAM)&gdwStartSel, + (LPARAM)&gdwEndSel); + return FALSE; + } + + if ( HIWORD( wParam ) == CBN_EDITCHANGE ) + { + EnableWindow ( + GetDlgItem( ghWndMain, IDD_DDIAL ), + (BOOL) GetWindowTextLength ( + GetDlgItem ( + ghWndMain, + IDD_DCOMBO + ) + ) + ); + return TRUE; + } + + break; + + case IDD_DSPEEDDIAL1: + case IDD_DSPEEDDIAL2: + case IDD_DSPEEDDIAL3: + case IDD_DSPEEDDIAL4: + case IDD_DSPEEDDIAL5: + case IDD_DSPEEDDIAL6: + case IDD_DSPEEDDIAL7: + case IDD_DSPEEDDIAL8: + { + DWORD cSDEntry = LOWORD( (DWORD) wParam) - IDD_DSPEEDDIAL1 + 1; + char szFieldName [MAXBUFSIZE]; + + // get information for the speed dial button + // from the INI file + wsprintf(szFieldName, "Name%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + szName, + TAPIMAXCALLEDPARTYSIZE - 1, + gszINIfilename + ); + + wsprintf(szFieldName, "%s%d", "Number", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + gszSDNumber[cSDEntry], + TAPIMAXDESTADDRESSSIZE - 1, + gszINIfilename + ); + + // entry not set yet + if( gszSDNumber[cSDEntry][0] == 0 ) + { + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_SD2), + ghWndMain, + (DLGPROC)SpeedDial2Proc, + MAKELPARAM(wParam,0) + ); + } + + // no line open + // once the currentline has been set + // using the connect proc + // the user must hit dial again + else if ( giCurrentLine == (DWORD)-1) + { + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CONNECTUSING), + ghWndMain, + (DLGPROC)ConnectUsingProc, + INVALID_LINE + ); + } + // entry is set and valid voice line is open + else + { + // add number to list box combo. + AddToRedialList( gszSDNumber[cSDEntry] ); + InitiateCall( gszSDNumber[cSDEntry], szName ); + } + break; + } + } // end switch (LOWORD((DWORD)wParam)) { ... } + + break; // end case WM_COMMAND + } + + + case WM_PAINT: + { + PAINTSTRUCT ps; + + + BeginPaint(ghWndMain, &ps); + + if(IsIconic(ghWndMain)) + DrawIcon(ps.hdc, 0, 0, hIcon); + else + { + HBRUSH hBrush; + + hBrush = GetSysColorBrush( COLOR_3DFACE ); + // FillRect(ps.hdc, &ps.rcPaint, GetStockObject(LTGRAY_BRUSH)); + FillRect(ps.hdc, &ps.rcPaint, hBrush); + } + + EndPaint(ghWndMain, &ps); + + return TRUE; + } + + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam; + BOOL fHighlighted = (SendDlgItemMessage( + ghWndMain, + lpdis->CtlID, + BM_GETSTATE, + 0, + 0 + ) & 0x0004); + + DrawButton(lpdis->hDC, lpdis->rcItem, fHighlighted); + DrawButtonText( + lpdis->hDC, + lpdis->rcItem, + fHighlighted, + lpdis->CtlID + ); + return TRUE; + } + + + case WM_CTLCOLORLISTBOX: + case WM_CTLCOLORBTN: + case WM_CTLCOLORSTATIC: + SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNFACE)); + return (BOOL)GetSysColorBrush( COLOR_3DFACE ); + + + default: + ; + // return DefDlgProc( hwnd, msg, wParam, lParam ); + // return DefWindowProc( hwnd, msg, wParam, lParam ); + + + } // switch (msg) { ... } + + return FALSE; + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID AddToRedialList( LPCSTR szNumber ) +{ + // NLASTDIALED == 10 + WORD cNum; + HWND hWndCombo = GetDlgItem(ghWndMain, IDD_DCOMBO); + DWORD nMatch; + + // if valid number + if ( szNumber[0] ) + { + // if list box has entries, check if this number + // is already present. If so delete old entry + cNum = (WORD) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0); + if ( cNum != 0 ) + { + nMatch = SendMessage ( hWndCombo, CB_FINDSTRING, 0, (LPARAM)szNumber ); + if ( nMatch != CB_ERR ) + { + SendMessage(hWndCombo, CB_DELETESTRING, nMatch, 0); + } + else + { + // if the list is full, remove oldest + if ( cNum == NLASTDIALED ) + { + SendMessage( hWndCombo, CB_DELETESTRING, NLASTDIALED - 1, 0 ); + } + } + } + SendMessage(hWndCombo, CB_INSERTSTRING, 0, (LPARAM)szNumber); + SendMessage(hWndCombo, CB_SETCURSEL, 0, 0L); + EnableWindow ( GetDlgItem( ghWndMain, IDD_DDIAL ), TRUE ); + } +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID InitiateCall ( LPCSTR szNumber, LPCSTR szName ) +{ + HLINE hLine = NULL; + + DWORD errCode; + + // struct size info + DWORD dwLTPSize = sizeof ( LINETRANSLATEOUTPUT ); + DWORD dwNameLen = lstrlen( szName ) + 1; + DWORD dwLCPSize = sizeof( LINECALLPARAMS ); + + LPLINETRANSLATEOUTPUT lpTransOut = NULL; + LPLINECALLPARAMS lpLineCallParams = NULL; + + char szCanNumber[ TAPIMAXDESTADDRESSSIZE ]; + + // Open a line + errCode = lineOpen ( + ghLineApp, + giCurrentLine, + &hLine, + gCurrentLineInfo.dwAPIVersion, + 0, + 0, + LINECALLPRIVILEGE_NONE, + 0, + NULL + ); + if (errCode) + { + errString ( ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK ); + goto error; + } + + + // call translate address before dialing + do + { + lpTransOut = (LPLINETRANSLATEOUTPUT) DialerAlloc( dwLTPSize ); + if ( !lpTransOut ) + { + errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK ); + goto error; + } + lpTransOut-> dwTotalSize = dwLTPSize; + + + if ( !MakeCanonicalNumber( szNumber, szCanNumber ) ) + { + lstrcpy( szCanNumber, szNumber ); + } + + errCode = lineTranslateAddress ( + ghLineApp, + giCurrentLine, + gCurrentLineInfo.dwAPIVersion, + szCanNumber, + 0, + 0, + lpTransOut + ); + if ( ((LONG)errCode) < 0 ) + { + errString( ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK ); + goto error; + } + + if ( lpTransOut-> dwNeededSize <= lpTransOut->dwTotalSize ) + { + // ok we are done + break; + } + else + { + dwLTPSize = lpTransOut-> dwNeededSize; + DialerFree ( lpTransOut ); + lpTransOut = NULL; + } + + } while ( TRUE ); + + + // if number dialed is 911, bring up a warning + if ( Is911( lpTransOut) ) + { + INT nRes = errString ( ghWndMain, ERR_911WARN, MB_ICONSTOP | MB_YESNO ); + if ( nRes == IDNO ) + { + goto error; + } + } + + + // set call parameters + dwLCPSize += dwNameLen + lpTransOut-> dwDisplayableStringSize; + + lpLineCallParams = (LPLINECALLPARAMS) DialerAlloc( dwLCPSize ); + if ( !lpLineCallParams ) + { + errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK ); + goto error; + } + + lpLineCallParams->dwTotalSize = dwLCPSize; + lpLineCallParams->dwBearerMode = LINEBEARERMODE_VOICE; + lpLineCallParams->dwMediaMode = LINEMEDIAMODE_INTERACTIVEVOICE; + lpLineCallParams->dwCallParamFlags = LINECALLPARAMFLAGS_IDLE; + lpLineCallParams->dwAddressMode = LINEADDRESSMODE_ADDRESSID; + lpLineCallParams->dwAddressID = giCurrentAddress; + + if ( szName[ 0 ] ) + { + lpLineCallParams->dwCalledPartySize = dwNameLen; + lpLineCallParams->dwCalledPartyOffset = sizeof( LINECALLPARAMS ); + lstrcpy ( + (LPSTR) lpLineCallParams + sizeof(LINECALLPARAMS), + szName + ); + } + + lpLineCallParams-> dwDisplayableAddressSize = lpTransOut-> dwDisplayableStringSize; + lpLineCallParams-> dwDisplayableAddressOffset = sizeof( LINECALLPARAMS ) + dwNameLen; + + lstrcpy ( + (LPSTR) lpLineCallParams + sizeof(LINECALLPARAMS) + dwNameLen, + (LPSTR) lpTransOut + lpTransOut-> dwDisplayableStringOffset + ); + + + // save dialing information + // Free old allocs. + if ( gszCurrentName ) + { + DialerFree ( gszCurrentName ); + } + + if ( gszCurrentNumber ) + { + DialerFree ( gszCurrentNumber ); + } + + // save new stuff + gszCurrentName = (LPSTR) DialerAlloc( dwNameLen ); + if ( !gszCurrentName ) + { + errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK ); + goto error; + } + lstrcpy ( gszCurrentName, szName ); + + gszCurrentNumber = (LPSTR) DialerAlloc( lpTransOut-> dwDisplayableStringSize ); + if ( !gszCurrentNumber ) + { + errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK ); + goto error; + } + lstrcpy ( + gszCurrentNumber, + (LPSTR) lpTransOut + lpTransOut-> dwDisplayableStringOffset + ); + + gCurrentLineInfo.hLine = hLine; + ghCall = NULL; + + + // finally make the call. + gMakeCallRequestID = 0; + + gMakeCallRequestID = lineMakeCall ( + hLine, + &ghCall, + (LPSTR) lpTransOut + lpTransOut-> dwDialableStringOffset, + 0, + lpLineCallParams + ); + + // async request ID + // - the call is going out + if ( (LONG) gMakeCallRequestID > 0 ) + { + gfCurrentLineAvail = FALSE; + gfMakeCallReplyPending = TRUE; + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_DIALING), + ghWndMain, + (DLGPROC)DialingProc, + 0 + ); + + } + + else + { + if ( gMakeCallRequestID == LINEERR_CALLUNAVAIL ) + { + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CALLFAILED), + ghWndMain, + (DLGPROC)LineInUseProc, + 0 + ); + } + + else + { + errString( ghWndMain, gMakeCallRequestID, MB_ICONEXCLAMATION | MB_OK ); + } + + DialerLineClose(); + gfCurrentLineAvail = TRUE; + } + +error : + if ( lpLineCallParams ) + { + DialerFree( lpLineCallParams ); + } + + if ( lpTransOut ) + { + DialerFree( lpTransOut ); + } + + // if makecall did not succeed but line + // was opened, close it. + if ( ( gMakeCallRequestID <= 0 ) && ( gCurrentLineInfo.hLine ) ) + { + DialerLineClose (); + gfCurrentLineAvail = TRUE; + } + + SetFocus( GetDlgItem( ghWndMain, IDD_DCOMBO ) ); + + return; + +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +DWORD GetLineInfo ( DWORD iLine, LPLINEINFO lpLineInfo ) +{ + DWORD errCode = 0; + DWORD dwNeededSize = 0; + LINEEXTENSIONID ExtensionID; + + LPSTR pszLineName = NULL; + LPLINEDEVCAPS lpDevCaps = NULL; + + + errCode = lineNegotiateAPIVersion ( + ghLineApp, + iLine, + TAPI_VERSION_1_0, + TAPI_CURRENT_VERSION, + &( lpLineInfo->dwAPIVersion ), + &ExtensionID + ); + if ( errCode ) + { + GetLineInfoFailed( iLine, lpDevCaps, lpLineInfo ); + goto error; + } + + dwNeededSize = sizeof( LINEDEVCAPS ); + do + { + lpDevCaps = ( LPLINEDEVCAPS ) DialerAlloc( dwNeededSize ); + if ( !lpDevCaps ) + { + GetLineInfoFailed( iLine, lpDevCaps, lpLineInfo ); + errCode = LINEERR_NOMEM; + goto error; + } + + lpDevCaps->dwTotalSize = dwNeededSize; + errCode = lineGetDevCaps ( + ghLineApp, + iLine, + lpLineInfo->dwAPIVersion, + 0, + lpDevCaps + ); + if ( errCode ) + { + GetLineInfoFailed( iLine, lpDevCaps, lpLineInfo ); + goto error; + } + + if ( lpDevCaps-> dwNeededSize <= lpDevCaps-> dwTotalSize ) + { + break; + } + + dwNeededSize = lpDevCaps->dwNeededSize; + DialerFree( lpDevCaps ); + lpDevCaps = NULL; + + } while ( TRUE ); + + + lpLineInfo->nAddr = lpDevCaps->dwNumAddresses; + lpLineInfo->fVoiceLine = + ( (lpDevCaps->dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE) != 0 ); + + pszLineName = (LPSTR) DialerAlloc( MAXBUFSIZE ); + if ( !pszLineName ) + { + errCode = LINEERR_NOMEM; + goto error; + } + + if ( lpDevCaps->dwLineNameSize > 0 ) + { + if ( lpDevCaps-> dwLineNameSize > (MAXBUFSIZE - 1) ) + { + strncpy ( + pszLineName, + (LPSTR) lpDevCaps + lpDevCaps->dwLineNameOffset, + MAXBUFSIZE - 1 + ); + pszLineName[ MAXBUFSIZE - 1 ] = '\0'; + } + else + { + lstrcpy( pszLineName, (LPSTR) lpDevCaps + lpDevCaps-> dwLineNameOffset ); + } + } + else + { + wsprintf ( pszLineName, "Line %d", iLine ); + } + + + lstrcpy( lpLineInfo->szLineName, pszLineName ); + lpLineInfo->dwPermanentLineID = lpDevCaps->dwPermanentLineID; + + +error: + if ( lpDevCaps ) + DialerFree( lpDevCaps ); + + if ( pszLineName ) + DialerFree( pszLineName ); + + return errCode; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID GetLineInfoFailed ( DWORD iLine, LPLINEDEVCAPS lpDevCaps, LPLINEINFO lpLineInfo ) +{ + if ( lpDevCaps ) + DialerFree(lpDevCaps); + + lpLineInfo->nAddr = 0; + lpLineInfo->fVoiceLine = FALSE; + lpLineInfo->dwAPIVersion = 0; + lpLineInfo->hLine = (HLINE)0; + lpLineInfo->dwPermanentLineID = 0; + lpLineInfo->szLineName[0] = 0; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +LPSTR GetAddressName(DWORD iLine, DWORD iAddress) +{ + DWORD errCode = 0; + DWORD dwNeededSize = 0; + LPSTR pszAddressName = NULL; + LPLINEADDRESSCAPS lpAddressCaps = NULL; + + // allocate space for lineGetAddressCaps data + dwNeededSize = sizeof( LINEADDRESSCAPS ); + + do + { + lpAddressCaps = ( LPLINEADDRESSCAPS )DialerAlloc( dwNeededSize ); + if ( !lpAddressCaps ) + { + goto error; + } + + lpAddressCaps->dwTotalSize = dwNeededSize; + errCode = lineGetAddressCaps ( + ghLineApp, + iLine, + iAddress, + gCurrentLineInfo.dwAPIVersion, + 0, + lpAddressCaps + ); + if ( errCode ) + { + errString( ghWndMain, errCode, MB_ICONSTOP | MB_OK ); + goto error; + } + + if ( lpAddressCaps-> dwNeededSize <= lpAddressCaps-> dwTotalSize ) + { + break; + } + + dwNeededSize = lpAddressCaps->dwNeededSize; + DialerFree( lpAddressCaps ); + lpAddressCaps = NULL; + + } while( TRUE ); + + + // get the address name + pszAddressName = DialerAlloc( MAXBUFSIZE ); + if ( !pszAddressName ) + { + goto error; + } + + if ( lpAddressCaps-> dwAddressSize > 0 ) + { + // keep string length bounded + if ( lpAddressCaps-> dwAddressSize > (MAXBUFSIZE - 1 ) ) + { + strncpy( + pszAddressName, + (LPSTR) lpAddressCaps + lpAddressCaps->dwAddressOffset, + MAXBUFSIZE - 1 + ); + pszAddressName[ MAXBUFSIZE - 1] = '\0'; + } + else + { + lstrcpy ( + pszAddressName, + (LPSTR) lpAddressCaps + lpAddressCaps->dwAddressOffset + ); + } + } + else + // use default name + { + wsprintf(pszAddressName, "Address %d", iAddress); + } + +error: + if ( lpAddressCaps ) + { + DialerFree( lpAddressCaps ); + } + + return pszAddressName; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK DialingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + + switch(msg) + { + char szTemp[ TAPIMAXCALLEDPARTYSIZE ]; + + case WM_INITDIALOG: + // set global handle to window + ghWndDialing = hwnd; + + AmpersandCompensate( gszCurrentName, szTemp ); + + SetDlgItemText(hwnd, IDD_DGNUMBERTEXT, gszCurrentNumber); + SetDlgItemText(hwnd, IDD_DGNAMETEXT, szTemp ); + break; + + case WM_COMMAND: + switch ( LOWORD( (DWORD)wParam ) ) + { + // hang up + case IDCANCEL: + //gfDropping = TRUE; + + // if lineMakeCall has completed + // only then drop call. + if ( !gfMakeCallReplyPending && ghCall ) + { + if ( ( gDropCallRequestID = lineDrop ( ghCall, NULL, 0 ) ) < 0 ) + { + errString ( ghWndDialing, gDropCallRequestID, MB_ICONSTOP | MB_OK ); + } + } + else + { + DialerLineClose(); + gfCurrentLineAvail = TRUE; + gfMakeCallReplyPending = FALSE; + } + + ghWndDialing = NULL; + EndDialog(hwnd, FALSE); + + return TRUE; + + + // something else terminated the call + // all we have to do is terminate this dialog box + case IDOK: + ghWndDialing = NULL; + EndDialog(hwnd, TRUE); + + return TRUE; + } + break; + + default: + ; + } + return FALSE; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK AboutProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) + { + switch(msg) + { + case WM_INITDIALOG: + { + char sz[MAXBUFSIZE]; + char szLabel[MAXBUFSIZE]; + + // sets up the version number for Windows + GetDlgItemText(hwnd, IDD_ATEXTTITLE, sz, MAXBUFSIZE); + wsprintf( + szLabel, + sz, + LOWORD(GetVersion()) & 0xFF, + HIBYTE(LOWORD(GetVersion)) == 10 ? 1 : 0 + ); + SetDlgItemText(hwnd, IDD_ATEXTTITLE, szLabel); + +/* // sets up version number for Dialer + GetDlgItemText(hwnd, IDD_ATEXTVERSION, sz, MAXBUFSIZE); + wsprintf(szLabel, sz, VER_MAJOR, VER_MINOR, VER_BUILD); + + + { // strip off build number for release copies + DWORD i; + LPSTR ch = szLabel; + + for (i = 0; i < 2 && *ch; ++ch) + { + if(*ch == '.') + ++i; + if(i == 2) + *ch = 0; + } + + SetDlgItemText(hwnd ,IDD_ATEXTVERSION, szLabel); + } */ + + +/* // get free memory information + GetDlgItemText(hwnd, IDD_ATEXTFREEMEM, sz, MAXBUFSIZE); + wsprintf(szLabel, sz, GetFreeSpace(0)>>10); + SetDlgItemText(hwnd, IDD_ATEXTFREEMEM, szLabel); + + // get free resources information + GetDlgItemText(hwnd, IDD_ATEXTRESOURCE, sz,MAXBUFSIZE); + wsprintf(szLabel, sz, GetFreeSystemResources(0)); + SetDlgItemText(hwnd, IDD_ATEXTRESOURCE, szLabel); */ + + return TRUE; + } + + case WM_COMMAND: + if(LOWORD((DWORD)wParam) == IDOK) + { + EndDialog(hwnd, TRUE); + return TRUE; + } + break; + } + return FALSE; + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK ConnectUsingProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + static const DWORD aMenuHelpIDs[] = + { + IDD_CUTEXTLINE, IDH_DIALER_OPTIONS_LINE, + IDD_CULISTLINE, IDH_DIALER_OPTIONS_LINE, + IDD_CUTEXTADDRESS, IDH_DIALER_OPTIONS_ADDRESS, + IDD_CULISTADDRESS, IDH_DIALER_OPTIONS_ADDRESS, + IDD_CUSIMPLETAPICHKBOX, IDH_DIALER_OPTIONS_VOICE, + IDD_CUPROPERTIES, IDH_DIALER_OPTIONS_PROPERTIES, + 0, 0 + }; + + switch(msg) + { + case WM_HELP: + // processes clicks on controls when + // context mode help is selected + WinHelp ( + ((LPHELPINFO)lParam)->hItemHandle, + gszHELPfilename, + HELP_WM_HELP, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_CONTEXTMENU: + // processes right-clicks on controls + WinHelp ( + (HWND)wParam, + gszHELPfilename, + HELP_CONTEXTMENU, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_INITDIALOG: + { + BOOL fEnable; + DWORD dwPriority; + + // + // Is there any point in even showing this dialog box? + if ( gnAvailDevices == 0 ) + { + // Nope. Let's tell the user what we don't like. + errString ( ghWndMain, ERR_NOLINES, MB_ICONEXCLAMATION | MB_OK ); + + EndDialog(hwnd, FALSE); + return TRUE; + } + + // if not brought up by InitializeTAPI() + if ( lParam != INVALID_LINE ) + { + // hide error text + EnableWindow( GetDlgItem( hwnd, IDD_CUERRORTEXT ), FALSE ); + } + + // get list of lines into the line list box. + fEnable = InitializeLineBox( GetDlgItem(hwnd, IDD_CULISTLINE) ); + EnableWindow( GetDlgItem( hwnd, IDD_CULISTLINE ), fEnable); + + // get list of addresses into the address list box. + fEnable = fEnable && + InitializeAddressBox ( + GetDlgItem(hwnd, IDD_CULISTLINE), + GetDlgItem(hwnd, IDD_CULISTADDRESS) + ); + EnableWindow( GetDlgItem( hwnd, IDD_CULISTADDRESS ), fEnable ); + EnableWindow( GetDlgItem( hwnd, IDOK ), fEnable ); + + EnableWindow( GetDlgItem( hwnd, IDD_CUPROPERTIES ), fEnable ); + + lineGetAppPriority ( + "DIALER.EXE", + 0, // checking app priority for Assisted Telephony requests + NULL, + LINEREQUESTMODE_MAKECALL, + NULL, + &dwPriority + ); + CheckDlgButton(hwnd, IDD_CUSIMPLETAPICHKBOX, (dwPriority == 1)); + + // if dwPriority == 1, we're supporting Assisted Telephony AND + // have the highest priority. + EnableWindow ( + GetDlgItem(hwnd, IDD_CUSIMPLETAPICHKBOX), + gfRegistered + ); + + return FALSE; + } + + case WM_COMMAND: + { + switch ( LOWORD( (DWORD)wParam ) ) + { + case IDD_CULISTLINE: + if ( HIWORD( wParam ) == CBN_SELENDOK ) + // update address box + InitializeAddressBox ( + GetDlgItem(hwnd, IDD_CULISTLINE), + GetDlgItem(hwnd, IDD_CULISTADDRESS) + ); + break; + + case IDD_CUPROPERTIES: + { + HWND hW = GetDlgItem(hwnd, IDD_CULISTLINE); + + lineConfigDialog ( + // device ID + (DWORD) SendMessage ( + hW, + CB_GETITEMDATA, + (WORD) SendMessage(hW, CB_GETCURSEL, 0, 0), + 0 + ), + hwnd, + NULL + ); + break; + } + + case IDOK: + { + HWND hwndBox; + char szBuffer[MAXBUFSIZE]; + DWORD dwPriority; + + // Update line + hwndBox = GetDlgItem( hwnd, IDD_CULISTLINE ); + giCurrentLine = SendMessage ( + hwndBox, + CB_GETITEMDATA, + SendMessage( hwndBox, CB_GETCURSEL, 0, 0 ), + 0 + ); + + // base 10 + itoa( gdwPLID[giCurrentLine], szBuffer, 10 ); + WritePrivateProfileString ( + "Preference", + "Preferred Line", + szBuffer, + gszINIfilename + ); + + + // Update address + hwndBox = GetDlgItem( hwnd, IDD_CULISTADDRESS ); + giCurrentAddress = SendMessage ( + hwndBox, + CB_GETITEMDATA, + SendMessage(hwndBox, CB_GETCURSEL, 0, 0), + 0 + ); + + itoa( giCurrentAddress, szBuffer, 10 ); + WritePrivateProfileString ( + "Preference", + "Preferred Address", + szBuffer, + gszINIfilename + ); + + + // Update application priority + if ( SendDlgItemMessage ( + hwnd, + IDD_CUSIMPLETAPICHKBOX, + BM_GETCHECK, + 0, + 0L + ) + == 0) + { + dwPriority = 0; + } + else + { + dwPriority = 1; + } + + lineSetAppPriority ( + "DIALER.EXE", + 0, + NULL, + LINEREQUESTMODE_MAKECALL, + NULL, + dwPriority + ); + + EndDialog(hwnd, TRUE); + return TRUE; + } + + case IDCANCEL: + EndDialog(hwnd, FALSE); + return TRUE; + } + } + + default: + ; + + } + + return FALSE; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK LineInUseProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) + { + LPARAM lNewParam = lParam; + PTSTR ptStr; + + + switch(msg) + { + case WM_INITDIALOG: + { + switch(lParam) + { + case LINEDISCONNECTMODE_REJECT: + lNewParam = ikszDisconnectedReject; + break; + + case LINEDISCONNECTMODE_BUSY: + lNewParam = ikszDisconnectedBusy; + break; + + case LINEDISCONNECTMODE_NOANSWER: + lNewParam = ikszDisconnectedNoAnswer; + break; + + case LINEDISCONNECTMODE_CONGESTION: + lNewParam = ikszDisconnectedNetwork; + break; + + case LINEDISCONNECTMODE_INCOMPATIBLE: + lNewParam = ikszDisconnectedIncompatible; + break; + + case LINEDISCONNECTMODE_NODIALTONE: + lNewParam = ikszDisconnectedNoDialTone; + break; + + default: + lNewParam = ikszDisconnectedCantDo; + break; + } + return TRUE; + } + + case WM_COMMAND: + if(LOWORD((DWORD)wParam) == IDOK) + { + EndDialog(hwnd, TRUE); + return TRUE; + } + break; + + default: + ; +// return DefDlgProc( hwnd, msg, wParam, lParam ); + + } + + + ptStr = DialerAlloc( MAXBUFSIZE ); + + LoadString( ghInst, lNewParam, ptStr, MAXBUFSIZE ); + + SetDlgItemText( + hwnd, + IDD_CFTEXT, + ptStr + ); + + DialerFree( ptStr ); + + + return FALSE; + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK SpeedDial1Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static DWORD nCurrentSpeedDial; + + static const DWORD aMenuHelpIDs[] = + { + IDOK, IDH_DIALER_SPEED_SAVE, + IDD_SD1SPEEDDIAL1, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL2, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL3, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL4, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL5, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL6, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL7, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL8, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT1, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT2, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT3, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT4, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT5, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT6, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT7, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT8, IDH_DIALER_BUTTONS, + IDD_SD1TEXTNAME, IDH_DIALER_SPEED_NAME, + IDD_SD1EDITNAME, IDH_DIALER_SPEED_NAME, + IDD_SD1TEXTNUMBER, IDH_DIALER_SPEED_NUMBER, + IDD_SD1EDITNUMBER, IDH_DIALER_SPEED_NUMBER, + IDD_SD1TEXTCHOOSE, (DWORD)-1, + IDD_SD1TEXTENTER, (DWORD)-1, + 0, 0 + }; + + // buffer to store speed dial names till they are saved. + static TCHAR szSDName[NSPEEDDIALS + 1][TAPIMAXDESTADDRESSSIZE]; + + switch(msg) + { + case WM_HELP: + // processes clicks on controls when + // context mode help is selected + WinHelp( + ((LPHELPINFO)lParam)->hItemHandle, + gszHELPfilename, + HELP_WM_HELP, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_CONTEXTMENU: // processes right-clicks on controls + WinHelp( + (HWND)wParam, + gszHELPfilename, + HELP_CONTEXTMENU, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_INITDIALOG: + { + DWORD cSDEntry; + DWORD idFirstEmpty = (DWORD) -1; + + char szName[TAPIMAXCALLEDPARTYSIZE]; + char szTemp[TAPIMAXCALLEDPARTYSIZE]; + char szFieldName[MAXBUFSIZE]; + + // Retrieve speed dial info from INI file + for(cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry) + { + wsprintf(szFieldName, "Name%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + szSDName[ cSDEntry ], + TAPIMAXCALLEDPARTYSIZE - 1, + gszINIfilename + ); + + // set the first empty speed dial button + if ( idFirstEmpty == -1 && + szSDName[ cSDEntry ][0] == '\0' && + gszSDNumber[ cSDEntry ][ 0 ] == '\0' ) + idFirstEmpty = cSDEntry; + + wsprintf(szFieldName, "Number%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + gszSDNumber[cSDEntry], + MAXBUFSIZE - 1, + gszINIfilename + ); + + // get a copy of the name for editing + // if name is empty, use the number as the + // name. + if ( lstrcmp( gszNULL, szSDName[ cSDEntry ] ) ) + { + lstrcpy( szName, szSDName[ cSDEntry] ); + } + else + { + lstrcpy( szName, gszSDNumber[ cSDEntry ] ); + } + + FitTextToButton( hwnd, IDD_SD1SPEEDDIAL1 + cSDEntry - 1, szName ); + AmpersandCompensate( szName, szTemp ); + + SetDlgItemText ( + hwnd, + IDD_SD1SPEEDDIAL1 + cSDEntry - 1, + (LPCSTR) szTemp + ); + + } + + // for the edit speed dial dialog + // limit the lengths of text + SendDlgItemMessage ( + hwnd, + IDD_SD1EDITNAME, + EM_LIMITTEXT, + (WPARAM)(TAPIMAXCALLEDPARTYSIZE - 1), + 0 + ); + + SendDlgItemMessage ( + hwnd, + IDD_SD1EDITNUMBER, + EM_LIMITTEXT, + (WPARAM)(TAPIMAXDESTADDRESSSIZE - 1), + 0 + ); + + // select the first empty button + // nothing empty, then edit #1 + if ( -1 == idFirstEmpty ) + { + nCurrentSpeedDial = 1; + SetDlgItemText( + hwnd, + IDD_SD1EDITNAME, + (LPCSTR) szSDName[ 1 ] + ); + + SetDlgItemText( + hwnd, + IDD_SD1EDITNUMBER, + (LPCSTR) gszSDNumber[ 1 ] + ); + } + else + { + nCurrentSpeedDial = idFirstEmpty; + } + + SetFocus( GetDlgItem( hwnd, IDD_SD1EDITNAME ) ); + return FALSE; + } + + case WM_COMMAND: + { + char szName[TAPIMAXCALLEDPARTYSIZE]; + char szTemp[ TAPIMAXCALLEDPARTYSIZE ]; + + switch( LOWORD( (DWORD) wParam ) ) + { + case IDOK: + { + DWORD cSDEntry; + char szFieldName[MAXBUFSIZE]; + + // save new speed dial settings + for ( cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry ) + { + wsprintf(szFieldName, "Name%d", cSDEntry); + WritePrivateProfileString ( + "Speed Dial Settings", + szFieldName, + szSDName [cSDEntry], + gszINIfilename + ); + + wsprintf(szFieldName, "Number%d", cSDEntry); + WritePrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszSDNumber[cSDEntry], + gszINIfilename + ); + + // set the text for the corresponding + // main window button + if ( szSDName[ cSDEntry ][ 0 ] == '\0' ) + { + lstrcpy( szName, gszSDNumber[ cSDEntry ] ); + } + else + { + lstrcpy( szName, szSDName[ cSDEntry ] ); + } + + FitTextToButton( + ghWndMain, + IDD_DSPEEDDIAL1 + cSDEntry - 1, + szName + ); + + AmpersandCompensate( szName, szTemp ); + SetDlgItemText ( + ghWndMain, + IDD_DSPEEDDIAL1 + cSDEntry - 1, + (LPCSTR) szTemp + ); + } + + EndDialog(hwnd, TRUE); + return TRUE; + } + + case IDCANCEL: + EndDialog(hwnd, FALSE); + return TRUE; + + case IDD_SD1SPEEDDIAL1: + case IDD_SD1SPEEDDIAL2: + case IDD_SD1SPEEDDIAL3: + case IDD_SD1SPEEDDIAL4: + case IDD_SD1SPEEDDIAL5: + case IDD_SD1SPEEDDIAL6: + case IDD_SD1SPEEDDIAL7: + case IDD_SD1SPEEDDIAL8: + + nCurrentSpeedDial = LOWORD( (DWORD) wParam ) - IDD_SD1SPEEDDIAL1 + 1; + + SetDlgItemText ( + hwnd, + IDD_SD1EDITNAME, + szSDName [ nCurrentSpeedDial ] + ); + SetDlgItemText ( + hwnd, + IDD_SD1EDITNUMBER, + gszSDNumber[nCurrentSpeedDial] + ); + + SetFocus( GetDlgItem( hwnd, IDD_SD1EDITNAME ) ); + SendDlgItemMessage( + hwnd, + IDD_SD1EDITNAME, + EM_SETSEL, + 0, + MAKELPARAM(0, -1) + ); + break; + + case IDD_SD1EDITNAME: + if ( HIWORD( wParam ) == EN_CHANGE ) + { + + GetDlgItemText ( + hwnd, + IDD_SD1EDITNAME, + szName, + TAPIMAXCALLEDPARTYSIZE + ); + + // if there is no name, label the button with + // the number + if ( szName[ 0 ] == '\0' ) + { + szSDName[ nCurrentSpeedDial ][ 0 ] = '\0'; + lstrcpy( szName, gszSDNumber[ nCurrentSpeedDial ] ); + } + else + { + lstrcpy( szSDName[ nCurrentSpeedDial ], szName ); + } + + FitTextToButton ( + hwnd, + IDD_SD1SPEEDDIAL1 + nCurrentSpeedDial - 1, + szName + ); + AmpersandCompensate( szName, szTemp ); + + SetDlgItemText ( + hwnd, + IDD_SD1SPEEDDIAL1 + nCurrentSpeedDial - 1, + szTemp + ); + } + break; + + case IDD_SD1EDITNUMBER: + if ( HIWORD( wParam ) == EN_CHANGE ) + { + GetDlgItemText ( + hwnd, + IDD_SD1EDITNUMBER, + gszSDNumber[nCurrentSpeedDial], + TAPIMAXDESTADDRESSSIZE + ); + + if ( gszSDNumber[ nCurrentSpeedDial ][ 0 ] == '\0' ) + { + GetDlgItemText ( + hwnd, + IDD_SD1EDITNAME, + szName, + TAPIMAXDESTADDRESSSIZE + ); + + if ( szName[ 0 ] == '\0' ) + { + SetDlgItemText ( + hwnd, + IDD_SD1SPEEDDIAL1 + nCurrentSpeedDial - 1, + szName + ); + + } + } + } + break; + } // switch(LOWORD((DWORD)wParam)) + break; + + } // case WM_COMMAND: + + default: + ; + + } // switch(msg) + + return FALSE; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK SpeedDial2Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static DWORD nCurrentSpeedDial; + + static const DWORD aMenuHelpIDs[] = + { + IDOK, IDH_DIALER_SPEED_SAVE, + IDD_SD2SAVEANDDIAL, IDH_DIALER_SPEED_SAVE_DIAL, + IDD_SD2TEXTNAME, IDH_DIALER_SPEED_NAME, + IDD_SD2EDITNAME, IDH_DIALER_SPEED_NAME, + IDD_SD2TEXTNUMBER, IDH_DIALER_SPEED_NUMBER, + IDD_SD2EDITNUMBER, IDH_DIALER_SPEED_NUMBER, + 0, 0 + }; + + switch(msg) + { + case WM_HELP: + // processes clicks on controls when + // context mode help is selected + WinHelp ( + ((LPHELPINFO)lParam)->hItemHandle, + gszHELPfilename, + HELP_WM_HELP, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_CONTEXTMENU: + // processes right-clicks on controls + WinHelp ( + (HWND)wParam, + gszHELPfilename, + HELP_CONTEXTMENU, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_INITDIALOG: + { + char szFieldName [MAXBUFSIZE]; + char szName [TAPIMAXCALLEDPARTYSIZE]; + + nCurrentSpeedDial = LOWORD( lParam ) - IDD_DSPEEDDIAL1 + 1; + + // retrieve speed dial button info + wsprintf(szFieldName, "Name%d", nCurrentSpeedDial); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + szName, + TAPIMAXCALLEDPARTYSIZE - 1, + gszINIfilename + ); + SetDlgItemText ( + hwnd, + IDD_SD2EDITNAME, + szName + ); + + SetDlgItemText ( + hwnd, + IDD_SD2EDITNUMBER, + gszSDNumber[nCurrentSpeedDial] + ); + + // limit the lengths of the texts + SendDlgItemMessage ( + hwnd, + IDD_SD2EDITNAME, + EM_LIMITTEXT, + (WPARAM)(TAPIMAXCALLEDPARTYSIZE - 1), + 0 + ); + + SendDlgItemMessage ( + hwnd, + IDD_SD2EDITNUMBER, + EM_LIMITTEXT, + (WPARAM)(TAPIMAXDESTADDRESSSIZE - 1), + 0 + ); + + + SetFocus( GetDlgItem( hwnd, IDD_SD2EDITNAME ) ); + SendDlgItemMessage ( + hwnd, + IDD_SD2EDITNAME, + EM_SETSEL, + 0, + MAKELPARAM(0, -1) + ); + + return FALSE; + } + + case WM_COMMAND: + { + char szName[ TAPIMAXCALLEDPARTYSIZE ]; + char szTemp[ TAPIMAXCALLEDPARTYSIZE ]; + char szFieldName[MAXBUFSIZE]; + + switch ( LOWORD( (DWORD) wParam ) ) + { + case IDOK: + case IDD_SD2SAVEANDDIAL: + { + GetDlgItemText ( + hwnd, + IDD_SD2EDITNAME, + (LPTSTR) szName, + TAPIMAXCALLEDPARTYSIZE + ); + + GetDlgItemText ( + hwnd, + IDD_SD2EDITNUMBER, + (LPTSTR) gszSDNumber[nCurrentSpeedDial], + TAPIMAXCALLEDPARTYSIZE + ); + + wsprintf ( szFieldName, "Name%d", nCurrentSpeedDial ); + + WritePrivateProfileString ( + "Speed Dial Settings", + szFieldName, + szName, + gszINIfilename + ); + + wsprintf ( szFieldName, "Number%d", nCurrentSpeedDial ); + WritePrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszSDNumber[nCurrentSpeedDial], + gszINIfilename + ); + + // update main window buttons + // is only number has been entered, label button with it. + if ( szName[ 0 ] == '\0' ) + { + lstrcpy( szName, gszSDNumber[ nCurrentSpeedDial ] ); + } + + FitTextToButton ( + ghWndMain, + IDD_DSPEEDDIAL1 + nCurrentSpeedDial - 1, + (LPSTR) szName + ); + + AmpersandCompensate( szName, szTemp ); + + SetDlgItemText ( + ghWndMain, + IDD_DSPEEDDIAL1 + nCurrentSpeedDial - 1, + (LPCSTR)szTemp + ); + + // if save and dial, then post dial message to main window + if ( LOWORD( (DWORD) wParam ) == IDD_SD2SAVEANDDIAL ) + { + PostMessage ( + ghWndMain, + WM_COMMAND, + MAKEWPARAM ( + nCurrentSpeedDial + IDD_DSPEEDDIAL1 - 1, + BN_CLICKED + ), + (LPARAM) GetDlgItem ( + ghWndMain, + nCurrentSpeedDial + IDD_DSPEEDDIAL1 - 1 + ) + ); + } + EndDialog(hwnd, TRUE); + return TRUE; + } + + case IDCANCEL: + EndDialog(hwnd, FALSE); + return TRUE; + + case IDD_SD2EDITNAME: + case IDD_SD2EDITNUMBER: + if ( HIWORD( wParam ) == EN_CHANGE) + { + EnableWindow ( + GetDlgItem( hwnd, IDD_SD2SAVEANDDIAL ), + GetWindowTextLength ( GetDlgItem( hwnd, IDD_SD2EDITNUMBER ) ) > 0 + ); + } + break; + + } // switch(LOWORD((DWORD)wParam)) + break; + } + + + default: + ; + + } // switch(msg) + + return FALSE; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID CALLBACK +tapiCallback ( + DWORD hDevice, + DWORD dwMsg, + DWORD dwCBInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3 + ) +{ + switch (dwMsg) + { + INT errCode; + + case LINE_ADDRESSSTATE: + break; + + case LINE_CALLINFO: + break; + + case LINE_CALLSTATE: + if ( (HCALL)hDevice != ghCall ) + return; + + switch ( dwParam1 ) // new state + { + case LINECALLSTATE_IDLE: + + // tell "Dialing" window to terminate + if ( ghWndDialing ) + { + SendMessage ( + ghWndDialing, + WM_COMMAND, + MAKEWPARAM( IDOK, 0 ), + 0 + ); + } + + // tapi call cleanup + if ( !gfMakeCallReplyPending && ghCall ) + { + if ( ( errCode = lineDeallocateCall( ghCall ) ) < 0 ) + { + errString ( ghWndMain, errCode, MB_ICONSTOP | MB_OK ); + } + ghCall = NULL; + } + DialerLineClose(); + gfCurrentLineAvail = TRUE; + + // update main window + DisableDialButtons( FALSE ); + break; + + case LINECALLSTATE_BUSY: + tapiCallback ( + hDevice, + dwMsg, + dwCBInstance, + LINECALLSTATE_DISCONNECTED, + LINEDISCONNECTMODE_BUSY, + dwParam3 + ); + break; + + case LINECALLSTATE_SPECIALINFO: + tapiCallback ( + hDevice, + dwMsg, + dwCBInstance, + LINECALLSTATE_DISCONNECTED, + LINEDISCONNECTMODE_UNREACHABLE, + dwParam3 + ); + break; + + case LINECALLSTATE_DISCONNECTED: + { + BOOL fCallOK; + DWORD LineDisconnectMode; + + + if ( dwParam2 == 0 ) + LineDisconnectMode = LINEDISCONNECTMODE_NORMAL; + else + LineDisconnectMode = dwParam2; + + fCallOK = ( LineDisconnectMode == LINEDISCONNECTMODE_NORMAL || + LineDisconnectMode == LINEDISCONNECTMODE_UNKNOWN || + LineDisconnectMode == LINEDISCONNECTMODE_PICKUP || + LineDisconnectMode == LINEDISCONNECTMODE_FORWARDED || + LineDisconnectMode == LINEDISCONNECTMODE_UNAVAIL + ); + + + if ( !gfMakeCallReplyPending && ghCall ) + { + //gfDropping = TRUE; + if ( ( gDropCallRequestID = lineDrop ( ghCall, NULL, 0 ) ) < 0 ) + { + errString ( ghWndMain, gDropCallRequestID, MB_ICONSTOP | MB_OK ); + } + } + + if ( !fCallOK ) + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CALLFAILED), + ghWndMain, + (DLGPROC)LineInUseProc, + LineDisconnectMode + ); + break; + } + } + break; + + + case LINE_CLOSE: + if ( gCurrentLineInfo.hLine == (HLINE)hDevice ) + { + errString(ghWndMain, ERR_LINECLOSE, MB_ICONEXCLAMATION | MB_OK ); + gCurrentLineInfo.hLine = NULL; + gfCurrentLineAvail = FALSE; + DisableDialButtons(FALSE); + } + break; + + case LINE_CREATE: + // dwParam1 is the new device's ID + if ( dwParam1 >= gnAvailDevices ) + { + DWORD* gnAddrTemp; + DWORD iLine; + LINEINFO LineInfo; + + // we record new device's address count. + + // we are assuming here that we're just adding a new + // line and it's sequential and it's the last one + + gnAvailDevices = dwParam1 + 1; + + gnAddrTemp = (DWORD *) DialerAlloc ( sizeof(DWORD) * (int)(gnAvailDevices) ); + + for ( iLine = 0; iLine < (gnAvailDevices-1); ++iLine ) + gnAddrTemp[iLine] = gnAddr[iLine]; + + DialerFree( gnAddr ); + + // we have effectively added one more + // space in the gnAddr array + gnAddr = gnAddrTemp; + + if ( GetLineInfo( dwParam1, &LineInfo ) != ERR_NONE ) + break; + + gnAddr[dwParam1] = LineInfo.nAddr; + } + break; + + case LINE_DEVSPECIFIC: + break; + + case LINE_DEVSPECIFICFEATURE: + break; + + case LINE_GATHERDIGITS: + break; + + case LINE_GENERATE: + break; + + case LINE_LINEDEVSTATE: + if ( dwParam1 & LINEDEVSTATE_REINIT ) + { + if(dwParam2 != 0) + { + // this is another msg translated into REINIT + tapiCallback( hDevice, dwParam2, dwCBInstance, dwParam3, 0, 0 ); + } + else + { + // Re-initialize TAPI + gfNeedToReinit = TRUE; + } + } + + if ( dwParam1 & LINEDEVSTATE_REMOVED ) + { + DialerLineClose(); + tapiCallback(hDevice, LINE_CLOSE, dwCBInstance, 0, 0, 0); // is this needed? + } + break; + + case LINE_MONITORDIGITS: + break; + + case LINE_MONITORMEDIA: + break; + + case LINE_MONITORTONE: + break; + + // async reply from lineMakeCall() or lineDrop() + case LINE_REPLY: + + // reply for lineMakeCall + if ( (LONG) dwParam1 == gMakeCallRequestID ) + { + // error on make call + if ( dwParam2 != ERR_NONE ) + { + // Get rid of the Dialing Dialog box if it's up + if ( ghWndDialing ) + { + SendMessage( + ghWndDialing, + WM_COMMAND, + MAKEWPARAM(IDOK,0), + 0 + ); + } + + if ( dwParam2 == LINEERR_CALLUNAVAIL ) + { + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CALLFAILED), + ghWndMain, + (DLGPROC)LineInUseProc, + 0 + ); + } + else + { + errString ( ghWndMain, dwParam2, MB_ICONEXCLAMATION | MB_OK ); + } + + ghCall = NULL; + DialerLineClose(); + gfCurrentLineAvail = TRUE; + } + + gfMakeCallReplyPending = FALSE; + } + + // reply from lineDrop() + if ( (LONG) dwParam1 == gDropCallRequestID ) + { + //gfDropping = FALSE; + + // tell "Dialing" window to terminate + if ( ghWndDialing ) + { + SendMessage ( + ghWndDialing, + WM_COMMAND, + MAKEWPARAM( IDOK,0 ), + 0 + ); + } + + // tapi call cleanup + if ( dwParam2 == ERR_NONE ) + { + if ( !gfMakeCallReplyPending && ghCall ) + { + if ( ( errCode = lineDeallocateCall( ghCall ) ) < 0 ) + { + errString ( ghWndMain, errCode, MB_ICONSTOP | MB_OK ); + } + ghCall = NULL; + } + } + DialerLineClose (); + gfCurrentLineAvail = TRUE; + } + + break; + + case LINE_REQUEST: + // Simple TAPI request + if ( dwParam1 == LINEREQUESTMODE_MAKECALL ) + { + gfCallRequest = TRUE; + } + break; + } +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL InitializeLineBox(HWND hwndLineBox) +{ + + DWORD iLine, iItem, iItemCurrent = (DWORD)-1; + DWORD errCode; + + LPLINEINFO lpLineInfo = NULL; + + // allocate buffer for storing LINEINFO for all of + // the available lines. Always allocate space for + // at least one line + if ( gnAvailDevices == 0 ) + { + lpLineInfo = (LPLINEINFO) DialerAlloc( sizeof(LINEINFO) ); + } + else + { + lpLineInfo = (LPLINEINFO) DialerAlloc ( sizeof(LINEINFO) * (int)gnAvailDevices ); + } + + // if no space was set aside... + if ( lpLineInfo == NULL ) + return LINEERR_NOMEM; + + // fill lpLineInfo[] and open each line + for ( iLine = 0; iLine < gnAvailDevices; ++iLine ) + { + // skip remaining processing for this line if it didn't open + if ( GetLineInfo( iLine, &lpLineInfo[iLine] ) != ERR_NONE ) + { + continue; + } + + iItem = SendMessage ( + hwndLineBox, + CB_ADDSTRING, + 0, + (LPARAM)(LPCSTR)(lpLineInfo[iLine].szLineName) + ); + + // error, bail out. + if ( iItem == CB_ERR || iItem == CB_ERRSPACE ) + { + if (lpLineInfo) + { + DialerFree(lpLineInfo); + } + + return FALSE; + } + + errCode = SendMessage ( + hwndLineBox, + CB_SETITEMDATA, + (WPARAM)iItem, + (LPARAM)iLine + ); + + if ( iLine == giCurrentLine ) + { + iItemCurrent = iItem; + } + else if ( iItemCurrent != -1 && iItem <= iItemCurrent ) + { + // if the item we are putting is before the + // "current" item, we must increment iItemCurrent + // to reflect that something is being placed before + // it, due to sorting + ++iItemCurrent; + } + } + + if ( iItemCurrent == (DWORD)-1 ) + iItemCurrent = 0; + + if ( SendMessage( hwndLineBox, CB_GETCOUNT, 0, 0) != 0 ) + { + SendMessage( hwndLineBox, CB_SETCURSEL, (WPARAM)iItemCurrent, 0 ); + return TRUE; + } + + DialerFree(lpLineInfo); + return FALSE; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL InitializeAddressBox( HWND hwndLineBox, HWND hwndAddressBox ) +{ + DWORD errCode; + DWORD iAddress, iItem, iItemCurrent = (DWORD)-1; + DWORD iLineBoxCurrent; + LPSTR pszAddressName; + + if ( SendMessage( hwndLineBox, CB_GETCOUNT, 0, 0 ) == 0 ) + { + return FALSE; + } + + // select current entry in line box + iLineBoxCurrent = SendMessage ( + hwndLineBox, + CB_GETITEMDATA, + SendMessage( hwndLineBox, CB_GETCURSEL, 0, 0 ), + 0 + ); + // empty address list box + SendMessage ( hwndAddressBox, CB_RESETCONTENT, 0, 0); + + // get all the address for this line + for ( iAddress = 0; iAddress < gnAddr[iLineBoxCurrent]; ++iAddress ) + { + pszAddressName = GetAddressName( iLineBoxCurrent, iAddress ); + + // if this address if fails, try the next one + if ( !pszAddressName ) + continue; + + iItem = SendMessage ( + hwndAddressBox, + CB_ADDSTRING, + 0, + (LPARAM) (LPCSTR) (pszAddressName) + ); + + // error, bail out + if ( iItem == CB_ERR || iItem == CB_ERRSPACE ) + return FALSE; + + errCode = SendMessage ( + hwndAddressBox, + CB_SETITEMDATA, + (WPARAM) iItem, + (LPARAM) iAddress + ); + + if ( iLineBoxCurrent == giCurrentLine ) + { + if(iAddress == giCurrentAddress) + { + iItemCurrent = iItem; + } + else + { + // if the item we are putting is before the + // "current" item, we must increment iItemCur + // to reflect that something is being placed + // before it, due to sorting + if ( iItemCurrent != -1 && iItem <= iItemCurrent ) + { + ++iItemCurrent; + } + } + } + + DialerFree( pszAddressName ); + } + + if ( iLineBoxCurrent != giCurrentLine ) + { + // if we're not looking at the current line + // then highlight address 0 + iItemCurrent = 0; + } + + SendMessage ( + hwndAddressBox, + CB_SETCURSEL, + iItemCurrent, + 0 + ); + return TRUE; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID ManageAssistedTelephony(VOID) +{ + DWORD errCode; + LPLINEREQMAKECALL lpRequestBuffer; + + lpRequestBuffer = (LPLINEREQMAKECALL) DialerAlloc( sizeof( LINEREQMAKECALL ) ); + if ( !lpRequestBuffer ) + { + goto error; + } + + // bring window to front + SetForegroundWindow(ghWndMain); + + // get next queued request. + errCode = lineGetRequest ( + ghLineApp, + LINEREQUESTMODE_MAKECALL, + lpRequestBuffer + + ); + if ( errCode ) + { + // if no more call requests pending, reset flag. + if ( errCode == LINEERR_NOREQUEST ) + { + gfCallRequest = FALSE; + } + else + { + errString ( ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK ); + } + goto error; + } + + + // if a line has not been selected + if ( giCurrentLine == (DWORD)-1 ) + { + if (!DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CONNECTUSING), + ghWndMain, + (DLGPROC) ConnectUsingProc, + INVALID_LINE + )) + { + // failed to get a line + goto error; + } + } + + // make the reuested call. + InitiateCall ( + lpRequestBuffer->szDestAddress, + lpRequestBuffer->szCalledParty + ); + +error : + if ( lpRequestBuffer ) + { + DialerFree( lpRequestBuffer ); + } + return; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID DialerLineClose() +{ + DWORD errCode; + + if ( gCurrentLineInfo.hLine ) + { + if ( errCode = lineClose ( gCurrentLineInfo.hLine ) ) + { + errString ( ghWndMain, errCode, MB_ICONSTOP | MB_OK ); + } + gCurrentLineInfo.hLine = NULL; + } + + + // re-initialize TAPI if it needs to be re-initialized + if ( gfNeedToReinit ) + { + CloseTAPI(); + + errCode = InitializeTAPI(); + if(errCode) + { + errString(ghWndMain, errCode, MB_APPLMODAL | MB_ICONEXCLAMATION ); + DialerCleanup(); // terminate program if we can't init + return; + } + + errCode = lineRegisterRequestRecipient ( + ghLineApp, + 0, + LINEREQUESTMODE_MAKECALL, + TRUE + ); + if (errCode) + { + errString(ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK ); + } + + gfNeedToReinit = FALSE; + } +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +int errString( HWND hWndOwner, UINT errCode, UINT uFlags ) +{ + PTSTR ptStrTitle; + PTSTR ptStrError; + int nResult; + BOOL bDefault = FALSE; + + ptStrTitle = DialerAlloc( MAXBUFSIZE ); + if ( NULL == ptStrTitle ) + { + // Now, _this_ is a problem. + return 0; + } + + ptStrError = DialerAlloc( MAXBUFSIZE ); + if ( NULL == ptStrError ) + { + // Now, _this_ is a problem. + DialerFree( ptStrTitle); + return 0; + } + + switch(errCode) + { + case ERR_NOLINES: + errCode = ikszErrNoVoiceLine; + break; + + case ERR_NOVOICELINE: + errCode = ikszErrNoVoiceLine; + break; + + case ERR_LINECLOSE: + errCode = ikszErrLineClose; + break; + + case ERR_911WARN: + errCode = ikszWarningFor911; + break; + + case ERR_NEWDEFAULT: + errCode = ikszWarningNewDefault; + break; + + case LINEERR_NODRIVER: + errCode = ikszErrLineInitNoDriver; + break; + + case LINEERR_NODEVICE: + errCode = ikszErrLineInitNoDevice; + break; + + case LINEERR_INIFILECORRUPT: + errCode = ikszErrLineInitBadIniFile ; + break; + + case LINEERR_NOMEM: + errCode = ikszErrOOM; + break; + + case LINEERR_INCOMPATIBLEAPIVERSION: + errCode = ikszErrLineInitWrongDrivers ; + break; + + case LINEERR_OPERATIONFAILED: + errCode = ikszErrTAPI; + break; + + case LINEERR_INVALADDRESS: + errCode = ikszErrInvalAddress; + break; + + case LINEERR_ADDRESSBLOCKED: + errCode = ikszErrAddrBlocked; + break; + + case LINEERR_BILLINGREJECTED: + errCode = ikszErrBillingRejected; + break; + + case LINEERR_RESOURCEUNAVAIL: + case LINEERR_ALLOCATED: + case LINEERR_INUSE: + errCode = ikszErrResUnavail; + break; + + case LINEERR_NOMULTIPLEINSTANCE: + errCode = ikszErrNoMultipleInstance; + break; + + case LINEERR_INVALCALLSTATE: + errCode = ikszErrInvalCallState; + break; + + case LINEERR_INVALCOUNTRYCODE: + errCode = ikszErrInvalidCountryCode; + break; + + default: + bDefault = TRUE; + break; + + } + + + if (bDefault) + { + // if using default error, get TAPI's + // error message from FormatError() + if (!FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, + (LPCVOID)GetModuleHandle(TEXT("TAPI32.DLL")), + (DWORD)TAPIERROR_FORMATMESSAGE(errCode), + 0, + (LPTSTR)ptStrError, + MAXBUFSIZE, + NULL)) + { + // if this fails, fall back on default + LoadString( ghInst, ikszErrDefault, ptStrError, MAXBUFSIZE); + } + + } + else // not the default error message + { + + if ( 0 == LoadString( ghInst, errCode, ptStrError, MAXBUFSIZE ) ) + { +#if DBG + TCHAR buf[200]; + wsprintf( buf, "Cannot load string: hinst:0x%08lx errcode: %ld", (DWORD)ghInst,(DWORD)errCode); + OutputDebugString( buf ); + MessageBox( NULL, buf, "Dialer", MB_OK); +#endif + + LoadString( ghInst, ikszErrDefault, ptStrError, MAXBUFSIZE ); + } + } + + LoadString( ghInst, ikszWarningTitle, ptStrTitle, MAXBUFSIZE ); + + nResult = MessageBox( hWndOwner, ptStrError, ptStrTitle, uFlags ); + + + DialerFree( ptStrTitle ); + DialerFree( ptStrError ); + + + return nResult; +} + + +/* + * Name : + * FitTextToButton + * + * Arguements : + * hDlg handle for the dialog in which this button is embedded + * nButtonID button id of this button + * szName Name to fit on the button. Max size TAPIMAXCALLEDPARTYSIZE + * + * Return : + * None + * + * Comments : + * Function first checks to see if the button text specified fits in the + * button. If it does not it truncates it appropriately and adds trailing + * ellipses. + */ +VOID FitTextToButton ( HWND hDlg, INT nButtonID, LPSTR szName ) +{ + + HDC hDC; + HFONT hFont, hOldFont; + HWND hWnd; + + do + { + // calculate number of chars. that can fit on + // the button + int nLen; + RECT rect; + SIZE size; + POINT pt; + char buf [TAPIMAXCALLEDPARTYSIZE + 1]; + + // get button dimensions + hWnd = GetDlgItem( hDlg, nButtonID ); + if ( hWnd == NULL ) + break; + + if ( !GetClientRect( hWnd, &rect ) ) + break; + + // get character dimensions + hDC = GetDC( hWnd ); + if ( hDC == NULL ) + break; + + hFont = (HFONT) SendMessage( hWnd, WM_GETFONT, 0, 0 ); + if ( hFont == NULL ) + hOldFont = SelectObject( hDC, GetStockObject( SYSTEM_FONT ) ); + else + hOldFont = SelectObject( hDC, hFont ); + + // add an extra char at the end to compensate for + // leading space, + lstrcpy ( buf, szName ); + nLen = lstrlen( buf ); + buf [ nLen ] = 'X'; + buf [ nLen + 1 ] = '\0'; + + if ( !GetTextExtentPoint32( hDC, buf, nLen + 1, &size ) ) + break; + + pt.x = size.cx; + if ( !LPtoDP( hDC, &pt, 1 ) ) + break; + + // check if name fits on button + if ( pt.x > rect.right ) + { + // find how much of the name fits + int i = 0; + + nLen = lstrlen( szName ); + for ( i = 0; i < nLen; i++ ) + { + buf[ i ] = szName[ i ]; + // an extra char is stuffed to compensate for the + // leading space left by the left alignment + buf [ i + 1 ] = 'X'; + buf [ i + 2 ] = '\0'; + + // break out in cases of error condition + if ( !GetTextExtentPoint32( hDC, buf, i + 2, &size ) ) + { + i = nLen; + break; + } + + pt.x = size.cx; + if ( !LPtoDP( hDC, &pt, 1 ) ) + { + i = nLen; + break; + } + + if ( pt.x > rect.right ) + break; + } + + // error + if ( i >= nLen ) + break; + + // name is too long. truncate and add ellipses + szName [i - 3] = '\0'; + lstrcat( szName, "..." ); + } + + } while( FALSE ); + + if ( hDC ) + { + SelectObject( hDC, hOldFont ); + ReleaseDC( hWnd, hDC ); + } + + return; +} + + + +/* + * Name : + * Is911 + * + * Arguements : + * lpTransOut - Translated address contained the dialable string + * + * Returns + * TRUE - If number to be dialed (in the US) is prefixed by 911 + * FALSE - Otherwise + * + * Comments + * + */ +BOOL Is911 ( LPLINETRANSLATEOUTPUT lpTransOut ) +{ + + DWORD i = 0, j = 0; + LPSTR lpDialDigits = (LPSTR)lpTransOut + lpTransOut-> dwDialableStringOffset; + char sz3Pref [ 4 ] = ""; + + + // if this is not the US + if ( lpTransOut-> dwCurrentCountry != 1 ) + return FALSE; + + // skip non digit characters and extract + // the first 3 digits in the dialable number + for ( i = 0, j = 0; i < lpTransOut-> dwDialableStringSize ; i++ ) + { + if ( ISDIGIT( lpDialDigits[i] ) ) + { + sz3Pref[ j++ ] = lpDialDigits [ i ]; + sz3Pref[ j ] = '\0'; + if ( j == 3 ) + break; + } + } + + if ( !lstrcmp( sz3Pref, "911" ) ) + { + return TRUE; + } + + return FALSE; +} + + +/* + * Name : + * MakeCanonicalNumber + * + * Arguements : + * szNumber Number to convert into canonical form. Max size TAPIMAXDESTADDRESSSIZE + * szCanNumber Canonical representation of number specified in szNumber + * + * Return : + * TRUE If the conversion was successful. + * FALSE otherwise + * + * Comments : + * Function first checks if given number is already in canonical form. + * If it is, it returns. If it is not, then it performs the conversion. + */ + +BOOL MakeCanonicalNumber ( LPCSTR szNumber, LPSTR szCanNumber ) +{ + char szDigits [ TAPIMAXDESTADDRESSSIZE ]; + char szPref [ TAPIMAXDESTADDRESSSIZE ]; + + BOOL bRes = FALSE; + + INT errCode = -1; + INT nLenPref, nLenDigits, cPos, i; + + DWORD dwSize = 0; + DWORD dwInd = 0; + + LPLINETRANSLATEOUTPUT lpTransOut = NULL; + LPLINETRANSLATECAPS lpTransCaps = NULL; + + + dwSize = sizeof ( LINETRANSLATEOUTPUT ); + do + { + lpTransOut = ( LPLINETRANSLATEOUTPUT ) DialerAlloc ( dwSize ); + if ( !lpTransOut ) + { + errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK ); + goto error; + } + + lpTransOut-> dwTotalSize = dwSize; + errCode = lineTranslateAddress ( + ghLineApp, + giCurrentLine, + gCurrentLineInfo.dwAPIVersion, + szNumber, + 0, + 0, + lpTransOut + ); + if ( errCode ) + { + goto error; + } + + if ( lpTransOut-> dwNeededSize <= lpTransOut-> dwTotalSize ) + break; + + dwSize = lpTransOut-> dwNeededSize; + DialerFree( lpTransOut ); + + } while( TRUE ); + + + // check if input number is already in + // canonical form. + if ( lpTransOut-> dwTranslateResults & LINETRANSLATERESULT_CANONICAL ) + goto error; + + // ensure country is the USA. + if ( lpTransOut-> dwCurrentCountry != 1 ) + goto error; + + + // Extract the digits from given string + // allowed formatting characters that are ignored are + // space, (, ), -, . + // presence of other characters will render the string invalid. + + // find the prefix of the address upto the | mark. + // the rest of the string can be ignored + nLenPref = strcspn ( szNumber, "|" ); + strncpy( szPref, szNumber, nLenPref ); + szPref[ nLenPref ] = '\0'; + + // if string is not composed entirely of digits + // and allowable formating characters, quit conversion + if ( strspn( szPref, " 0123456789()-." ) != (size_t) nLenPref ) + goto error; + + // collect digits ignoring formating characters. + szDigits[ 0 ] = '\0'; + for ( i = 0, nLenDigits = 0; i < nLenPref; i++ ) + { + if ( ISDIGIT( szNumber[ i ] ) ) + { + szDigits[ nLenDigits++ ] = szNumber[ i ]; + } + } + szDigits[ nLenDigits ] = '\0'; + + // if "internal" number + if ( nLenDigits < LOCAL_NUMBER ) + goto error; + + switch ( nLenDigits ) + { + // Local number ( 7 digits) preceeded by a 0/1 + // Strip leading 0/1 and treat as a local number + case EXTENDED_LOCAL_NUMBER: + if ( szDigits[ 0 ] == '0' || szDigits[ 0 ] == '1' ) + { + nLenDigits--; + memmove( szDigits, &(szDigits[1]), nLenDigits ); + szDigits[ nLenDigits ] = '\0'; + + cPos = strcspn( szPref, "01" ); + nLenPref--; + memmove( &(szPref[ cPos ]), &(szPref[ cPos + 1 ]), nLenPref - cPos ); + szPref[ nLenPref ] = '\0'; + } + else + { + goto error; + } + + case LOCAL_NUMBER : + { + LPLINELOCATIONENTRY lpLocLst; + + // if leading digit is 0 or 1, it is + // illegal in the US + if ( szDigits[ 0 ] == '0' || szDigits[ 0 ] == '1' ) + { + goto error; + } + + // get area code nformation for local number + dwSize = sizeof( LINETRANSLATECAPS ); + do + { + lpTransCaps = (LPLINETRANSLATECAPS) DialerAlloc( dwSize ); + if ( !lpTransCaps ) + { + errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK ); + goto error; + } + + lpTransCaps-> dwTotalSize = dwSize; + errCode = lineGetTranslateCaps ( + ghLineApp, + gCurrentLineInfo.dwAPIVersion, + lpTransCaps + ); + if ( errCode ) + { + errString( ghWndMain, errCode, MB_ICONSTOP | MB_OK ); + goto error; + } + + if ( lpTransCaps-> dwNeededSize <= lpTransCaps-> dwTotalSize ) + { + break; + } + + dwSize = lpTransCaps-> dwNeededSize; + DialerFree( lpTransCaps ); + + } while ( TRUE ); + + // skip entries till you locate information for current location + dwSize = sizeof( LINELOCATIONENTRY ); + lpLocLst = (LPLINELOCATIONENTRY) ( (LPSTR) lpTransCaps + + lpTransCaps-> dwLocationListOffset ); + + for ( dwInd = 0; dwInd < lpTransCaps-> dwNumLocations ; dwInd++ ) + { + if ( lpLocLst[ dwInd ].dwPermanentLocationID == lpTransCaps-> dwCurrentLocationID ) + break; + } + + // current location no found ????? + // login error + if ( dwInd == lpTransCaps-> dwNumLocations ) + { + goto error; + } + + // construct canonical form as + szCanNumber[ 0 ]= '\0'; + lstrcat( szCanNumber, "+1 (" ); + lstrcat( szCanNumber, (LPSTR) lpTransCaps + lpLocLst[ dwInd ].dwCityCodeOffset ); + lstrcat( szCanNumber, ") " ); + lstrcat( szCanNumber, szDigits ); + + cPos = strcspn( szNumber, "|" ); + if ( cPos != lstrlen( szNumber ) ) + { + lstrcat( szCanNumber, &(szNumber[ cPos ]) ); + } + + bRes = TRUE; + break; + } + + case EXTENDED_LONG_DISTANCE_NUMBER: + { + // Long distance number ( 10 digits) preceeded by a 0/1 + // Strip leading 0/1 and treat as a long distance number + if ( szDigits[ 0 ] == '0' || szDigits[ 0 ] == '1' ) + { + nLenDigits--; + memmove( szDigits, &(szDigits[1]), nLenDigits ); + szDigits[ nLenDigits ] = '\0'; + + cPos = strcspn( szPref, "01" ); + nLenPref--; + memmove( &(szPref[ cPos ]), &(szPref[ cPos + 1 ]), nLenPref - cPos ); + szPref[ nLenPref ] = '\0'; + } + else + { + goto error; + } + + } + + case LONG_DISTANCE_NUMBER: + { + // if first or fourth digit is 0/1, illegal number + if ( szDigits[ 0 ] == '0' || szDigits[ 0 ] == '1' || + szDigits[ 3 ] == '0' || szDigits[ 3 ] == '1' ) + { + goto error; + } + + szCanNumber[ 0 ] = '\0'; + lstrcat( szCanNumber, "+1 (" ); + strncat( szCanNumber, szDigits, 3 ); + lstrcat( szCanNumber, ") " ); + + lstrcat( szCanNumber, &(szDigits[ 3 ]) ); + + bRes = TRUE; + } + break; + + default : + goto error; + } + +error: + if ( lpTransOut ) + DialerFree( lpTransOut ); + + if ( lpTransCaps ) + DialerFree( lpTransCaps ); + + return bRes; +} + + +/* + * Name : + * AmpersandCompensate + * + * Arguements : + * lpszSrc : Src string containing &s + * lpszDst : Dest string + * + * Return : + * + * Comments : + * Copies string pointed to by lpszSrc to lpszDst character by + * character. If an & is encountered in this process in lpszSrc + * it is copied as && into lpszDst. + * Assumes lpszDst and lpszSrc are of size TAPIMAXCALLEDPARTYSIZE + */ +VOID AmpersandCompensate ( LPCSTR lpszSrc, LPSTR lpszDst ) +{ + // check if the name has an & in it. If so replace + // it with &&. + INT cCnt, cInd; + + for ( cCnt = 0, cInd = 0; + cInd < TAPIMAXCALLEDPARTYSIZE; + cInd++, cCnt++ ) + { + if ( lpszSrc[ cCnt ] == '&' ) + { + lpszDst[ cInd++ ] = '&'; + } + lpszDst[ cInd ] = lpszSrc[ cCnt ]; + + if ( lpszSrc[ cCnt ] == '\0' ) + break; + } + + // make sure string is null terminated. + lpszDst[ TAPIMAXCALLEDPARTYSIZE - 1 ] = '\0'; + + return; +} + + + /* + * Name : + * AmpersandDeCompensate + * + * Arguements : + * lpszSrc : Src string containing &s + * lpszDst : Dest string + * + * Return : + * + * Comments : + * Copies string pointed to by lpszSrc to lpszDst character by + * character. If an && is encountered in this process in lpszSrc + * it is copied as & into lpszDst. + * Assumes lpszDst and lpszSrc are of size TAPIMAXCALLEDPARTYSIZE + */ + VOID AmpersandDeCompensate ( LPCSTR lpszSrc, LPSTR lpszDst ) + { + // check if the name has an & in it. If so replace + // it with &&. + INT cCnt, cInd; + + for ( cCnt = 0, cInd = 0; + cInd < TAPIMAXCALLEDPARTYSIZE; + cInd++, cCnt++ ) + { + if ( ( lpszSrc[ cInd ] == '&' ) && + ( lpszSrc[ cInd + 1 ] == '&' ) ) + { + cInd++; + } + lpszDst[ cCnt ] = lpszSrc[ cInd ] ; + + if ( lpszSrc [ cInd ] == '\0' ) + { + break; + } + } + + lpszDst[ TAPIMAXCALLEDPARTYSIZE - 1 ] = '\0'; + + return; + } diff --git a/private/tapi/dev/apps/dialer/dialer.def b/private/tapi/dev/apps/dialer/dialer.def new file mode 100644 index 000000000..b40ab0af1 --- /dev/null +++ b/private/tapi/dev/apps/dialer/dialer.def @@ -0,0 +1,9 @@ +NAME DIALER +;STUB 'WINSTUB.EXE' +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE +HEAPSIZE 2048 +STACKSIZE 8192 + +EXPORTS + MainWndProc diff --git a/private/tapi/dev/apps/dialer/dialer.h b/private/tapi/dev/apps/dialer/dialer.h new file mode 100644 index 000000000..6f5832862 --- /dev/null +++ b/private/tapi/dev/apps/dialer/dialer.h @@ -0,0 +1,51 @@ +/*++ BUILD Version: 0001 // Increment this if a change has global effects + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + dialer.h + +Abstract: + + Header file for dialer + +Author: + + Dan Knudson (DanKn) 05-Apr-1995 + +Revision History: + + Jeremy Horwitz (t-jereh) 30-May-1995 + +--*/ + + +#define TAPI_VERSION_1_0 0x00010003 +#define TAPI_VERSION_1_4 0x00010004 +#define TAPI_VERSION_2_0 0x00020000 +#define TAPI_CURRENT_VERSION TAPI_VERSION_2_0 + +#include <windows.h> +#include "tapi.h" +#include "resource.h" +#include "dialhelp.h" + + +#define MENU_CHOICE 1 // for Connect Using dialog... +#define INVALID_LINE 2 // if INVALID_LINE, turn off CANCEL + // button and add extra text... + +#define MAXNUMLENGTH 64 +#define MAXBUFSIZE 256 +#define NSPEEDDIALS 8 // Dialer supports 8 configurable speed dial entries. +#define NLASTDIALED 20 // Dialer keeps track of the 20 last dialed numbers. + +#define ERR_NONE 0 +#define ERR_NOVOICELINE 1 +#define ERR_LINECLOSE 2 +#define ERR_NOLINES 3 +#define ERR_911WARN 4 +#define ERR_NEWDEFAULT 5 + +#define itoa(x,y,z) _itoa(x,y,z) diff --git a/private/tapi/dev/apps/dialer/dialer.ico b/private/tapi/dev/apps/dialer/dialer.ico Binary files differnew file mode 100644 index 000000000..44ccbca29 --- /dev/null +++ b/private/tapi/dev/apps/dialer/dialer.ico diff --git a/private/tapi/dev/apps/dialer/dialer.mak b/private/tapi/dev/apps/dialer/dialer.mak new file mode 100644 index 000000000..3c4a04bea --- /dev/null +++ b/private/tapi/dev/apps/dialer/dialer.mak @@ -0,0 +1,389 @@ +# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 +# TARGTYPE "Win32 (MIPS) Application" 0x0501 + +!IF "$(CFG)" == "" +CFG=Win32 (80x86) Debug +!MESSAGE No configuration specified. Defaulting to Win32 (80x86) Debug. +!ENDIF + +!IF "$(CFG)" != "Win32 (80x86) Release" && "$(CFG)" != "Win32 (80x86) Debug" &&\ + "$(CFG)" != "Win32 (MIPS) Debug" && "$(CFG)" != "Win32 (MIPS) Release" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "dialer.mak" CFG="Win32 (80x86) Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Win32 (80x86) Release" (based on "Win32 (x86) Application") +!MESSAGE "Win32 (80x86) Debug" (based on "Win32 (x86) Application") +!MESSAGE "Win32 (MIPS) Debug" (based on "Win32 (MIPS) Application") +!MESSAGE "Win32 (MIPS) Release" (based on "Win32 (MIPS) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "Win32 (MIPS) Debug" + +!IF "$(CFG)" == "Win32 (80x86) Release" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "WinRel" +# PROP BASE Intermediate_Dir "WinRel" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "WinRel" +# PROP Intermediate_Dir "WinRel" +OUTDIR=.\WinRel +INTDIR=.\WinRel + +ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +MTL=MkTypLib.exe +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /W3 /GX /YX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /c +CPP_PROJ=/nologo /W3 /GX /YX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\ + "_MBCS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/ /c +CPP_OBJS=.\WinRel/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"DIALER.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# SUBTRACT BASE BSC32 /Iu +# ADD BSC32 /nologo +# SUBTRACT BSC32 /Iu +BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc" +BSC32_SBRS= \ + $(INTDIR)/DIALER.SBR + +$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib mfc30.lib mfco30.lib mfcd30.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:I386 +# ADD LINK32 tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:I386 +LINK32_FLAGS=tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\ + uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /INCREMENTAL:no\ + /PDB:$(OUTDIR)/"dialer.pdb" /MACHINE:I386 /OUT:$(OUTDIR)/"dialer.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/DIALER.res \ + $(INTDIR)/DIALER.OBJ + +$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Win32 (80x86) Debug" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "WinDebug" +# PROP BASE Intermediate_Dir "WinDebug" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "WinDebug" +# PROP Intermediate_Dir "WinDebug" +OUTDIR=.\WinDebug +INTDIR=.\WinDebug + +ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +MTL=MkTypLib.exe +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /c +CPP_PROJ=/nologo /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D\ + "_MBCS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/\ + /Fd$(OUTDIR)/"dialer.pdb" /c +CPP_OBJS=.\WinDebug/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"DIALER.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# SUBTRACT BASE BSC32 /Iu +# ADD BSC32 /nologo +# SUBTRACT BSC32 /Iu +BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc" +BSC32_SBRS= \ + $(INTDIR)/DIALER.SBR + +$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib mfc30d.lib mfco30d.lib mfcd30d.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:I386 +# ADD LINK32 tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:I386 +LINK32_FLAGS=tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\ + uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /INCREMENTAL:yes\ + /PDB:$(OUTDIR)/"dialer.pdb" /DEBUG /MACHINE:I386 /OUT:$(OUTDIR)/"dialer.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/DIALER.res \ + $(INTDIR)/DIALER.OBJ + +$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Win32 (MIPS) Debug" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 1 +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "WinDebug" +# PROP Intermediate_Dir "WinDebug" +OUTDIR=.\WinDebug +INTDIR=.\WinDebug + +ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +MTL=MkTypLib.exe +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MD /Gt0 /QMOb2000 /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /Gt0 /QMOb2000 /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "WIN32" /FR /c +CPP_PROJ=/nologo /Gt0 /QMOb2000 /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS"\ + /D "_MBCS" /D "WIN32" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/\ + /Fd$(OUTDIR)/"dialer.pdb" /c +CPP_OBJS=.\WinDebug/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"dialer.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# SUBTRACT BASE BSC32 /Iu +# ADD BSC32 /nologo +# SUBTRACT BSC32 /Iu +BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc" +BSC32_SBRS= \ + $(INTDIR)/dialer.sbr + +$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib odbc32.lib mfc30d.lib mfco30d.lib mfcd30d.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:MIPS +# ADD LINK32 version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:MIPS +LINK32_FLAGS=version.lib kernel32.lib user32.lib gdi32.lib winspool.lib\ + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO\ + /SUBSYSTEM:windows /PDB:$(OUTDIR)/"dialer.pdb" /DEBUG /MACHINE:MIPS\ + /OUT:$(OUTDIR)/"dialer.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/dialer.res \ + $(INTDIR)/dialer.obj + +$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Win32 (MIPS) Release" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 0 +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "WinRel" +# PROP Intermediate_Dir "WinRel" +OUTDIR=.\WinRel +INTDIR=.\WinRel + +ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +MTL=MkTypLib.exe +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MD /Gt0 /QMOb2000 /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /Gt0 /QMOb2000 /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "WIN32" /FR /c +CPP_PROJ=/nologo /Gt0 /QMOb2000 /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D\ + "_MBCS" /D "WIN32" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/ /c +CPP_OBJS=.\WinRel/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"dialer.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# SUBTRACT BASE BSC32 /Iu +# ADD BSC32 /nologo +# SUBTRACT BSC32 /Iu +BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc" +BSC32_SBRS= \ + $(INTDIR)/dialer.sbr + +$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib odbc32.lib mfc30.lib mfco30.lib mfcd30.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:MIPS +# ADD LINK32 version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:MIPS +LINK32_FLAGS=version.lib kernel32.lib user32.lib gdi32.lib winspool.lib\ + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO\ + /SUBSYSTEM:windows /PDB:$(OUTDIR)/"dialer.pdb" /MACHINE:MIPS\ + /OUT:$(OUTDIR)/"dialer.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/dialer.res \ + $(INTDIR)/dialer.obj + +$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +################################################################################ +# Begin Group "Source Files" + +################################################################################ +# Begin Source File + +SOURCE=.\DIALER.RC +DEP_DIALE=\ + .\dialer.ico + +!IF "$(CFG)" == "Win32 (80x86) Release" + +$(INTDIR)/DIALER.res : $(SOURCE) $(DEP_DIALE) $(INTDIR) + $(RSC) $(RSC_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 (80x86) Debug" + +$(INTDIR)/DIALER.res : $(SOURCE) $(DEP_DIALE) $(INTDIR) + $(RSC) $(RSC_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 (MIPS) Debug" + +$(INTDIR)/dialer.res : $(SOURCE) $(DEP_GENER) $(INTDIR) + $(RSC) $(RSC_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 (MIPS) Release" + +$(INTDIR)/dialer.res : $(SOURCE) $(DEP_GENER) $(INTDIR) + $(RSC) $(RSC_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DIALER.C +DEP_DIALER=\ + .\DIALER.H\ + ..\..\INC\TAPI.H\ + .\dialhelp.h + +!IF "$(CFG)" == "Win32 (80x86) Release" + +$(INTDIR)/DIALER.OBJ : $(SOURCE) $(DEP_DIALER) $(INTDIR) + +!ELSEIF "$(CFG)" == "Win32 (80x86) Debug" + +$(INTDIR)/DIALER.OBJ : $(SOURCE) $(DEP_DIALER) $(INTDIR) + +!ELSEIF "$(CFG)" == "Win32 (MIPS) Debug" + +$(INTDIR)/dialer.obj : $(SOURCE) $(DEP_GENERI) $(INTDIR) + +!ELSEIF "$(CFG)" == "Win32 (MIPS) Release" + +$(INTDIR)/dialer.obj : $(SOURCE) $(DEP_GENERI) $(INTDIR) + +!ENDIF + +# End Source File +# End Group +# End Project +################################################################################ diff --git a/private/tapi/dev/apps/dialer/dialer.rc b/private/tapi/dev/apps/dialer/dialer.rc new file mode 100644 index 000000000..d1e73947e --- /dev/null +++ b/private/tapi/dev/apps/dialer/dialer.rc @@ -0,0 +1,452 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""windows.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALER DIALOG PRELOAD DISCARDABLE 50, 50, 194, 168 +STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU +CAPTION "Phone Dialer" +MENU IDM_MENU +CLASS "DialerClass" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "",IDD_DRECTSEPARATOR,"Static",SS_ETCHEDHORZ | + WS_DISABLED,0,0,194,1 + LTEXT "&Number to dial:",IDD_DNUMTODIAL,7,7,90,10 + COMBOBOX IDD_DCOMBO,7,21,90,104,CBS_DROPDOWN | CBS_AUTOHSCROLL | + WS_VSCROLL | WS_GROUP | WS_TABSTOP | ES_NOHIDESEL + DEFPUSHBUTTON "&Dial",IDD_DDIAL,7,38,90,14,WS_DISABLED | WS_GROUP + CONTROL "\n1",IDD_DBUTTON1,"Button",BS_OWNERDRAW,14,62,23,20 + CONTROL "ABC\n2",IDD_DBUTTON2,"Button",BS_OWNERDRAW,40,62,23,20 + CONTROL "DEF\n3",IDD_DBUTTON3,"Button",BS_OWNERDRAW,66,62,23,20 + CONTROL "GHI\n4",IDD_DBUTTON4,"Button",BS_OWNERDRAW,14,86,23,20 + CONTROL "JKL\n5",IDD_DBUTTON5,"Button",BS_OWNERDRAW,40,86,23,20 + CONTROL "MNO\n6",IDD_DBUTTON6,"Button",BS_OWNERDRAW,66,86,23,20 + CONTROL "PQRS\n7",IDD_DBUTTON7,"Button",BS_OWNERDRAW,14,110,23, + 20 + CONTROL "TUV\n8",IDD_DBUTTON8,"Button",BS_OWNERDRAW,40,110,23,20 + CONTROL "WXYZ\n9",IDD_DBUTTON9,"Button",BS_OWNERDRAW,66,110,23, + 20 + CONTROL "\n*",IDD_DBUTTONSTAR,"Button",BS_OWNERDRAW,14,134,23,20 + CONTROL "\n0",IDD_DBUTTON0,"Button",BS_OWNERDRAW,40,134,23,20 + CONTROL "\n#",IDD_DBUTTONPOUND,"Button",BS_OWNERDRAW,66,134,23, + 20 + GROUPBOX "Speed dial",IDD_DSPEEDDIALGRP,103,7,84,154 + LTEXT "&1",IDD_DSPEEDDIALTEXT1,109,24,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL1,117,21,63,14,BS_LEFT | WS_GROUP + LTEXT "&2",IDD_DSPEEDDIALTEXT2,109,41,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL2,117,38,63,14,BS_LEFT | WS_GROUP + LTEXT "&3",IDD_DSPEEDDIALTEXT3,109,58,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL3,117,55,63,14,BS_LEFT | WS_GROUP + LTEXT "&4",IDD_DSPEEDDIALTEXT4,109,75,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL4,117,72,63,14,BS_LEFT | WS_GROUP + LTEXT "&5",IDD_DSPEEDDIALTEXT5,109,92,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL5,117,89,63,14,BS_LEFT | WS_GROUP + LTEXT "&6",IDD_DSPEEDDIALTEXT6,109,109,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL6,117,106,63,14,BS_LEFT | WS_GROUP + LTEXT "&7",IDD_DSPEEDDIALTEXT7,109,126,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL7,117,123,63,14,BS_LEFT | WS_GROUP + LTEXT "&8",IDD_DSPEEDDIALTEXT8,109,143,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL8,117,140,63,14,BS_LEFT | WS_GROUP +END + +IDD_SD1 DIALOG DISCARDABLE 12, 29, 165, 173 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP +CAPTION "Edit Speed Dial" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Choose a button from the group below.", + IDD_SD1TEXTCHOOSE,7,7,140,10 + LTEXT "1",IDD_SD1SPEEDDIALTEXT1,7,27,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL1,16,24,63,14,BS_LEFT | WS_GROUP + LTEXT "2",IDD_SD1SPEEDDIALTEXT2,7,44,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL2,16,41,63,14,BS_LEFT | WS_GROUP + LTEXT "3",IDD_SD1SPEEDDIALTEXT3,7,61,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL3,16,58,63,14,BS_LEFT | WS_GROUP + LTEXT "4",IDD_SD1SPEEDDIALTEXT4,7,78,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL4,16,75,63,14,BS_LEFT | WS_GROUP + LTEXT "5",IDD_SD1SPEEDDIALTEXT5,86,27,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL5,95,24,63,14,BS_LEFT | WS_GROUP + LTEXT "6",IDD_SD1SPEEDDIALTEXT6,86,44,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL6,95,41,63,14,BS_LEFT | WS_GROUP + LTEXT "7",IDD_SD1SPEEDDIALTEXT7,86,61,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL7,95,58,63,14,BS_LEFT | WS_GROUP + LTEXT "8",IDD_SD1SPEEDDIALTEXT8,86,78,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL8,95,75,63,14,BS_LEFT | WS_GROUP + LTEXT "",IDD_SD1RECTSEPARATOR,7,96,151,8,WS_DISABLED | NOT + WS_GROUP + LTEXT "Enter a name and number for the selected button.", + IDD_SD1TEXTENTER,7,104,160,10 + LTEXT "&Name:",IDD_SD1TEXTNAME,16,119,29,10 + EDITTEXT IDD_SD1EDITNAME,16,130,63,14,ES_AUTOHSCROLL + LTEXT "N&umber to dial:",IDD_SD1TEXTNUMBER,95,119,53,10 + EDITTEXT IDD_SD1EDITNUMBER,95,130,63,14,ES_AUTOHSCROLL + PUSHBUTTON "&Save",IDOK,55,152,50,14,WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,108,152,50,14 +END + +IDD_SD2 DIALOG DISCARDABLE 12, 29, 158, 91 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP +CAPTION "Program Speed Dial" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Enter a name and number to save on this button.", + IDD_SD2TEXTENTER,7,7,85,21 + DEFPUSHBUTTON "&Save",IDOK,98,7,53,14,WS_GROUP + PUSHBUTTON "Save and &Dial",IDD_SD2SAVEANDDIAL,98,24,53,14, + WS_DISABLED | WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,98,41,53,14 + LTEXT "&Name:",IDD_SD2TEXTNAME,7,30,29,10 + EDITTEXT IDD_SD2EDITNAME,7,41,63,14,ES_AUTOHSCROLL + LTEXT "N&umber to dial:",IDD_SD2TEXTNUMBER,7,59,53,10 + EDITTEXT IDD_SD2EDITNUMBER,7,70,63,14,ES_AUTOHSCROLL +END + +IDD_CONNECTUSING DIALOG PRELOAD DISCARDABLE 50, 50, 260, 105 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP +CAPTION "Connect Using" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "&Line:",IDD_CUTEXTLINE,7,16,79,10,NOT WS_GROUP + COMBOBOX IDD_CULISTLINE,7,27,173,97,CBS_DROPDOWNLIST | CBS_SORT | + WS_GROUP | WS_TABSTOP | WS_VSCROLL + LTEXT "&Address:",IDD_CUTEXTADDRESS,7,43,79,10,NOT WS_GROUP + COMBOBOX IDD_CULISTADDRESS,7,53,173,82,CBS_DROPDOWNLIST | + CBS_SORT | WS_GROUP | WS_TABSTOP | WS_VSCROLL + CONTROL "Use Phone Dialer to handle &voice call requests from other programs", + IDD_CUSIMPLETAPICHKBOX,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,72,230,10 + PUSHBUTTON "Line &Properties...",IDD_CUPROPERTIES,190,26,63,14 + DEFPUSHBUTTON "OK",IDOK,146,84,50,14,WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,203,84,50,14,WS_GROUP +END + +IDD_ABOUT DIALOG DISCARDABLE 22, 38, 227, 100 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "About Phone Dialer" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_DIALER,IDD_AICON,10,5,18,20 + LTEXT "",IDD_ATEXTTITLE,38,5,127,10,SS_NOPREFIX | NOT WS_GROUP + LTEXT "Copyright © 1993-1995 Microsoft. All Rights Reserved.", + IDD_ATEXTCOPYRIGHT,38,35,179,20,SS_NOPREFIX | NOT + WS_GROUP + LTEXT "",-1,38,60,172,1,NOT WS_GROUP + LTEXT "Memory:",-1,38,75,70,10,SS_NOPREFIX | NOT WS_GROUP + LTEXT "%lu KB Free",IDD_ATEXTFREEMEM,120,75,74,10,SS_NOPREFIX | + NOT WS_GROUP + DEFPUSHBUTTON "OK",IDOK,177,5,40,14 + LTEXT "System resources:",-1,38,85,70,10,SS_NOPREFIX | NOT + WS_GROUP + LTEXT "%d%%",IDD_ATEXTRESOURCE,120,85,74,10,SS_NOPREFIX | NOT + WS_GROUP +END + +IDD_INUSE DIALOG DISCARDABLE 22, 38, 199, 81 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Line In Use" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "OK",IDOK,36,58,53,16 + ICON IDI_LINEBUSY,IDD_IUICON,10,5,18,20 + LTEXT "The selected line or address is in use by another program or device on the line. Your call can not be placed at this time.", + IDD_IUTEXT1,45,5,144,27,SS_NOPREFIX | NOT WS_GROUP + LTEXT "Try your call again later.",IDD_IUTEXT2,45,40,114,12, + SS_NOPREFIX | NOT WS_GROUP +END + +IDD_CALLFAILED DIALOG DISCARDABLE 22, 38, 199, 73 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Call Failed" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "OK",IDOK,72,50,53,16 + ICON IDI_LINEBUSY,IDD_IUICON,10,5,18,20 + LTEXT "",IDD_CFTEXT,45,5,144,40,SS_NOPREFIX | NOT WS_GROUP +END + +IDD_DIALING DIALOG DISCARDABLE 0, 0, 172, 62 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Dialing" +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "&Hang Up",IDCANCEL,9,37,50,14 + RTEXT "Currently dialing:",IDD_DGNUMBER,9,9,52,9 + LTEXT "",IDD_DGNUMBERTEXT,63,9,100,9 + LTEXT "",IDD_DGNAMETEXT,63,23,100,9 +END + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDM_MENU MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "E&xit", IDM_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT + MENUITEM "&Copy\tCtrl+C", IDM_EDIT_COPY + MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE + MENUITEM "&Delete\tDel", IDM_EDIT_DELETE + MENUITEM SEPARATOR + MENUITEM "&Speed Dial...", IDM_EDIT_SPEEDDIAL + END + POPUP "&Tools" + BEGIN + MENUITEM "&Connect Using...", IDM_CONNECTUSING + MENUITEM "&Dialing Properties...", IDM_LOCATION + END + POPUP "&Help" + BEGIN + MENUITEM "&Help Topics", IDM_HELP_CONTENTS + MENUITEM "&What's This?", IDM_HELP_WHATSTHIS + MENUITEM SEPARATOR + MENUITEM "&About Phone Dialer", IDM_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +#if WINNT +IDI_DIALER ICON DISCARDABLE "DIALER.ICO" +IDI_LINEBUSY ICON DISCARDABLE "LINEBUSY.ICO" +#else +IDI_DIALER ICON DISCARDABLE "..\\DIALER.ICO" +IDI_LINEBUSY ICON DISCARDABLE "..\\LINEBUSY.ICO" +#endif +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDA_DIALER ACCELERATORS DISCARDABLE +BEGIN + "1", IDD_DSPEEDDIAL1, VIRTKEY, ALT, NOINVERT + "2", IDD_DSPEEDDIAL2, VIRTKEY, ALT, NOINVERT + "3", IDD_DSPEEDDIAL3, VIRTKEY, ALT, NOINVERT + "4", IDD_DSPEEDDIAL4, VIRTKEY, ALT, NOINVERT + "5", IDD_DSPEEDDIAL5, VIRTKEY, ALT, NOINVERT + "6", IDD_DSPEEDDIAL6, VIRTKEY, ALT, NOINVERT + "7", IDD_DSPEEDDIAL7, VIRTKEY, ALT, NOINVERT + "8", IDD_DSPEEDDIAL8, VIRTKEY, ALT, NOINVERT + "C", IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT + "D", IDD_DDIAL, VIRTKEY, ALT, NOINVERT + "N", IDM_ACCEL_NUMTODIAL, VIRTKEY, ALT, NOINVERT + "V", IDM_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT + VK_INSERT, IDM_EDIT_PASTE, VIRTKEY, SHIFT, NOINVERT + "X", IDM_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + + + +#ifdef SDKRELEASE + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 4,0,1259,1 + PRODUCTVERSION 4,0,1259,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "Microsoft Corporation\0" + VALUE "FileDescription", "Microsoft® Windows(TM) Phone Dialer\0" + VALUE "FileVersion", "4.00\0" + VALUE "InternalName", "Phone Dialer\0" + VALUE "LegalCopyright", "Copyright © Microsoft Corporation 1996. All Rights Reserved.\0" + VALUE "OriginalFilename", "dialer.exe\0" + VALUE "ProductName", "Microsoft(R) Windows NT(TM) Operating System\0" + VALUE "ProductVersion", "4.00\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +#else + +#if WINNT +#include <ntverp.h> +#else +#include <version.h> +#endif + +#define VER_FILEDESCRIPTION_STR "Microsoft\256 Windows(TM) Phone Dialer" +#define VER_INTERNALNAME_STR "Dialer" +#define VER_ORIGINALFILENAME_STR "DIALER.EXE" +//#define VER_LEGALCOPYRIGHT_STR "Copyright \251 Microsoft Corporation 1996. All Rights Reserved." +#define VER_LEGALCOPYRIGHT_YEARS "1996" + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT2_UNKNOWN + +#include <common.ver> + + +#endif + + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + ikszAppName "Dialer" + ikszAppFriendlyName "Phone Dialer" +END + +STRINGTABLE DISCARDABLE +BEGIN + ikszErrDefault "An internal error occurred in Phone Dialer.\nQuit and restart Phone Dialer." + ikszErrOOM "There was not enough memory to continue.\nQuit one or more programs, and then try again." + ikszErrTAPI "Windows Telephony was unable to complete an operation requested by Phone Dialer.\nQuit and restart Phone Dialer." + ikszErrNoVoiceLine "Phone Dialer was unable to find a telephone device or modem to use to dial voice calls.\nIn Control Panel, double-click the Modems icon to install a modem, or install another telephone device to use for dialing calls." +END + +STRINGTABLE DISCARDABLE +BEGIN + ikszWarningTapiReInit "Phone Dialer cannot successfully start.\nQuit all other telephony programs, and then try again." + ikszErrLineClose "Your call was cancelled because the Telephony device driver closed the line." + ikszDisconnectedNoDialTone + "A dial tone was not detected. Please check your telephone cable connections, and be sure the line is not in use by someone else." +END + +STRINGTABLE DISCARDABLE +BEGIN + ikszErrLineInitBadIniFile + "Configuration information relating to Telephony services appears to be corrupt.\nPlease check the configuration of telephone devices in the control panel." + ikszErrLineInitNoDriver "One of the components of the Telephony device driver is missing.\nUse the Control Panel to set up the driver properly." + ikszErrLineInitNoDevice "The selected device has been removed from your computer. Please select a different device for dialing." + ikszErrNoMultipleInstance + "You have two copies of the same Telephony driver installed.\nUse the Control Panel to remove one of the copies." +END + +STRINGTABLE DISCARDABLE +BEGIN + ikszErrInvalAddress "The specified phone number either contains invalid characters, or is incorrectly formatted.\nClick on the number box with the right mouse button to see more information." + ikszErrLineInitWrongDrivers + "One or more telephone device drivers are incompatible with TAPI.DLL.\nInstall an updated version." + ikszErrAddrBlocked "The specified phone number cannot be dialed on the selected line device because it is blocked at the telephone switch." + ikszErrBillingRejected "The billing information specified as part of the phone number has been rejected.\nCheck to make sure you've entered it correctly, and then try again." + ikszErrResUnavail "Another program is using the selected Telephony device.\nTry again after the other program completes." + ikszErrInvalidCountryCode "The country code you entered is invalid.\nPlease check the phone number again." +END + +STRINGTABLE DISCARDABLE +BEGIN + ikszDisconnectedReject "The call was rejected by the called party." + ikszDisconnectedBusy "The called number is busy." + ikszDisconnectedNoAnswer "There was no answer." + ikszDisconnectedCantDo "The call cannot be completed as dialed." + ikszDisconnectedNetwork "The call failed due to network congestion." + ikszDisconnectedIncompatible + "Equipment at the called number is incompatible with your equipment." + ikszErrInvalCallState "The Telephony device driver is unable to respond to your request at this time." +END + +STRINGTABLE DISCARDABLE +BEGIN + ikszWarningTitle "Warning" + ikszWarningFor911 "Using your current location and calling card selection, dialing this number could result in a emergency services call to 911. Are you sure you want to dial this call ?" + ikszWarningNewDefault "Your preferred device selection is not available. A new device has been selected by default. If you wish to change the selection use the 'Connect Using' option under the 'Tools' menu" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/private/tapi/dev/apps/dialer/dialhelp.h b/private/tapi/dev/apps/dialer/dialhelp.h new file mode 100644 index 000000000..54084e44c --- /dev/null +++ b/private/tapi/dev/apps/dialer/dialhelp.h @@ -0,0 +1,29 @@ +// +// (c) 1995 Microsoft Corporation. All Rights Reserved. +// +#define IDH_DIALER_CHANGE_DIAL_HELPER 1000 +#define IDH_DIALER_CHANGE_DIGITS 1001 +#define IDH_DIALER_CHANGE_OPTIONS 1002 +#define IDH_DIALER_CHANGE_REDIAL_BUTTON 1003 +#define IDH_DIALER_DIALING_LOGNAME 1004 +#define IDH_DIALER_DIALING_STATUS 1005 +#define IDH_DIALER_HANGUP 1006 +#define IDH_DIALER_LOG_IN 1007 +#define IDH_DIALER_LOG_OUT 1008 +#define IDH_DIALER_OPTIONS_ADDRESS 1009 +#define IDH_DIALER_OPTIONS_LINE 1010 +#define IDH_DIALER_OPTIONS_NONVOICE 1011 +#define IDH_DIALER_OPTIONS_VOICE 1012 +#define IDH_DIALER_PAUSE_CONTINUE 1013 +#define IDH_DIALER_SPEED_CHOOSE 1014 +#define IDH_DIALER_SPEED_NAME 1015 +#define IDH_DIALER_SPEED_NUMBER 1016 +#define IDH_DIALER_SPEED_SAVE 1017 +#define IDH_DIALER_SPEED_SAVE_DIAL 1018 +#define IDH_DIALER_DIAL_NUMBER 1019 +#define IDH_DIALER_DIAL_SPEED_CHOOSE 1020 +#define IDH_DIALER_DIAL_BUTTON 1021 +#define IDH_DIALER_DIAL_KEYPAD 1022 +#define IDH_DIALER_LOG 1023 +#define IDH_DIALER_OPTIONS_PROPERTIES 1024 +#define IDH_DIALER_BUTTONS 1025 diff --git a/private/tapi/dev/apps/dialer/linebusy.ico b/private/tapi/dev/apps/dialer/linebusy.ico Binary files differnew file mode 100644 index 000000000..589f2671b --- /dev/null +++ b/private/tapi/dev/apps/dialer/linebusy.ico diff --git a/private/tapi/dev/apps/dialer/makefile b/private/tapi/dev/apps/dialer/makefile new file mode 100644 index 000000000..f1084966b --- /dev/null +++ b/private/tapi/dev/apps/dialer/makefile @@ -0,0 +1,29 @@ +!if "$(OS)" == "Windows_NT" + +!INCLUDE $(NTMAKEENV)\makefile.def + +!else + +############################################################################## +# +# Dialer.exe Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\.. + +VERSIONLIST=debug retail + +DEPENDNAME=depend.mk + +COMMONMKFILE=makefile.def + +IS_OEM=TRUE +IS_32 = TRUE + +!include $(ROOT)\dev\master.mk + +!endif + diff --git a/private/tapi/dev/apps/dialer/makefile.def b/private/tapi/dev/apps/dialer/makefile.def new file mode 100644 index 000000000..1eb194df8 --- /dev/null +++ b/private/tapi/dev/apps/dialer/makefile.def @@ -0,0 +1,50 @@ +############################################################################## +# +# Dialer Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\..\.. + + +IS_OEM=1 +WANT_C932=1 +IS_32 = TRUE +WIN32=1 + +DEPENDNAME=..\depend.mk + +DRVNAME=dialer +TARGETS=dialer.exe + +DEFENTRY = WinMain + +SRCDIR=.. + +BUILD_COFF=1 + +L32EXE=dialer.exe # Name of exe. +L32DEF=..\dialer.def # Our def file. +L32MAP=dialer.map # Our map file. +L32SYM=dialer.sym # Our sym file. +L32LIBS= \ + $(W32LIBID)\user32.lib \ + $(W32LIBID)\gdi32.lib \ + $(W32LIBID)\kernel32.lib \ + $(DEVROOT)\sdk\lib\tapi32.lib \ + $(DEVROOT)\tools\c932\lib\oldnames.lib \ + $(DEVROOT)\tools\c932\lib\msvcrt.lib \ + $(DEVROOT)\sdk\lib\shell32.lib + +L32RES=dialer.res # Resource file. +L32OBJS = dialer.obj + +!include $(ROOT)\dev\master.mk + +CFLAGS=$(CFLAGS) -DWIN32=100 -DWIN_32=100 -Og + +!IF "$(VERDIR)" == "debug" +CFLAGS = $(CFLAGS) -DDBG=1 +!endif diff --git a/private/tapi/dev/apps/dialer/nextver/depend.mk b/private/tapi/dev/apps/dialer/nextver/depend.mk new file mode 100644 index 000000000..506be7029 --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/depend.mk @@ -0,0 +1,4 @@ +.\dialer.obj: ..\dialer.c ..\dialer.h ..\dialhelp.h ..\resource.h + +.\dialer.res: ..\dialer.rc ..\version.rc ..\resource.h + diff --git a/private/tapi/dev/apps/dialer/nextver/dialer.c b/private/tapi/dev/apps/dialer/nextver/dialer.c new file mode 100644 index 000000000..3a6d8918b --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/dialer.c @@ -0,0 +1,4300 @@ +/*++ + +Copyright (c) 1996 Microsoft Corporation + +Module Name: + + dialer.c + +--*/ + + +#include "dialer.h" +#include "string.h" +#include "stdlib.h" +#include "shellapi.h" + + +#define ISDIGIT(x) (((x) - '0') >= 0) && (((x) - '0') <= 9) +enum NumberTypes +{ + LOCAL_NUMBER = 7, + EXTENDED_LOCAL_NUMBER, + LONG_DISTANCE_NUMBER = 10, + EXTENDED_LONG_DISTANCE_NUMBER +}; + + +// structs +typedef struct tagLINEINFO +{ + DWORD nAddr; // Number of avail. addresses on the line + BOOL fVoiceLine; // Is this a voice line? + DWORD dwAPIVersion; // API version which the line supports + HLINE hLine; // line handle returned by lineOpen + DWORD dwPermanentLineID; // Permanent line ID retreived from devcaps + char szLineName[MAXBUFSIZE]; // the line's name + +} LINEINFO, *LPLINEINFO; + + +// Global variables + +// window/instance variables +HWND ghWndMain; +HWND ghWndDialing = NULL; +HINSTANCE ghInst = 0; + +// file name vars. +static TCHAR gszAppName[64]; +static TCHAR gszINIfilename [] = "DIALER.INI"; +static TCHAR gszHELPfilename [] = "DIALER.HLP"; +static TCHAR gszDialerClassName[] = "DialerClass"; +TCHAR const gszNULL[] = ""; + +// window item variables +HFONT ghFontBtn; // handle to 1, 2, ..., 0's font +HFONT ghFontBtnText; // handle to number button's text font +HFONT ghFontBtnStar; // handle to * and # button's font +HLINEAPP ghLineApp = NULL; // Dialer's usage handle (regist. w/TAPI) +HCALL ghCall = NULL; // call handle for Dialer's call + +LPSTR gszCurrentNumber = NULL; // number of destination of current call +LPSTR gszCurrentName = NULL; // name of destination of current call + +BOOL gfRegistered; // was lineRegisterRequestRecipient() + // successful? + +//BOOL gfDropping = FALSE; // is Dialer currently dropping a call? +BOOL gfNeedToReinit = FALSE; // does Dialer need to re-initialize? + +BOOL gfCallRequest = FALSE; // Does a Simple TAPI app want a call? +BOOL gfCurrentLineAvail = TRUE; // Simple TAPI requests are only carried + // out if the current chosen line is avail. +BOOL gfMakeCallReplyPending = FALSE; + +LONG gMakeCallRequestID = 0; // request ID returned by async TAPI fns. +LONG gDropCallRequestID = 0; // request ID returned by async TAPI fns. + +DWORD gnAvailDevices = 0; // # of line devices avail. to Dialer +LINEINFO gCurrentLineInfo; +DWORD * gnAddr; + +// global to remember where the cursor is in the edit control +DWORD gdwStartSel; +DWORD gdwEndSel; + +DWORD * gdwPLID; // current line's permanent line ID +DWORD giCurrentLine = (DWORD)-1; // the line selected by the user +DWORD giCurrentAddress = 0; // the address selected by the user + +// + 1 so we can work 1-based rather than 0-based (for convenience only) +// global varibles to hold the names and address of the +TCHAR gszSDNumber[ NSPEEDDIALS + 1 ][ TAPIMAXDESTADDRESSSIZE ]; + + +// Function declarations + +// button related functions +VOID ButtonFontSetup(VOID); +VOID DrawButton(HDC hdc, RECT rcBtn, BOOL fHighlighted); +VOID DrawButtonText(HDC hdc, RECT rcBtn, BOOL fHighlighted, UINT IDD_Btn); +VOID DisableDialButtons(BOOL fDisable); +VOID FitTextToButton( HWND, INT, LPSTR ); + +// Callback functions +BOOL CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK DialingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK AboutProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK ConnectUsingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK LineInUseProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK SpeedDial1Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK SpeedDial2Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +VOID CALLBACK tapiCallback ( + DWORD hDevice, DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, DWORD dwParam2, + DWORD dwParam3 + ); + +// tapi related functions +VOID ManageAssistedTelephony(VOID); +VOID InitiateCall(LPCSTR szNumber, LPCSTR szName); + +VOID DialerLineClose(VOID); +VOID DialerCleanup(VOID); +VOID CloseTAPI(VOID); + +DWORD GetLineInfo(DWORD iLine, LPLINEINFO lpLineInfo); +VOID GetLineInfoFailed ( + DWORD iLine, LPLINEDEVCAPS lpDevCaps, + LPLINEINFO lpLineInfo + ); +LPSTR GetAddressName(DWORD iLine, DWORD iAddress); +BOOL MakeCanonicalNumber( LPCSTR szName, LPSTR szCanNumber ); + +// misc. helper functions +VOID ReadINI(VOID); +int errString(HWND hWnd, UINT errCode, UINT uFlags); +VOID AddToRedialList(LPCSTR szNumber); +BOOL InitializeLineBox(HWND hwndLineBox); +BOOL InitializeAddressBox(HWND hwndLineBox, HWND hwndAddressBox); +BOOL Is911 ( LPLINETRANSLATEOUTPUT lpTransOut ); +VOID AmpersandCompensate( LPCSTR lpszSrc, LPSTR lpszDst ); +VOID AmpersandDeCompensate( LPCSTR lpszSrc, LPSTR lpszDst ); + +// Dialer memory management functions +LPVOID DialerAlloc(size_t cbToAlloc); +LPVOID DialerFree(LPVOID lpMem); + + +// Function definitions + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +DWORD InitializeTAPI (VOID) +{ + INT cvLine; + + DWORD iLine; + DWORD dwPreferredPLID, dwID = (DWORD) -1; + + MSG msg; + + LPLINEINFO lpLineInfo = NULL; // LINEINFO for each available line + + DWORD errCode; + DWORD tc = GetTickCount(); + DWORD dwReturn = ERR_NONE; + + char szBuffer[MAXBUFSIZE]; // to read in dwPreferredPLID as a string first + + + + errCode = lineInitialize ( + &ghLineApp, + ghInst, + (LINECALLBACK) tapiCallback, + gszAppName, + &gnAvailDevices + ); + if ( errCode == LINEERR_REINIT ) + { + // take away dialer functionality + EnableWindow( ghWndMain, FALSE ); + DisableDialButtons(TRUE); + + // keep trying until the user cancels + // or we stop getting LINEERR_REINIT + while ( ( errCode = lineInitialize ( + &ghLineApp, + ghInst, + (LINECALLBACK)tapiCallback, + gszAppName, + &gnAvailDevices + ) ) + == LINEERR_REINIT ) + { + // flush queue & yield + while ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + + // bring up the box if 5 seconds have passed since + if(GetTickCount() > 5000 + tc) + { + if ( errString( ghWndMain, ikszWarningTapiReInit, MB_RETRYCANCEL ) + == IDCANCEL ) + { + break; + } + // reset the relative counter + tc = GetTickCount(); + } + } + + // give back dialer functionality + DisableDialButtons( FALSE ); + EnableWindow( ghWndMain, TRUE ); + } + + if ( errCode ) + { + dwReturn = errCode; + goto tapiinit_exit; + } + + // retrieve preferred line info from INI file + GetPrivateProfileString ( + "Preference", + "Preferred Line", + gszNULL, + szBuffer, + MAXBUFSIZE, + gszINIfilename + ); + + // if szBuffer is not empty. + if ( lstrcmp ( gszNULL, szBuffer ) ) + { + dwPreferredPLID = (DWORD) atoi( szBuffer ); + } + else + { + dwPreferredPLID = (DWORD) -1; + } + + // -1 default - tells us if it ever gets set + giCurrentLine = (DWORD) -1; + + // allocate buffer for storing LINEINFO for all of the available lines + // always allocate space for at least one line + if ( gnAvailDevices == 0 ) + { + gnAddr = (DWORD *) DialerAlloc( sizeof( DWORD ) ); + gdwPLID = (DWORD *) DialerAlloc( sizeof( DWORD ) ); + lpLineInfo = (LPLINEINFO) DialerAlloc( sizeof( LINEINFO ) ); + } + else + { + gnAddr = (DWORD *) DialerAlloc( sizeof( DWORD ) * (int)gnAvailDevices); + gdwPLID = (DWORD *) DialerAlloc( sizeof( DWORD ) * (int)gnAvailDevices); + lpLineInfo = (LPLINEINFO) DialerAlloc( sizeof( LINEINFO ) * (int)gnAvailDevices ); + } + + // if no space was set aside... + if ( lpLineInfo == NULL || gnAddr == NULL ) + { + dwReturn = LINEERR_NOMEM; + goto tapiinit_exit; + } + + // fill lpLineInfo[] and open each line + for ( iLine = 0, cvLine = 0; iLine < gnAvailDevices; ++iLine ) + { + // skip remaining processing for this if it didn't open + if ( GetLineInfo( iLine, &lpLineInfo[iLine] ) != ERR_NONE ) + continue; + + gnAddr [ iLine ] = lpLineInfo[iLine].nAddr; + gdwPLID[ iLine ] = lpLineInfo[iLine].dwPermanentLineID; + + if ( lpLineInfo[iLine].dwPermanentLineID == dwPreferredPLID ) + giCurrentLine = iLine; + + // note number of lines with Interactive voice caps. + // used to select a preferred line by default + if ( lpLineInfo [ iLine ].fVoiceLine ) + { + cvLine++; + dwID = iLine; + } + } + + // if we couldn't find the preferred line, + // try and assign one by default + // else bring up connect using dialog + if ( giCurrentLine == (DWORD)-1 ) + { + // check if there is only one line + // that has interactive voice caps, + // make it default line + if ( cvLine == 1 ) + { + giCurrentLine = dwID; + + // if the preferred address read from the INI file + // was different i.e we are changing setting, inform + // the user + if ( dwPreferredPLID != -1 ) + { + errString( ghWndMain, ERR_NEWDEFAULT, MB_ICONEXCLAMATION | MB_OK ); + } + } + else + { + gCurrentLineInfo = lpLineInfo[0]; + if ( DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CONNECTUSING), + ghWndMain, + (DLGPROC)ConnectUsingProc, + INVALID_LINE + ) + == -1) + { + dwReturn = (DWORD) -1; + } + else + { + dwReturn = ERR_NONE; + } + + goto tapiinit_exit; + } + } + gCurrentLineInfo = lpLineInfo[ giCurrentLine ]; + + + // select default address + giCurrentAddress = 0; + + // get the name of the preferred address from ini file + GetPrivateProfileString ( + "Preference", + "Preferred Address", + gszNULL, + szBuffer, + MAXBUFSIZE, + gszINIfilename + ); + + // if preferred address read from INI file + if ( lstrcmp( gszNULL, szBuffer ) ) + { + giCurrentAddress = (DWORD) atoi( szBuffer ); + + // if the address is invalid, set default + if ( giCurrentAddress >= gCurrentLineInfo.nAddr ) + giCurrentAddress = 0; + } + + +tapiinit_exit: + + if (lpLineInfo) + { + DialerFree(lpLineInfo); + } + + return dwReturn;; +} + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +int WINAPI WinMain ( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow + ) +{ + HACCEL hAccel; + MSG msg; + DWORD errCode; + HANDLE hImHere; + + + ghInst = GetModuleHandle( NULL ); + LoadString( ghInst, ikszAppFriendlyName, gszAppName, sizeof(gszAppName)/sizeof(TCHAR) ); + + // + // Now, let's see if we've already got an instance of ourself + hImHere = CreateMutex(NULL, TRUE, "DialersIveBeenStartedMutex"); + + // + // Is there another one of us already here? + if ( ERROR_ALREADY_EXISTS == GetLastError() ) + { + HWND hDialerWnd; + + hDialerWnd = FindWindow(gszDialerClassName, + NULL); + + SetForegroundWindow(hDialerWnd); + + CloseHandle( hImHere ); + return 0; + } + + + { + WNDCLASS wc; + wc.style = CS_DBLCLKS | CS_SAVEBITS | CS_BYTEALIGNWINDOW; + wc.lpfnWndProc = DefDlgProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = DLGWINDOWEXTRA; + wc.hInstance = ghInst; + wc.hIcon = LoadIcon(ghInst, MAKEINTRESOURCE(IDI_DIALER) ); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = GetStockObject (COLOR_WINDOW + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = gszDialerClassName; + RegisterClass(&wc); + } + + + // create the dialog box and set it with info + // from the .INI file + ghWndMain = CreateDialog ( + ghInst, + (LPCSTR)MAKEINTRESOURCE(IDD_DIALER), + (HWND)NULL, + MainWndProc + ); + + ReadINI(); + ButtonFontSetup(); + + ShowWindow(ghWndMain, SW_SHOW); + UpdateWindow(ghWndMain); + + // limit text in Number field to TAPIMAXDESTADDRESSSIZE + SendDlgItemMessage ( + ghWndMain, + IDD_DCOMBO, + CB_LIMITTEXT, + (WPARAM)TAPIMAXDESTADDRESSSIZE, + 0 + ); + + // 0 (ERR_NONE) error code registers success - otherwise terminate + errCode = InitializeTAPI(); + if(errCode) + { + errString(ghWndMain, errCode, MB_APPLMODAL | MB_ICONEXCLAMATION ); + + DialerCleanup(); + return errCode; + } + + errCode = lineRegisterRequestRecipient ( + ghLineApp, + 0, // registration instance + LINEREQUESTMODE_MAKECALL, + TRUE + ); + + if(errCode) + { + gfRegistered = FALSE; + errString(ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK ); + } + else + { + gfRegistered = TRUE; + } + + + hAccel = LoadAccelerators(ghInst, gszAppName); + + while ( GetMessage( &msg, NULL, 0, 0 ) ) + { + if ( ghWndMain == NULL || !IsDialogMessage( ghWndMain, &msg ) ) + { + if(!TranslateAccelerator(ghWndMain, hAccel, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + // If: 1) Dialer is a call manager (if not, ignore requests) + // 2) the currently chosen line is available + // 3) there is a Simple TAPI request + // Then: process the request + if ( gfCurrentLineAvail && gfCallRequest ) + { + ManageAssistedTelephony(); + } + } + + + + DialerCleanup(); + + CloseHandle( hImHere ); + + return msg.wParam; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +LPVOID DialerAlloc(size_t cbToAlloc) +{ + return LocalAlloc(LPTR, cbToAlloc); +} + + +LPVOID DialerFree(LPVOID lpMem) +{ + return LocalFree( lpMem ); +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID ReadINI( VOID ) +{ + WORD cSDEntry, cLastDialed; + DWORD cComma; + + POINT ptLeftTop; + + char szName[ TAPIMAXCALLEDPARTYSIZE ]; + char szTemp[ TAPIMAXCALLEDPARTYSIZE ]; + + char szNum[MAXBUFSIZE]; + char szFieldName[MAXBUFSIZE]; + char szPt[MAXBUFSIZE]; + + + // get speed dial settings from INI file + for(cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry) + { + + wsprintf(szFieldName, "Name%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + szName, + TAPIMAXCALLEDPARTYSIZE - 1, + gszINIfilename + ); + + wsprintf(szFieldName, "Number%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + gszSDNumber[cSDEntry], + TAPIMAXDESTADDRESSSIZE - 1, + gszINIfilename + ); + + if ( !lstrcmp( gszNULL, szName ) ) + { + lstrcpy( szName, gszSDNumber[ cSDEntry ] ); + } + + FitTextToButton( ghWndMain, IDD_DSPEEDDIAL1 + cSDEntry - 1, szName ); + + AmpersandCompensate( szName, szTemp ); + SetDlgItemText ( + ghWndMain, + IDD_DSPEEDDIAL1 + cSDEntry - 1, + (LPCSTR)szTemp + ); // Label the speed dial button + } + + + // set up last dialed numbers in combo box (read from INI) + for(cLastDialed = 1; cLastDialed <= NLASTDIALED; ++cLastDialed) + { + wsprintf(szFieldName, "Last dialed %d", cLastDialed); + GetPrivateProfileString ( + "Last dialed numbers", + szFieldName, + gszNULL, + szNum, + MAXBUFSIZE - 1, + gszINIfilename + ); + if ( szNum[0] ) // i.e. if szNum isn't simply "" - if we read something + // from the INI - put it in the combo box + SendDlgItemMessage( + ghWndMain, + IDD_DCOMBO, + CB_ADDSTRING, + 0, + (LPARAM)(LPCSTR)szNum + ); + } + + // set defaults + ptLeftTop.x = 100; + ptLeftTop.y = 100; + + // set the window position based on the INI data + GetPrivateProfileString ( + "Preference", + "Main Window Left/Top", + gszNULL, + szPt, + MAXBUFSIZE - 1, + gszINIfilename + ); + + if ( szPt[0] ) + { + cComma = strcspn(szPt, ","); + szPt[cComma] = 0; + ptLeftTop.x = atoi(szPt); + + // a possibly absurd check to see that the string + // wasn't akin to "320," with no second entry + if ( *(szPt + cComma + 1 ) ) + ptLeftTop.y = atoi( szPt + cComma + 1 ); + + // check to see that the box is on the screen - the upper left + // must be on the screen, along with a 50x50 box below and to + // the right of it + if ( ptLeftTop.x < 0 + || ptLeftTop.x + 50 >= GetSystemMetrics(SM_CXSCREEN) + || ptLeftTop.y < 0 + || ptLeftTop.y + 50 >= GetSystemMetrics(SM_CYSCREEN) + ) + { + ptLeftTop.x = 100; // set defaults if the box is off of the screen + ptLeftTop.y = 100; // set defaults if the box is off of the screen + } + } + + SetWindowPos ( + ghWndMain, + NULL, + ptLeftTop.x, + ptLeftTop.y, + 0, + 0, + SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOZORDER + ); +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID ButtonFontSetup(VOID) + { + HDC hdc; + int IDD; + + // define the fonts for the buttons + hdc = GetDC(GetDesktopWindow()); + + ghFontBtn = CreateFont( + (-10)*GetDeviceCaps(hdc, LOGPIXELSY)/72, + 0, + 0, + 0, + FW_BOLD, + FALSE, + FALSE, + FALSE, + ANSI_CHARSET, + OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, + PROOF_QUALITY, + VARIABLE_PITCH | FF_SWISS, + (LPSTR)"Arial" + ); + + ghFontBtnText = CreateFont( + (-6)*GetDeviceCaps(hdc, LOGPIXELSY)/72, + 0, + 0, + 0, + FW_NORMAL, + FALSE, + FALSE, + FALSE, + ANSI_CHARSET, + OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, + PROOF_QUALITY, + VARIABLE_PITCH | FF_SWISS, + NULL + ); + + ghFontBtnStar = CreateFont( + (-18)*GetDeviceCaps(hdc, LOGPIXELSY)/72, + 0, + 0, + 0, + FW_BOLD, + FALSE, + FALSE, + FALSE, + SYMBOL_CHARSET, + OUT_TT_PRECIS, + CLIP_DEFAULT_PRECIS, + PROOF_QUALITY, + VARIABLE_PITCH | FF_DONTCARE, + (LPSTR)"Symbol" + ); + + ReleaseDC(GetDesktopWindow(), hdc); + + + // set the fonts for the buttons + if(ghFontBtn) + { + // set fonts on number buttons + for(IDD = IDD_DBUTTON1; IDD <= IDD_DBUTTON0; ++IDD) + // the order is IDD_DBUTTON1, 2, 3, ..., 0 (thus from 1 to 0) + SendMessage( + GetDlgItem(ghWndMain, IDD), + WM_SETFONT, + (WPARAM)ghFontBtn, + 0L + ); + + // set fonts on * and # buttons + SendMessage( + GetDlgItem(ghWndMain, IDD_DBUTTONSTAR), + WM_SETFONT, + (WPARAM)ghFontBtnStar, + 0L + ); + SendMessage( + GetDlgItem(ghWndMain, IDD_DBUTTONPOUND), + WM_SETFONT, + (WPARAM)ghFontBtnStar, + 0L + ); + } + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +// Draws a 3D button within rcBtn on hDC +VOID DrawButton(HDC hDC, RECT rcBtn, BOOL fHighlighted) + { + HPEN hPenPrev, hPenShadow, hPenHighlight, hPenBlack; + HBRUSH hBrushPrev, hBrushFace; + int RopPrev; + + --rcBtn.right; + --rcBtn.bottom; + + // set up pens/brush + hPenShadow = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DSHADOW)); + hPenHighlight = CreatePen(PS_SOLID,0,GetSysColor(COLOR_3DHILIGHT)); + hPenBlack = GetStockObject(BLACK_PEN); + hBrushFace = GetSysColorBrush(COLOR_3DFACE); + + // get current state so we can put it back at the end of DrawButton + hPenPrev = SelectObject(hDC, hPenBlack); + RopPrev = SetROP2(hDC, R2_COPYPEN); + hBrushPrev = SelectObject(hDC, hBrushFace); + + PatBlt( + hDC, + rcBtn.left + 1, + rcBtn.top + 1, + rcBtn.right - rcBtn.left - 1, + rcBtn.bottom - rcBtn.top - 1, + PATCOPY + ); + + if(fHighlighted) + { + SelectObject(hDC, hPenBlack); + MoveToEx(hDC, rcBtn.left, rcBtn.bottom - 1, NULL); + LineTo(hDC, rcBtn.left, rcBtn.top); // _ + LineTo(hDC, rcBtn.right, rcBtn.top); // | + + SelectObject(hDC, hPenHighlight); + MoveToEx(hDC, rcBtn.right, rcBtn.top, NULL); + LineTo(hDC, rcBtn.right, rcBtn.bottom); + LineTo(hDC, rcBtn.left - 1, rcBtn.bottom); // _| + + SelectObject(hDC, hPenShadow); + MoveToEx(hDC, rcBtn.left + 1, rcBtn.bottom - 2, NULL); + LineTo(hDC, rcBtn.left + 1, rcBtn.top + 1); + LineTo(hDC, rcBtn.right - 1, rcBtn.top + 1); + } + else + { + SelectObject(hDC, hPenHighlight); + MoveToEx(hDC, rcBtn.left, rcBtn.bottom - 1, NULL); + LineTo(hDC, rcBtn.left, rcBtn.top); // _ + LineTo(hDC, rcBtn.right, rcBtn.top); // | + + SelectObject(hDC, hPenBlack); + MoveToEx(hDC, rcBtn.right, rcBtn.top, NULL); + LineTo(hDC, rcBtn.right, rcBtn.bottom); + LineTo(hDC, rcBtn.left - 1, rcBtn.bottom); // _| + + SelectObject(hDC, hPenShadow); + MoveToEx(hDC, rcBtn.left + 1, rcBtn.bottom - 1, NULL); + LineTo(hDC, rcBtn.right - 1, rcBtn.bottom - 1); + LineTo(hDC, rcBtn.right - 1, rcBtn.top); + } + + // put everything back how it was + SetROP2(hDC, RopPrev); + SelectObject(hDC, hBrushPrev); + SelectObject(hDC, hPenPrev); + + DeleteObject(hPenBlack); + DeleteObject(hPenShadow); + DeleteObject(hPenHighlight); + DeleteObject(hBrushFace); + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID DrawButtonText(HDC hDC, RECT rcBtn, BOOL fHighlighted, UINT IDD_Btn) + { + char szLine1[MAXBUFSIZE]; // text in button up to '\n' + LPSTR pszLine2; // text in button after '\n' + int BkModePrev; + HFONT hFontPrev = NULL; + TEXTMETRIC tm; + RECT rcText = rcBtn; + + BkModePrev = SetBkMode(hDC, TRANSPARENT); + + GetDlgItemText(ghWndMain, IDD_Btn, szLine1, MAXBUFSIZE); + pszLine2 = strstr(szLine1, "\n"); + if(pszLine2) + { + *pszLine2 = 0; // 1 -> "TEST1 \n TEST2" becomes "TEST 1 \0" + ++pszLine2; // now 2 -> " TEST 2" + } + + // now szLine1 points to the null terminated first string and + // pszLine2 points to either the null terminated second string or NULL + // if there was no second string + + if(szLine1[0]) + { + if(ghFontBtnText && pszLine2) + hFontPrev = SelectObject(hDC, ghFontBtnText); + + GetTextMetrics(hDC, &tm); + rcText.bottom = (rcBtn.bottom + rcBtn.top)/2 - 2; + rcText.top = rcText.bottom - (tm.tmHeight - 1); + + if(pszLine2 == NULL) + OffsetRect(&rcText, 0, (rcText.bottom - rcText.top)/2); + + if(fHighlighted) + OffsetRect(&rcText, 1, 1); + + DrawText(hDC, szLine1, -1, &rcText, DT_SINGLELINE | DT_CENTER); + + if(hFontPrev) + SelectObject(hDC, hFontPrev); + } + if(pszLine2) // recall that pszLine2 == NULL to represent no second string + { + GetTextMetrics(hDC, &tm); + if(IDD_Btn == IDD_DBUTTONSTAR || IDD_Btn == IDD_DBUTTONPOUND) + rcText.top = (rcBtn.bottom + rcBtn.top)/2 - (tm.tmHeight)/2; + else + rcText.top = (rcBtn.bottom + rcBtn.top)/2 - 2; + rcText.bottom = rcText.top + tm.tmHeight; + + if(fHighlighted) + OffsetRect(&rcText, 1, 1); + + DrawText(hDC, pszLine2, -1, &rcText, DT_SINGLELINE | DT_CENTER); + } + + SetBkMode(hDC, BkModePrev); + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID DisableDialButtons(BOOL fDisable) +{ + int IDD; + + // Disable/enable Dial button + EnableWindow( GetDlgItem( ghWndMain, IDD_DDIAL ),!fDisable) ; + + // Disable/enable Speed dial buttons + for ( IDD = IDD_DSPEEDDIAL1; IDD <= IDD_DSPEEDDIAL8; ++IDD ) + { + EnableWindow(GetDlgItem(ghWndMain, IDD),!fDisable); + } +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID DialerCleanup(VOID) + { + RECT rc; + WORD cItem; // count of numbers in combo box + DWORD cLastDialed; + char szPt[MAXBUFSIZE]; + char szNumber[TAPIMAXDESTADDRESSSIZE]; + char szFieldName[MAXBUFSIZE]; + + CloseTAPI(); // unregister and line close + + if(!IsIconic(ghWndMain)) // if the window is not minimized, record position + { + GetWindowRect(ghWndMain, &rc); + wsprintf(szPt, "%ld, %ld", rc.left, rc.top); + WritePrivateProfileString( + "Preference", + "Main Window Left/Top", + szPt, + gszINIfilename + ); + } + + cItem = (WORD)SendDlgItemMessage(ghWndMain, IDD_DCOMBO, CB_GETCOUNT, 0, 0); + + // write out last dialed numbers from combo box (write to INI) + for(cLastDialed = 1; cLastDialed <= NLASTDIALED; ++cLastDialed) + { + if(cLastDialed <= cItem) + SendDlgItemMessage( + ghWndMain, + IDD_DCOMBO, + CB_GETLBTEXT, + cLastDialed - 1, // it's a zero-based count + (LPARAM)(LPCSTR)szNumber); + + else + szNumber[0] = 0; + + wsprintf(szFieldName, "Last dialed %d", cLastDialed); + WritePrivateProfileString( + "Last dialed numbers", + szFieldName, + szNumber, + gszINIfilename + ); + + } + + WinHelp(ghWndMain, gszHELPfilename, HELP_QUIT, 0); // unload help + + DestroyWindow(ghWndMain); + ghWndMain = NULL; + + DeleteObject(ghFontBtn); + DeleteObject(ghFontBtnText); + DeleteObject(ghFontBtnStar); + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +// unregister and line close +VOID CloseTAPI(VOID) +{ + + // unregister as call manager + lineRegisterRequestRecipient ( + ghLineApp, + 0, // registration instance + LINEREQUESTMODE_MAKECALL, + FALSE + ); + + if ( gCurrentLineInfo.hLine ) + { + lineClose ( gCurrentLineInfo.hLine ); + gfCurrentLineAvail = FALSE; + gCurrentLineInfo.hLine = NULL; + } + + lineShutdown(ghLineApp); +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static HICON hIcon; + static const DWORD aMenuHelpIDs[] = + { + IDD_DSPEEDDIALGRP, (DWORD)-1, + IDD_DNUMTODIAL, IDH_DIALER_DIAL_NUMBER, + IDD_DCOMBO, IDH_DIALER_DIAL_NUMBER, + IDD_DDIAL, IDH_DIALER_DIAL_BUTTON, + IDD_DSPEEDDIAL1, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL2, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL3, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL4, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL5, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL6, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL7, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIAL8, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT1, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT2, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT3, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT4, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT5, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT6, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT7, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DSPEEDDIALTEXT8, IDH_DIALER_DIAL_SPEED_CHOOSE, + IDD_DBUTTON1, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON2, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON3, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON4, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON5, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON6, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON7, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON8, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON9, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTONSTAR, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTON0, IDH_DIALER_DIAL_KEYPAD, + IDD_DBUTTONPOUND, IDH_DIALER_DIAL_KEYPAD, + 0, 0 + }; + + switch (msg) + { + case WM_INITDIALOG: + hIcon = LoadIcon( ghInst, (LPCSTR) MAKEINTRESOURCE( IDI_DIALER ) ); + return TRUE; + + case WM_SYSCOMMAND: + switch( (DWORD) wParam ) + { + case SC_CLOSE: + PostQuitMessage(0); + } + break; + + // processes clicks on controls when + // context mode help is selected + case WM_HELP: + WinHelp ( + ( (LPHELPINFO) lParam)->hItemHandle, + gszHELPfilename, + HELP_WM_HELP, + (DWORD)(LPVOID) aMenuHelpIDs + ); + return TRUE; + + // processes right-clicks on controls + case WM_CONTEXTMENU: + WinHelp ( + (HWND)wParam, + gszHELPfilename, + HELP_CONTEXTMENU, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_INITMENUPOPUP: + // if edit menu + if ( LOWORD(lParam) == 1 ) + { + UINT wEnable; + + if ( GetParent( GetFocus() ) != GetDlgItem( ghWndMain, IDD_DCOMBO ) ) + { + wEnable = MF_GRAYED; + } + else + { + LONG lSelect = SendDlgItemMessage ( + ghWndMain, + IDD_DCOMBO, + CB_GETEDITSEL, + 0, + 0 + ); + + if ( HIWORD( lSelect ) != LOWORD( lSelect ) ) + wEnable = MF_ENABLED; + else + wEnable = MF_GRAYED; + } + + EnableMenuItem((HMENU)wParam, IDM_EDIT_CUT, wEnable); + EnableMenuItem((HMENU)wParam, IDM_EDIT_COPY, wEnable); + EnableMenuItem((HMENU)wParam, IDM_EDIT_DELETE, wEnable); + + // enable paste option is there is data + // in the clipboard + if ( IsClipboardFormatAvailable( CF_TEXT ) ) + { + if ( GetClipboardData ( CF_TEXT ) ) + { + wEnable = MF_ENABLED; + } + else + { + wEnable = MF_GRAYED; + } + } + else + { + wEnable = MF_GRAYED; + } + + } + break; + + + case WM_COMMAND: + { + char szName[TAPIMAXCALLEDPARTYSIZE] = {'\0'}; + char szNumber[TAPIMAXDESTADDRESSSIZE] = {'\0'}; + + switch( LOWORD( (DWORD)wParam ) ) + { + // FILE menu + case IDM_EXIT: + PostQuitMessage(0); + return TRUE; + + + // EDIT menu + case IDM_EDIT_CUT: + SendDlgItemMessage(ghWndMain, IDD_DCOMBO, WM_CUT, 0, 0); + return TRUE; + + case IDM_EDIT_COPY: + SendDlgItemMessage(ghWndMain, IDD_DCOMBO, WM_COPY, 0, 0); + return TRUE; + + case IDM_EDIT_PASTE: + SendDlgItemMessage(ghWndMain, IDD_DCOMBO, WM_PASTE, 0, 0); + return TRUE; + + case IDM_EDIT_DELETE: + SendDlgItemMessage(ghWndMain, IDD_DCOMBO, WM_CLEAR, 0, 0); + return TRUE; + + case IDM_EDIT_SPEEDDIAL: + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_SD1), + ghWndMain, + (DLGPROC)SpeedDial1Proc, + 0 + ); + SetFocus(GetDlgItem(ghWndMain, IDD_DDIAL)); + return TRUE; + + // TOOLS menu + case IDM_CONNECTUSING: + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CONNECTUSING), + ghWndMain, + (DLGPROC)ConnectUsingProc, + MENU_CHOICE + ); + return TRUE; + + case IDM_LOCATION: + { + char szCanNumber[ TAPIMAXDESTADDRESSSIZE ] = ""; + + // fetch the number to be dialed + if ( GetDlgItemText ( + ghWndMain, + IDD_DCOMBO, + szNumber, + TAPIMAXDESTADDRESSSIZE + ) + ) + { + // if a number exists, convert it to + // its canonical form. + if ( !MakeCanonicalNumber ( szNumber, szCanNumber ) ) + { + lstrcpy( szCanNumber, szNumber ); + } + } + + lineTranslateDialog ( + ghLineApp, + 0, + TAPI_CURRENT_VERSION, + ghWndMain, + szCanNumber + ); + return TRUE; + + } + // HELP menu + case IDM_HELP_CONTENTS: + WinHelp(ghWndMain, gszHELPfilename, HELP_CONTENTS, 0); + return TRUE; + + case IDM_HELP_WHATSTHIS: + PostMessage(ghWndMain, WM_SYSCOMMAND, SC_CONTEXTHELP, 0); + return TRUE; + + case IDM_ABOUT: + DialogBoxParam( + ghInst, + MAKEINTRESOURCE(IDD_ABOUT), + ghWndMain, + (DLGPROC)AboutProc, + 0 + ); + + return TRUE; + + + // Accelerator processing + case IDM_ACCEL_NUMTODIAL: + if(GetActiveWindow() == ghWndMain) + SetFocus(GetDlgItem(ghWndMain, IDD_DCOMBO)); + return TRUE; + + + // Buttons + case IDD_DDIAL: + + { + DWORD cSDEntry; + char szSDNumber[TAPIMAXDESTADDRESSSIZE]; + char szFieldName[MAXBUFSIZE]; + + // check if number entered is dialable + if ( SendMessage ( + GetDlgItem(ghWndMain, IDD_DCOMBO), + WM_GETTEXTLENGTH, + 0, + 0 + ) > 0 + ) + { + // get the number to be dialed + GetDlgItemText ( + ghWndMain, + IDD_DCOMBO, + (LPSTR)szNumber, + TAPIMAXDESTADDRESSSIZE + ); + + // check if it is a speed dial number. + // If so choose the name to be displayed. + for( cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry) + { + wsprintf(szFieldName, "Number%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + szSDNumber, + TAPIMAXCALLEDPARTYSIZE - 1, + gszINIfilename + ); + + // if the number matches, get the name + if ( lstrcmp(szSDNumber, szNumber) == 0 ) + { + wsprintf( szFieldName, "Name%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + szName, + TAPIMAXCALLEDPARTYSIZE - 1, + gszINIfilename + ); + break; + } + } + + SetFocus( GetDlgItem( ghWndMain, IDD_DDIAL ) ); + + // once the currentline has been set + // using the connect proc + // the user must hit dial again + if ( giCurrentLine == (DWORD)-1 ) + { + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CONNECTUSING), + ghWndMain, + (DLGPROC)ConnectUsingProc, + INVALID_LINE + ); + } + else + { + AddToRedialList(szNumber); + InitiateCall(szNumber, szName); + } + } + return TRUE; + } + + + case IDD_DBUTTON1: + case IDD_DBUTTON2: + case IDD_DBUTTON3: + case IDD_DBUTTON4: + case IDD_DBUTTON5: + case IDD_DBUTTON6: + case IDD_DBUTTON7: + case IDD_DBUTTON8: + case IDD_DBUTTON9: + case IDD_DBUTTON0: + case IDD_DBUTTONSTAR: + case IDD_DBUTTONPOUND: + { + int i; + TCHAR szBuffer[TAPIMAXDESTADDRESSSIZE+1]; + + static const char digits[] = { '1', '2', '3', '4', + '5', '6', '7', '8', + '9', '0', '*', '#' }; + + i = SendDlgItemMessage(ghWndMain, + IDD_DCOMBO, + WM_GETTEXT, + (WPARAM)TAPIMAXDESTADDRESSSIZE+1, + (LPARAM)szBuffer); + + if (i < TAPIMAXDESTADDRESSSIZE) + { + MoveMemory(szBuffer+gdwStartSel+1, + szBuffer+gdwEndSel, + i - ( gdwEndSel ) + 1 ); + + szBuffer[gdwStartSel] = digits[LOWORD(wParam) - IDD_DBUTTON1]; + + SendDlgItemMessage(ghWndMain, + IDD_DCOMBO, + WM_SETTEXT, + 0, + (LPARAM)szBuffer); + + gdwStartSel++; + gdwEndSel = gdwStartSel; + } + + SetFocus(GetDlgItem(ghWndMain, IDD_DDIAL)); + EnableWindow(GetDlgItem(ghWndMain, IDD_DDIAL), TRUE); + + return TRUE; + } + + + case IDD_DCOMBO: + + if (HIWORD(wParam) == CBN_SELENDOK) + { + EnableWindow( GetDlgItem(ghWndMain, IDD_DDIAL), TRUE ); + } + + if ((HIWORD(wParam) == CBN_SELENDOK) || + (HIWORD(wParam) == CBN_SELENDCANCEL)) + { + + (DWORD)SendDlgItemMessage(ghWndMain, + IDD_DCOMBO, + CB_GETEDITSEL, + (WPARAM)&gdwStartSel, + (LPARAM)&gdwEndSel); + return FALSE; + } + + if ( HIWORD( wParam ) == CBN_EDITCHANGE ) + { + EnableWindow ( + GetDlgItem( ghWndMain, IDD_DDIAL ), + (BOOL) GetWindowTextLength ( + GetDlgItem ( + ghWndMain, + IDD_DCOMBO + ) + ) + ); + return TRUE; + } + + break; + + case IDD_DSPEEDDIAL1: + case IDD_DSPEEDDIAL2: + case IDD_DSPEEDDIAL3: + case IDD_DSPEEDDIAL4: + case IDD_DSPEEDDIAL5: + case IDD_DSPEEDDIAL6: + case IDD_DSPEEDDIAL7: + case IDD_DSPEEDDIAL8: + { + DWORD cSDEntry = LOWORD( (DWORD) wParam) - IDD_DSPEEDDIAL1 + 1; + char szFieldName [MAXBUFSIZE]; + + // get information for the speed dial button + // from the INI file + wsprintf(szFieldName, "Name%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + szName, + TAPIMAXCALLEDPARTYSIZE - 1, + gszINIfilename + ); + + wsprintf(szFieldName, "%s%d", "Number", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + gszSDNumber[cSDEntry], + TAPIMAXDESTADDRESSSIZE - 1, + gszINIfilename + ); + + // entry not set yet + if( gszSDNumber[cSDEntry][0] == 0 ) + { + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_SD2), + ghWndMain, + (DLGPROC)SpeedDial2Proc, + MAKELPARAM(wParam,0) + ); + } + + // no line open + // once the currentline has been set + // using the connect proc + // the user must hit dial again + else if ( giCurrentLine == (DWORD)-1) + { + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CONNECTUSING), + ghWndMain, + (DLGPROC)ConnectUsingProc, + INVALID_LINE + ); + } + // entry is set and valid voice line is open + else + { + // add number to list box combo. + AddToRedialList( gszSDNumber[cSDEntry] ); + InitiateCall( gszSDNumber[cSDEntry], szName ); + } + break; + } + } // end switch (LOWORD((DWORD)wParam)) { ... } + + break; // end case WM_COMMAND + } + + + case WM_PAINT: + { + PAINTSTRUCT ps; + + + BeginPaint(ghWndMain, &ps); + + if(IsIconic(ghWndMain)) + DrawIcon(ps.hdc, 0, 0, hIcon); + else + { + HBRUSH hBrush; + + hBrush = GetSysColorBrush( COLOR_3DFACE ); + // FillRect(ps.hdc, &ps.rcPaint, GetStockObject(LTGRAY_BRUSH)); + FillRect(ps.hdc, &ps.rcPaint, hBrush); + } + + EndPaint(ghWndMain, &ps); + + return TRUE; + } + + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam; + BOOL fHighlighted = (SendDlgItemMessage( + ghWndMain, + lpdis->CtlID, + BM_GETSTATE, + 0, + 0 + ) & 0x0004); + + DrawButton(lpdis->hDC, lpdis->rcItem, fHighlighted); + DrawButtonText( + lpdis->hDC, + lpdis->rcItem, + fHighlighted, + lpdis->CtlID + ); + return TRUE; + } + + + case WM_CTLCOLORLISTBOX: + case WM_CTLCOLORBTN: + case WM_CTLCOLORSTATIC: + SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNFACE)); + return (BOOL)GetSysColorBrush( COLOR_3DFACE ); + + + default: + ; + // return DefDlgProc( hwnd, msg, wParam, lParam ); + // return DefWindowProc( hwnd, msg, wParam, lParam ); + + + } // switch (msg) { ... } + + return FALSE; + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID AddToRedialList( LPCSTR szNumber ) +{ + // NLASTDIALED == 10 + WORD cNum; + HWND hWndCombo = GetDlgItem(ghWndMain, IDD_DCOMBO); + DWORD nMatch; + + // if valid number + if ( szNumber[0] ) + { + // if list box has entries, check if this number + // is already present. If so delete old entry + cNum = (WORD) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0); + if ( cNum != 0 ) + { + nMatch = SendMessage ( hWndCombo, CB_FINDSTRING, 0, (LPARAM)szNumber ); + if ( nMatch != CB_ERR ) + { + SendMessage(hWndCombo, CB_DELETESTRING, nMatch, 0); + } + else + { + // if the list is full, remove oldest + if ( cNum == NLASTDIALED ) + { + SendMessage( hWndCombo, CB_DELETESTRING, NLASTDIALED - 1, 0 ); + } + } + } + SendMessage(hWndCombo, CB_INSERTSTRING, 0, (LPARAM)szNumber); + SendMessage(hWndCombo, CB_SETCURSEL, 0, 0L); + EnableWindow ( GetDlgItem( ghWndMain, IDD_DDIAL ), TRUE ); + } +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID InitiateCall ( LPCSTR szNumber, LPCSTR szName ) +{ + HLINE hLine = NULL; + + DWORD errCode; + + // struct size info + DWORD dwLTPSize = sizeof ( LINETRANSLATEOUTPUT ); + DWORD dwNameLen = lstrlen( szName ) + 1; + DWORD dwLCPSize = sizeof( LINECALLPARAMS ); + + LPLINETRANSLATEOUTPUT lpTransOut = NULL; + LPLINECALLPARAMS lpLineCallParams = NULL; + + char szCanNumber[ TAPIMAXDESTADDRESSSIZE ]; + + // Open a line + errCode = lineOpen ( + ghLineApp, + giCurrentLine, + &hLine, + gCurrentLineInfo.dwAPIVersion, + 0, + 0, + LINECALLPRIVILEGE_NONE, + 0, + NULL + ); + if (errCode) + { + errString ( ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK ); + goto error; + } + + + // call translate address before dialing + do + { + lpTransOut = (LPLINETRANSLATEOUTPUT) DialerAlloc( dwLTPSize ); + if ( !lpTransOut ) + { + errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK ); + goto error; + } + lpTransOut-> dwTotalSize = dwLTPSize; + + + if ( !MakeCanonicalNumber( szNumber, szCanNumber ) ) + { + lstrcpy( szCanNumber, szNumber ); + } + + errCode = lineTranslateAddress ( + ghLineApp, + giCurrentLine, + gCurrentLineInfo.dwAPIVersion, + szCanNumber, + 0, + 0, + lpTransOut + ); + if ( ((LONG)errCode) < 0 ) + { + errString( ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK ); + goto error; + } + + if ( lpTransOut-> dwNeededSize <= lpTransOut->dwTotalSize ) + { + // ok we are done + break; + } + else + { + dwLTPSize = lpTransOut-> dwNeededSize; + DialerFree ( lpTransOut ); + lpTransOut = NULL; + } + + } while ( TRUE ); + + + // if number dialed is 911, bring up a warning + if ( Is911( lpTransOut) ) + { + INT nRes = errString ( ghWndMain, ERR_911WARN, MB_ICONSTOP | MB_YESNO ); + if ( nRes == IDNO ) + { + goto error; + } + } + + + // set call parameters + dwLCPSize += dwNameLen + lpTransOut-> dwDisplayableStringSize; + + lpLineCallParams = (LPLINECALLPARAMS) DialerAlloc( dwLCPSize ); + if ( !lpLineCallParams ) + { + errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK ); + goto error; + } + + lpLineCallParams->dwTotalSize = dwLCPSize; + lpLineCallParams->dwBearerMode = LINEBEARERMODE_VOICE; + lpLineCallParams->dwMediaMode = LINEMEDIAMODE_INTERACTIVEVOICE; + lpLineCallParams->dwCallParamFlags = LINECALLPARAMFLAGS_IDLE; + lpLineCallParams->dwAddressMode = LINEADDRESSMODE_ADDRESSID; + lpLineCallParams->dwAddressID = giCurrentAddress; + + if ( szName[ 0 ] ) + { + lpLineCallParams->dwCalledPartySize = dwNameLen; + lpLineCallParams->dwCalledPartyOffset = sizeof( LINECALLPARAMS ); + lstrcpy ( + (LPSTR) lpLineCallParams + sizeof(LINECALLPARAMS), + szName + ); + } + + lpLineCallParams-> dwDisplayableAddressSize = lpTransOut-> dwDisplayableStringSize; + lpLineCallParams-> dwDisplayableAddressOffset = sizeof( LINECALLPARAMS ) + dwNameLen; + + lstrcpy ( + (LPSTR) lpLineCallParams + sizeof(LINECALLPARAMS) + dwNameLen, + (LPSTR) lpTransOut + lpTransOut-> dwDisplayableStringOffset + ); + + + // save dialing information + // Free old allocs. + if ( gszCurrentName ) + { + DialerFree ( gszCurrentName ); + } + + if ( gszCurrentNumber ) + { + DialerFree ( gszCurrentNumber ); + } + + // save new stuff + gszCurrentName = (LPSTR) DialerAlloc( dwNameLen ); + if ( !gszCurrentName ) + { + errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK ); + goto error; + } + lstrcpy ( gszCurrentName, szName ); + + gszCurrentNumber = (LPSTR) DialerAlloc( lpTransOut-> dwDisplayableStringSize ); + if ( !gszCurrentNumber ) + { + errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK ); + goto error; + } + lstrcpy ( + gszCurrentNumber, + (LPSTR) lpTransOut + lpTransOut-> dwDisplayableStringOffset + ); + + gCurrentLineInfo.hLine = hLine; + ghCall = NULL; + + + // finally make the call. + gMakeCallRequestID = 0; + + gMakeCallRequestID = lineMakeCall ( + hLine, + &ghCall, + (LPSTR) lpTransOut + lpTransOut-> dwDialableStringOffset, + 0, + lpLineCallParams + ); + + // async request ID + // - the call is going out + if ( (LONG) gMakeCallRequestID > 0 ) + { + gfCurrentLineAvail = FALSE; + gfMakeCallReplyPending = TRUE; + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_DIALING), + ghWndMain, + (DLGPROC)DialingProc, + 0 + ); + + } + + else + { + if ( gMakeCallRequestID == LINEERR_CALLUNAVAIL ) + { + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CALLFAILED), + ghWndMain, + (DLGPROC)LineInUseProc, + 0 + ); + } + + else + { + errString( ghWndMain, gMakeCallRequestID, MB_ICONEXCLAMATION | MB_OK ); + } + + DialerLineClose(); + gfCurrentLineAvail = TRUE; + } + +error : + if ( lpLineCallParams ) + { + DialerFree( lpLineCallParams ); + } + + if ( lpTransOut ) + { + DialerFree( lpTransOut ); + } + + // if makecall did not succeed but line + // was opened, close it. + if ( ( gMakeCallRequestID <= 0 ) && ( gCurrentLineInfo.hLine ) ) + { + DialerLineClose (); + gfCurrentLineAvail = TRUE; + } + + SetFocus( GetDlgItem( ghWndMain, IDD_DCOMBO ) ); + + return; + +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +DWORD GetLineInfo ( DWORD iLine, LPLINEINFO lpLineInfo ) +{ + DWORD errCode = 0; + DWORD dwNeededSize = 0; + LINEEXTENSIONID ExtensionID; + + LPSTR pszLineName = NULL; + LPLINEDEVCAPS lpDevCaps = NULL; + + + errCode = lineNegotiateAPIVersion ( + ghLineApp, + iLine, + TAPI_VERSION_1_0, + TAPI_CURRENT_VERSION, + &( lpLineInfo->dwAPIVersion ), + &ExtensionID + ); + if ( errCode ) + { + GetLineInfoFailed( iLine, lpDevCaps, lpLineInfo ); + goto error; + } + + dwNeededSize = sizeof( LINEDEVCAPS ); + do + { + lpDevCaps = ( LPLINEDEVCAPS ) DialerAlloc( dwNeededSize ); + if ( !lpDevCaps ) + { + GetLineInfoFailed( iLine, lpDevCaps, lpLineInfo ); + errCode = LINEERR_NOMEM; + goto error; + } + + lpDevCaps->dwTotalSize = dwNeededSize; + errCode = lineGetDevCaps ( + ghLineApp, + iLine, + lpLineInfo->dwAPIVersion, + 0, + lpDevCaps + ); + if ( errCode ) + { + GetLineInfoFailed( iLine, lpDevCaps, lpLineInfo ); + goto error; + } + + if ( lpDevCaps-> dwNeededSize <= lpDevCaps-> dwTotalSize ) + { + break; + } + + dwNeededSize = lpDevCaps->dwNeededSize; + DialerFree( lpDevCaps ); + lpDevCaps = NULL; + + } while ( TRUE ); + + + lpLineInfo->nAddr = lpDevCaps->dwNumAddresses; + lpLineInfo->fVoiceLine = + ( (lpDevCaps->dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE) != 0 ); + + pszLineName = (LPSTR) DialerAlloc( MAXBUFSIZE ); + if ( !pszLineName ) + { + errCode = LINEERR_NOMEM; + goto error; + } + + if ( lpDevCaps->dwLineNameSize > 0 ) + { + if ( lpDevCaps-> dwLineNameSize > (MAXBUFSIZE - 1) ) + { + strncpy ( + pszLineName, + (LPSTR) lpDevCaps + lpDevCaps->dwLineNameOffset, + MAXBUFSIZE - 1 + ); + pszLineName[ MAXBUFSIZE - 1 ] = '\0'; + } + else + { + lstrcpy( pszLineName, (LPSTR) lpDevCaps + lpDevCaps-> dwLineNameOffset ); + } + } + else + { + wsprintf ( pszLineName, "Line %d", iLine ); + } + + + lstrcpy( lpLineInfo->szLineName, pszLineName ); + lpLineInfo->dwPermanentLineID = lpDevCaps->dwPermanentLineID; + + +error: + if ( lpDevCaps ) + DialerFree( lpDevCaps ); + + if ( pszLineName ) + DialerFree( pszLineName ); + + return errCode; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID GetLineInfoFailed ( DWORD iLine, LPLINEDEVCAPS lpDevCaps, LPLINEINFO lpLineInfo ) +{ + if ( lpDevCaps ) + DialerFree(lpDevCaps); + + lpLineInfo->nAddr = 0; + lpLineInfo->fVoiceLine = FALSE; + lpLineInfo->dwAPIVersion = 0; + lpLineInfo->hLine = (HLINE)0; + lpLineInfo->dwPermanentLineID = 0; + lpLineInfo->szLineName[0] = 0; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +LPSTR GetAddressName(DWORD iLine, DWORD iAddress) +{ + DWORD errCode = 0; + DWORD dwNeededSize = 0; + LPSTR pszAddressName = NULL; + LPLINEADDRESSCAPS lpAddressCaps = NULL; + + // allocate space for lineGetAddressCaps data + dwNeededSize = sizeof( LINEADDRESSCAPS ); + + do + { + lpAddressCaps = ( LPLINEADDRESSCAPS )DialerAlloc( dwNeededSize ); + if ( !lpAddressCaps ) + { + goto error; + } + + lpAddressCaps->dwTotalSize = dwNeededSize; + errCode = lineGetAddressCaps ( + ghLineApp, + iLine, + iAddress, + gCurrentLineInfo.dwAPIVersion, + 0, + lpAddressCaps + ); + if ( errCode ) + { + errString( ghWndMain, errCode, MB_ICONSTOP | MB_OK ); + goto error; + } + + if ( lpAddressCaps-> dwNeededSize <= lpAddressCaps-> dwTotalSize ) + { + break; + } + + dwNeededSize = lpAddressCaps->dwNeededSize; + DialerFree( lpAddressCaps ); + lpAddressCaps = NULL; + + } while( TRUE ); + + + // get the address name + pszAddressName = DialerAlloc( MAXBUFSIZE ); + if ( !pszAddressName ) + { + goto error; + } + + if ( lpAddressCaps-> dwAddressSize > 0 ) + { + // keep string length bounded + if ( lpAddressCaps-> dwAddressSize > (MAXBUFSIZE - 1 ) ) + { + strncpy( + pszAddressName, + (LPSTR) lpAddressCaps + lpAddressCaps->dwAddressOffset, + MAXBUFSIZE - 1 + ); + pszAddressName[ MAXBUFSIZE - 1] = '\0'; + } + else + { + lstrcpy ( + pszAddressName, + (LPSTR) lpAddressCaps + lpAddressCaps->dwAddressOffset + ); + } + } + else + // use default name + { + wsprintf(pszAddressName, "Address %d", iAddress); + } + +error: + if ( lpAddressCaps ) + { + DialerFree( lpAddressCaps ); + } + + return pszAddressName; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK DialingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + + switch(msg) + { + char szTemp[ TAPIMAXCALLEDPARTYSIZE ]; + + case WM_INITDIALOG: + // set global handle to window + ghWndDialing = hwnd; + + AmpersandCompensate( gszCurrentName, szTemp ); + + SetDlgItemText(hwnd, IDD_DGNUMBERTEXT, gszCurrentNumber); + SetDlgItemText(hwnd, IDD_DGNAMETEXT, szTemp ); + break; + + case WM_COMMAND: + switch ( LOWORD( (DWORD)wParam ) ) + { + // hang up + case IDCANCEL: + //gfDropping = TRUE; + + // if lineMakeCall has completed + // only then drop call. + if ( !gfMakeCallReplyPending && ghCall ) + { + if ( ( gDropCallRequestID = lineDrop ( ghCall, NULL, 0 ) ) < 0 ) + { + errString ( ghWndDialing, gDropCallRequestID, MB_ICONSTOP | MB_OK ); + } + } + else + { + DialerLineClose(); + gfCurrentLineAvail = TRUE; + gfMakeCallReplyPending = FALSE; + } + + ghWndDialing = NULL; + EndDialog(hwnd, FALSE); + + return TRUE; + + + // something else terminated the call + // all we have to do is terminate this dialog box + case IDOK: + ghWndDialing = NULL; + EndDialog(hwnd, TRUE); + + return TRUE; + } + break; + + default: + ; + } + return FALSE; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK AboutProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + return TRUE; + } + + case WM_CLOSE: + EndDialog(hwnd, TRUE); + return TRUE; + + case WM_COMMAND: + if(LOWORD((DWORD)wParam) == IDOK) + { + EndDialog(hwnd, TRUE); + return TRUE; + } + + break; + } + + return FALSE; + +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK ConnectUsingProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + static const DWORD aMenuHelpIDs[] = + { + IDD_CUTEXTLINE, IDH_DIALER_OPTIONS_LINE, + IDD_CULISTLINE, IDH_DIALER_OPTIONS_LINE, + IDD_CUTEXTADDRESS, IDH_DIALER_OPTIONS_ADDRESS, + IDD_CULISTADDRESS, IDH_DIALER_OPTIONS_ADDRESS, + IDD_CUSIMPLETAPICHKBOX, IDH_DIALER_OPTIONS_VOICE, + IDD_CUPROPERTIES, IDH_DIALER_OPTIONS_PROPERTIES, + 0, 0 + }; + + switch(msg) + { + case WM_HELP: + // processes clicks on controls when + // context mode help is selected + WinHelp ( + ((LPHELPINFO)lParam)->hItemHandle, + gszHELPfilename, + HELP_WM_HELP, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_CONTEXTMENU: + // processes right-clicks on controls + WinHelp ( + (HWND)wParam, + gszHELPfilename, + HELP_CONTEXTMENU, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_INITDIALOG: + { + BOOL fEnable; + DWORD dwPriority; + + // + // Is there any point in even showing this dialog box? + if ( gnAvailDevices == 0 ) + { + // Nope. Let's tell the user what we don't like. + errString ( ghWndMain, ERR_NOLINES, MB_ICONEXCLAMATION | MB_OK ); + + EndDialog(hwnd, FALSE); + return TRUE; + } + + // if not brought up by InitializeTAPI() + if ( lParam != INVALID_LINE ) + { + // hide error text + EnableWindow( GetDlgItem( hwnd, IDD_CUERRORTEXT ), FALSE ); + } + + // get list of lines into the line list box. + fEnable = InitializeLineBox( GetDlgItem(hwnd, IDD_CULISTLINE) ); + EnableWindow( GetDlgItem( hwnd, IDD_CULISTLINE ), fEnable); + + // get list of addresses into the address list box. + fEnable = fEnable && + InitializeAddressBox ( + GetDlgItem(hwnd, IDD_CULISTLINE), + GetDlgItem(hwnd, IDD_CULISTADDRESS) + ); + EnableWindow( GetDlgItem( hwnd, IDD_CULISTADDRESS ), fEnable ); + EnableWindow( GetDlgItem( hwnd, IDOK ), fEnable ); + + EnableWindow( GetDlgItem( hwnd, IDD_CUPROPERTIES ), fEnable ); + + lineGetAppPriority ( + "DIALER.EXE", + 0, // checking app priority for Assisted Telephony requests + NULL, + LINEREQUESTMODE_MAKECALL, + NULL, + &dwPriority + ); + CheckDlgButton(hwnd, IDD_CUSIMPLETAPICHKBOX, (dwPriority == 1)); + + // if dwPriority == 1, we're supporting Assisted Telephony AND + // have the highest priority. + EnableWindow ( + GetDlgItem(hwnd, IDD_CUSIMPLETAPICHKBOX), + gfRegistered + ); + + return FALSE; + } + + case WM_COMMAND: + { + switch ( LOWORD( (DWORD)wParam ) ) + { + case IDD_CULISTLINE: + if ( HIWORD( wParam ) == CBN_SELENDOK ) + // update address box + InitializeAddressBox ( + GetDlgItem(hwnd, IDD_CULISTLINE), + GetDlgItem(hwnd, IDD_CULISTADDRESS) + ); + break; + + case IDD_CUPROPERTIES: + { + HWND hW = GetDlgItem(hwnd, IDD_CULISTLINE); + + lineConfigDialog ( + // device ID + (DWORD) SendMessage ( + hW, + CB_GETITEMDATA, + (WORD) SendMessage(hW, CB_GETCURSEL, 0, 0), + 0 + ), + hwnd, + NULL + ); + break; + } + + case IDOK: + { + HWND hwndBox; + char szBuffer[MAXBUFSIZE]; + DWORD dwPriority; + + // Update line + hwndBox = GetDlgItem( hwnd, IDD_CULISTLINE ); + giCurrentLine = SendMessage ( + hwndBox, + CB_GETITEMDATA, + SendMessage( hwndBox, CB_GETCURSEL, 0, 0 ), + 0 + ); + + // base 10 + itoa( gdwPLID[giCurrentLine], szBuffer, 10 ); + WritePrivateProfileString ( + "Preference", + "Preferred Line", + szBuffer, + gszINIfilename + ); + + + // Update address + hwndBox = GetDlgItem( hwnd, IDD_CULISTADDRESS ); + giCurrentAddress = SendMessage ( + hwndBox, + CB_GETITEMDATA, + SendMessage(hwndBox, CB_GETCURSEL, 0, 0), + 0 + ); + + itoa( giCurrentAddress, szBuffer, 10 ); + WritePrivateProfileString ( + "Preference", + "Preferred Address", + szBuffer, + gszINIfilename + ); + + + // Update application priority + if ( SendDlgItemMessage ( + hwnd, + IDD_CUSIMPLETAPICHKBOX, + BM_GETCHECK, + 0, + 0L + ) + == 0) + { + dwPriority = 0; + } + else + { + dwPriority = 1; + } + + lineSetAppPriority ( + "DIALER.EXE", + 0, + NULL, + LINEREQUESTMODE_MAKECALL, + NULL, + dwPriority + ); + + EndDialog(hwnd, TRUE); + return TRUE; + } + + case IDCANCEL: + EndDialog(hwnd, FALSE); + return TRUE; + } + } + + default: + ; + + } + + return FALSE; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK LineInUseProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) + { + LPARAM lNewParam = lParam; + PTSTR ptStr; + + + switch(msg) + { + case WM_INITDIALOG: + { + switch(lParam) + { + case LINEDISCONNECTMODE_REJECT: + lNewParam = ikszDisconnectedReject; + break; + + case LINEDISCONNECTMODE_BUSY: + lNewParam = ikszDisconnectedBusy; + break; + + case LINEDISCONNECTMODE_NOANSWER: + lNewParam = ikszDisconnectedNoAnswer; + break; + + case LINEDISCONNECTMODE_CONGESTION: + lNewParam = ikszDisconnectedNetwork; + break; + + case LINEDISCONNECTMODE_INCOMPATIBLE: + lNewParam = ikszDisconnectedIncompatible; + break; + + case LINEDISCONNECTMODE_NODIALTONE: + lNewParam = ikszDisconnectedNoDialTone; + break; + + default: + lNewParam = ikszDisconnectedCantDo; + break; + } + return TRUE; + } + + case WM_COMMAND: + if(LOWORD((DWORD)wParam) == IDOK) + { + EndDialog(hwnd, TRUE); + return TRUE; + } + break; + + default: + ; +// return DefDlgProc( hwnd, msg, wParam, lParam ); + + } + + + ptStr = DialerAlloc( MAXBUFSIZE ); + + LoadString( ghInst, lNewParam, ptStr, MAXBUFSIZE ); + + SetDlgItemText( + hwnd, + IDD_CFTEXT, + ptStr + ); + + DialerFree( ptStr ); + + + return FALSE; + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK SpeedDial1Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static DWORD nCurrentSpeedDial; + + static const DWORD aMenuHelpIDs[] = + { + IDOK, IDH_DIALER_SPEED_SAVE, + IDD_SD1SPEEDDIAL1, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL2, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL3, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL4, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL5, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL6, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL7, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIAL8, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT1, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT2, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT3, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT4, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT5, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT6, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT7, IDH_DIALER_BUTTONS, + IDD_SD1SPEEDDIALTEXT8, IDH_DIALER_BUTTONS, + IDD_SD1TEXTNAME, IDH_DIALER_SPEED_NAME, + IDD_SD1EDITNAME, IDH_DIALER_SPEED_NAME, + IDD_SD1TEXTNUMBER, IDH_DIALER_SPEED_NUMBER, + IDD_SD1EDITNUMBER, IDH_DIALER_SPEED_NUMBER, + IDD_SD1TEXTCHOOSE, (DWORD)-1, + IDD_SD1TEXTENTER, (DWORD)-1, + 0, 0 + }; + + // buffer to store speed dial names till they are saved. + static TCHAR szSDName[NSPEEDDIALS + 1][TAPIMAXDESTADDRESSSIZE]; + + switch(msg) + { + case WM_HELP: + // processes clicks on controls when + // context mode help is selected + WinHelp( + ((LPHELPINFO)lParam)->hItemHandle, + gszHELPfilename, + HELP_WM_HELP, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_CONTEXTMENU: // processes right-clicks on controls + WinHelp( + (HWND)wParam, + gszHELPfilename, + HELP_CONTEXTMENU, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_INITDIALOG: + { + DWORD cSDEntry; + DWORD idFirstEmpty = (DWORD) -1; + + char szName[TAPIMAXCALLEDPARTYSIZE]; + char szTemp[TAPIMAXCALLEDPARTYSIZE]; + char szFieldName[MAXBUFSIZE]; + + // Retrieve speed dial info from INI file + for(cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry) + { + wsprintf(szFieldName, "Name%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + szSDName[ cSDEntry ], + TAPIMAXCALLEDPARTYSIZE - 1, + gszINIfilename + ); + + // set the first empty speed dial button + if ( idFirstEmpty == -1 && + szSDName[ cSDEntry ][0] == '\0' && + gszSDNumber[ cSDEntry ][ 0 ] == '\0' ) + idFirstEmpty = cSDEntry; + + wsprintf(szFieldName, "Number%d", cSDEntry); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + gszSDNumber[cSDEntry], + MAXBUFSIZE - 1, + gszINIfilename + ); + + // get a copy of the name for editing + // if name is empty, use the number as the + // name. + if ( lstrcmp( gszNULL, szSDName[ cSDEntry ] ) ) + { + lstrcpy( szName, szSDName[ cSDEntry] ); + } + else + { + lstrcpy( szName, gszSDNumber[ cSDEntry ] ); + } + + FitTextToButton( hwnd, IDD_SD1SPEEDDIAL1 + cSDEntry - 1, szName ); + AmpersandCompensate( szName, szTemp ); + + SetDlgItemText ( + hwnd, + IDD_SD1SPEEDDIAL1 + cSDEntry - 1, + (LPCSTR) szTemp + ); + + } + + // for the edit speed dial dialog + // limit the lengths of text + SendDlgItemMessage ( + hwnd, + IDD_SD1EDITNAME, + EM_LIMITTEXT, + (WPARAM)(TAPIMAXCALLEDPARTYSIZE - 1), + 0 + ); + + SendDlgItemMessage ( + hwnd, + IDD_SD1EDITNUMBER, + EM_LIMITTEXT, + (WPARAM)(TAPIMAXDESTADDRESSSIZE - 1), + 0 + ); + + // select the first empty button + // nothing empty, then edit #1 + if ( -1 == idFirstEmpty ) + { + nCurrentSpeedDial = 1; + SetDlgItemText( + hwnd, + IDD_SD1EDITNAME, + (LPCSTR) szSDName[ 1 ] + ); + + SetDlgItemText( + hwnd, + IDD_SD1EDITNUMBER, + (LPCSTR) gszSDNumber[ 1 ] + ); + } + else + { + nCurrentSpeedDial = idFirstEmpty; + } + + SetFocus( GetDlgItem( hwnd, IDD_SD1EDITNAME ) ); + return FALSE; + } + + case WM_COMMAND: + { + char szName[TAPIMAXCALLEDPARTYSIZE]; + char szTemp[ TAPIMAXCALLEDPARTYSIZE ]; + + switch( LOWORD( (DWORD) wParam ) ) + { + case IDOK: + { + DWORD cSDEntry; + char szFieldName[MAXBUFSIZE]; + + // save new speed dial settings + for ( cSDEntry = 1; cSDEntry <= NSPEEDDIALS; ++cSDEntry ) + { + wsprintf(szFieldName, "Name%d", cSDEntry); + WritePrivateProfileString ( + "Speed Dial Settings", + szFieldName, + szSDName [cSDEntry], + gszINIfilename + ); + + wsprintf(szFieldName, "Number%d", cSDEntry); + WritePrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszSDNumber[cSDEntry], + gszINIfilename + ); + + // set the text for the corresponding + // main window button + if ( szSDName[ cSDEntry ][ 0 ] == '\0' ) + { + lstrcpy( szName, gszSDNumber[ cSDEntry ] ); + } + else + { + lstrcpy( szName, szSDName[ cSDEntry ] ); + } + + FitTextToButton( + ghWndMain, + IDD_DSPEEDDIAL1 + cSDEntry - 1, + szName + ); + + AmpersandCompensate( szName, szTemp ); + SetDlgItemText ( + ghWndMain, + IDD_DSPEEDDIAL1 + cSDEntry - 1, + (LPCSTR) szTemp + ); + } + + EndDialog(hwnd, TRUE); + return TRUE; + } + + case IDCANCEL: + EndDialog(hwnd, FALSE); + return TRUE; + + case IDD_SD1SPEEDDIAL1: + case IDD_SD1SPEEDDIAL2: + case IDD_SD1SPEEDDIAL3: + case IDD_SD1SPEEDDIAL4: + case IDD_SD1SPEEDDIAL5: + case IDD_SD1SPEEDDIAL6: + case IDD_SD1SPEEDDIAL7: + case IDD_SD1SPEEDDIAL8: + + nCurrentSpeedDial = LOWORD( (DWORD) wParam ) - IDD_SD1SPEEDDIAL1 + 1; + + SetDlgItemText ( + hwnd, + IDD_SD1EDITNAME, + szSDName [ nCurrentSpeedDial ] + ); + SetDlgItemText ( + hwnd, + IDD_SD1EDITNUMBER, + gszSDNumber[nCurrentSpeedDial] + ); + + SetFocus( GetDlgItem( hwnd, IDD_SD1EDITNAME ) ); + SendDlgItemMessage( + hwnd, + IDD_SD1EDITNAME, + EM_SETSEL, + 0, + MAKELPARAM(0, -1) + ); + break; + + case IDD_SD1EDITNAME: + if ( HIWORD( wParam ) == EN_CHANGE ) + { + + GetDlgItemText ( + hwnd, + IDD_SD1EDITNAME, + szName, + TAPIMAXCALLEDPARTYSIZE + ); + + // if there is no name, label the button with + // the number + if ( szName[ 0 ] == '\0' ) + { + szSDName[ nCurrentSpeedDial ][ 0 ] = '\0'; + lstrcpy( szName, gszSDNumber[ nCurrentSpeedDial ] ); + } + else + { + lstrcpy( szSDName[ nCurrentSpeedDial ], szName ); + } + + FitTextToButton ( + hwnd, + IDD_SD1SPEEDDIAL1 + nCurrentSpeedDial - 1, + szName + ); + AmpersandCompensate( szName, szTemp ); + + SetDlgItemText ( + hwnd, + IDD_SD1SPEEDDIAL1 + nCurrentSpeedDial - 1, + szTemp + ); + } + break; + + case IDD_SD1EDITNUMBER: + if ( HIWORD( wParam ) == EN_CHANGE ) + { + GetDlgItemText ( + hwnd, + IDD_SD1EDITNUMBER, + gszSDNumber[nCurrentSpeedDial], + TAPIMAXDESTADDRESSSIZE + ); + + if ( gszSDNumber[ nCurrentSpeedDial ][ 0 ] == '\0' ) + { + GetDlgItemText ( + hwnd, + IDD_SD1EDITNAME, + szName, + TAPIMAXDESTADDRESSSIZE + ); + + if ( szName[ 0 ] == '\0' ) + { + SetDlgItemText ( + hwnd, + IDD_SD1SPEEDDIAL1 + nCurrentSpeedDial - 1, + szName + ); + + } + } + } + break; + } // switch(LOWORD((DWORD)wParam)) + break; + + } // case WM_COMMAND: + + default: + ; + + } // switch(msg) + + return FALSE; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL CALLBACK SpeedDial2Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static DWORD nCurrentSpeedDial; + + static const DWORD aMenuHelpIDs[] = + { + IDOK, IDH_DIALER_SPEED_SAVE, + IDD_SD2SAVEANDDIAL, IDH_DIALER_SPEED_SAVE_DIAL, + IDD_SD2TEXTNAME, IDH_DIALER_SPEED_NAME, + IDD_SD2EDITNAME, IDH_DIALER_SPEED_NAME, + IDD_SD2TEXTNUMBER, IDH_DIALER_SPEED_NUMBER, + IDD_SD2EDITNUMBER, IDH_DIALER_SPEED_NUMBER, + 0, 0 + }; + + switch(msg) + { + case WM_HELP: + // processes clicks on controls when + // context mode help is selected + WinHelp ( + ((LPHELPINFO)lParam)->hItemHandle, + gszHELPfilename, + HELP_WM_HELP, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_CONTEXTMENU: + // processes right-clicks on controls + WinHelp ( + (HWND)wParam, + gszHELPfilename, + HELP_CONTEXTMENU, + (DWORD)(LPVOID)aMenuHelpIDs + ); + return TRUE; + + case WM_INITDIALOG: + { + char szFieldName [MAXBUFSIZE]; + char szName [TAPIMAXCALLEDPARTYSIZE]; + + nCurrentSpeedDial = LOWORD( lParam ) - IDD_DSPEEDDIAL1 + 1; + + // retrieve speed dial button info + wsprintf(szFieldName, "Name%d", nCurrentSpeedDial); + GetPrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszNULL, + szName, + TAPIMAXCALLEDPARTYSIZE - 1, + gszINIfilename + ); + SetDlgItemText ( + hwnd, + IDD_SD2EDITNAME, + szName + ); + + SetDlgItemText ( + hwnd, + IDD_SD2EDITNUMBER, + gszSDNumber[nCurrentSpeedDial] + ); + + // limit the lengths of the texts + SendDlgItemMessage ( + hwnd, + IDD_SD2EDITNAME, + EM_LIMITTEXT, + (WPARAM)(TAPIMAXCALLEDPARTYSIZE - 1), + 0 + ); + + SendDlgItemMessage ( + hwnd, + IDD_SD2EDITNUMBER, + EM_LIMITTEXT, + (WPARAM)(TAPIMAXDESTADDRESSSIZE - 1), + 0 + ); + + + SetFocus( GetDlgItem( hwnd, IDD_SD2EDITNAME ) ); + SendDlgItemMessage ( + hwnd, + IDD_SD2EDITNAME, + EM_SETSEL, + 0, + MAKELPARAM(0, -1) + ); + + return FALSE; + } + + case WM_COMMAND: + { + char szName[ TAPIMAXCALLEDPARTYSIZE ]; + char szTemp[ TAPIMAXCALLEDPARTYSIZE ]; + char szFieldName[MAXBUFSIZE]; + + switch ( LOWORD( (DWORD) wParam ) ) + { + case IDOK: + case IDD_SD2SAVEANDDIAL: + { + GetDlgItemText ( + hwnd, + IDD_SD2EDITNAME, + (LPTSTR) szName, + TAPIMAXCALLEDPARTYSIZE + ); + + GetDlgItemText ( + hwnd, + IDD_SD2EDITNUMBER, + (LPTSTR) gszSDNumber[nCurrentSpeedDial], + TAPIMAXCALLEDPARTYSIZE + ); + + wsprintf ( szFieldName, "Name%d", nCurrentSpeedDial ); + + WritePrivateProfileString ( + "Speed Dial Settings", + szFieldName, + szName, + gszINIfilename + ); + + wsprintf ( szFieldName, "Number%d", nCurrentSpeedDial ); + WritePrivateProfileString ( + "Speed Dial Settings", + szFieldName, + gszSDNumber[nCurrentSpeedDial], + gszINIfilename + ); + + // update main window buttons + // is only number has been entered, label button with it. + if ( szName[ 0 ] == '\0' ) + { + lstrcpy( szName, gszSDNumber[ nCurrentSpeedDial ] ); + } + + FitTextToButton ( + ghWndMain, + IDD_DSPEEDDIAL1 + nCurrentSpeedDial - 1, + (LPSTR) szName + ); + + AmpersandCompensate( szName, szTemp ); + + SetDlgItemText ( + ghWndMain, + IDD_DSPEEDDIAL1 + nCurrentSpeedDial - 1, + (LPCSTR)szTemp + ); + + // if save and dial, then post dial message to main window + if ( LOWORD( (DWORD) wParam ) == IDD_SD2SAVEANDDIAL ) + { + PostMessage ( + ghWndMain, + WM_COMMAND, + MAKEWPARAM ( + nCurrentSpeedDial + IDD_DSPEEDDIAL1 - 1, + BN_CLICKED + ), + (LPARAM) GetDlgItem ( + ghWndMain, + nCurrentSpeedDial + IDD_DSPEEDDIAL1 - 1 + ) + ); + } + EndDialog(hwnd, TRUE); + return TRUE; + } + + case IDCANCEL: + EndDialog(hwnd, FALSE); + return TRUE; + + case IDD_SD2EDITNAME: + case IDD_SD2EDITNUMBER: + if ( HIWORD( wParam ) == EN_CHANGE) + { + EnableWindow ( + GetDlgItem( hwnd, IDD_SD2SAVEANDDIAL ), + GetWindowTextLength ( GetDlgItem( hwnd, IDD_SD2EDITNUMBER ) ) > 0 + ); + } + break; + + } // switch(LOWORD((DWORD)wParam)) + break; + } + + + default: + ; + + } // switch(msg) + + return FALSE; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID CALLBACK +tapiCallback ( + DWORD hDevice, + DWORD dwMsg, + DWORD dwCBInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3 + ) +{ + switch (dwMsg) + { + INT errCode; + + case LINE_ADDRESSSTATE: + break; + + case LINE_CALLINFO: + break; + + case LINE_CALLSTATE: + if ( (HCALL)hDevice != ghCall ) + return; + + switch ( dwParam1 ) // new state + { + case LINECALLSTATE_IDLE: + + // tell "Dialing" window to terminate + if ( ghWndDialing ) + { + SendMessage ( + ghWndDialing, + WM_COMMAND, + MAKEWPARAM( IDOK, 0 ), + 0 + ); + } + + // tapi call cleanup + if ( !gfMakeCallReplyPending && ghCall ) + { + if ( ( errCode = lineDeallocateCall( ghCall ) ) < 0 ) + { + errString ( ghWndMain, errCode, MB_ICONSTOP | MB_OK ); + } + ghCall = NULL; + } + DialerLineClose(); + gfCurrentLineAvail = TRUE; + + // update main window + DisableDialButtons( FALSE ); + break; + + case LINECALLSTATE_BUSY: + tapiCallback ( + hDevice, + dwMsg, + dwCBInstance, + LINECALLSTATE_DISCONNECTED, + LINEDISCONNECTMODE_BUSY, + dwParam3 + ); + break; + + case LINECALLSTATE_SPECIALINFO: + tapiCallback ( + hDevice, + dwMsg, + dwCBInstance, + LINECALLSTATE_DISCONNECTED, + LINEDISCONNECTMODE_UNREACHABLE, + dwParam3 + ); + break; + + case LINECALLSTATE_DISCONNECTED: + { + BOOL fCallOK; + DWORD LineDisconnectMode; + + + if ( dwParam2 == 0 ) + LineDisconnectMode = LINEDISCONNECTMODE_NORMAL; + else + LineDisconnectMode = dwParam2; + + fCallOK = ( LineDisconnectMode == LINEDISCONNECTMODE_NORMAL || + LineDisconnectMode == LINEDISCONNECTMODE_UNKNOWN || + LineDisconnectMode == LINEDISCONNECTMODE_PICKUP || + LineDisconnectMode == LINEDISCONNECTMODE_FORWARDED || + LineDisconnectMode == LINEDISCONNECTMODE_UNAVAIL + ); + + + if ( !gfMakeCallReplyPending && ghCall ) + { + //gfDropping = TRUE; + if ( ( gDropCallRequestID = lineDrop ( ghCall, NULL, 0 ) ) < 0 ) + { + errString ( ghWndMain, gDropCallRequestID, MB_ICONSTOP | MB_OK ); + } + } + + if ( !fCallOK ) + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CALLFAILED), + ghWndMain, + (DLGPROC)LineInUseProc, + LineDisconnectMode + ); + break; + } + } + break; + + + case LINE_CLOSE: + if ( gCurrentLineInfo.hLine == (HLINE)hDevice ) + { + errString(ghWndMain, ERR_LINECLOSE, MB_ICONEXCLAMATION | MB_OK ); + gCurrentLineInfo.hLine = NULL; + gfCurrentLineAvail = FALSE; + DisableDialButtons(FALSE); + } + break; + + case LINE_CREATE: + // dwParam1 is the new device's ID + if ( dwParam1 >= gnAvailDevices ) + { + DWORD* gnAddrTemp; + DWORD iLine; + LINEINFO LineInfo; + + // we record new device's address count. + + // we are assuming here that we're just adding a new + // line and it's sequential and it's the last one + + gnAvailDevices = dwParam1 + 1; + + gnAddrTemp = (DWORD *) DialerAlloc ( sizeof(DWORD) * (int)(gnAvailDevices) ); + + for ( iLine = 0; iLine < (gnAvailDevices-1); ++iLine ) + gnAddrTemp[iLine] = gnAddr[iLine]; + + DialerFree( gnAddr ); + + // we have effectively added one more + // space in the gnAddr array + gnAddr = gnAddrTemp; + + if ( GetLineInfo( dwParam1, &LineInfo ) != ERR_NONE ) + break; + + gnAddr[dwParam1] = LineInfo.nAddr; + } + break; + + case LINE_DEVSPECIFIC: + break; + + case LINE_DEVSPECIFICFEATURE: + break; + + case LINE_GATHERDIGITS: + break; + + case LINE_GENERATE: + break; + + case LINE_LINEDEVSTATE: + if ( dwParam1 & LINEDEVSTATE_REINIT ) + { + if(dwParam2 != 0) + { + // this is another msg translated into REINIT + tapiCallback( hDevice, dwParam2, dwCBInstance, dwParam3, 0, 0 ); + } + else + { + // Re-initialize TAPI + gfNeedToReinit = TRUE; + } + } + + if ( dwParam1 & LINEDEVSTATE_REMOVED ) + { + DialerLineClose(); + tapiCallback(hDevice, LINE_CLOSE, dwCBInstance, 0, 0, 0); // is this needed? + } + break; + + case LINE_MONITORDIGITS: + break; + + case LINE_MONITORMEDIA: + break; + + case LINE_MONITORTONE: + break; + + // async reply from lineMakeCall() or lineDrop() + case LINE_REPLY: + + // reply for lineMakeCall + if ( (LONG) dwParam1 == gMakeCallRequestID ) + { + // error on make call + if ( dwParam2 != ERR_NONE ) + { + // Get rid of the Dialing Dialog box if it's up + if ( ghWndDialing ) + { + SendMessage( + ghWndDialing, + WM_COMMAND, + MAKEWPARAM(IDOK,0), + 0 + ); + } + + if ( dwParam2 == LINEERR_CALLUNAVAIL ) + { + DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CALLFAILED), + ghWndMain, + (DLGPROC)LineInUseProc, + 0 + ); + } + else + { + errString ( ghWndMain, dwParam2, MB_ICONEXCLAMATION | MB_OK ); + } + + ghCall = NULL; + DialerLineClose(); + gfCurrentLineAvail = TRUE; + } + + gfMakeCallReplyPending = FALSE; + } + + // reply from lineDrop() + if ( (LONG) dwParam1 == gDropCallRequestID ) + { + //gfDropping = FALSE; + + // tell "Dialing" window to terminate + if ( ghWndDialing ) + { + SendMessage ( + ghWndDialing, + WM_COMMAND, + MAKEWPARAM( IDOK,0 ), + 0 + ); + } + + // tapi call cleanup + if ( dwParam2 == ERR_NONE ) + { + if ( !gfMakeCallReplyPending && ghCall ) + { + if ( ( errCode = lineDeallocateCall( ghCall ) ) < 0 ) + { + errString ( ghWndMain, errCode, MB_ICONSTOP | MB_OK ); + } + ghCall = NULL; + } + } + DialerLineClose (); + gfCurrentLineAvail = TRUE; + } + + break; + + case LINE_REQUEST: + // Simple TAPI request + if ( dwParam1 == LINEREQUESTMODE_MAKECALL ) + { + gfCallRequest = TRUE; + } + break; + } +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL InitializeLineBox(HWND hwndLineBox) +{ + + DWORD iLine, iItem, iItemCurrent = (DWORD)-1; + DWORD errCode; + + LPLINEINFO lpLineInfo = NULL; + + // allocate buffer for storing LINEINFO for all of + // the available lines. Always allocate space for + // at least one line + if ( gnAvailDevices == 0 ) + { + lpLineInfo = (LPLINEINFO) DialerAlloc( sizeof(LINEINFO) ); + } + else + { + lpLineInfo = (LPLINEINFO) DialerAlloc ( sizeof(LINEINFO) * (int)gnAvailDevices ); + } + + // if no space was set aside... + if ( lpLineInfo == NULL ) + return LINEERR_NOMEM; + + // fill lpLineInfo[] and open each line + for ( iLine = 0; iLine < gnAvailDevices; ++iLine ) + { + // skip remaining processing for this line if it didn't open + if ( GetLineInfo( iLine, &lpLineInfo[iLine] ) != ERR_NONE ) + { + continue; + } + + iItem = SendMessage ( + hwndLineBox, + CB_ADDSTRING, + 0, + (LPARAM)(LPCSTR)(lpLineInfo[iLine].szLineName) + ); + + // error, bail out. + if ( iItem == CB_ERR || iItem == CB_ERRSPACE ) + { + if (lpLineInfo) + { + DialerFree(lpLineInfo); + } + + return FALSE; + } + + errCode = SendMessage ( + hwndLineBox, + CB_SETITEMDATA, + (WPARAM)iItem, + (LPARAM)iLine + ); + + if ( iLine == giCurrentLine ) + { + iItemCurrent = iItem; + } + else if ( iItemCurrent != -1 && iItem <= iItemCurrent ) + { + // if the item we are putting is before the + // "current" item, we must increment iItemCurrent + // to reflect that something is being placed before + // it, due to sorting + ++iItemCurrent; + } + } + + if ( iItemCurrent == (DWORD)-1 ) + iItemCurrent = 0; + + if ( SendMessage( hwndLineBox, CB_GETCOUNT, 0, 0) != 0 ) + { + SendMessage( hwndLineBox, CB_SETCURSEL, (WPARAM)iItemCurrent, 0 ); + return TRUE; + } + + DialerFree(lpLineInfo); + return FALSE; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL InitializeAddressBox( HWND hwndLineBox, HWND hwndAddressBox ) +{ + DWORD errCode; + DWORD iAddress, iItem, iItemCurrent = (DWORD)-1; + DWORD iLineBoxCurrent; + LPSTR pszAddressName; + + if ( SendMessage( hwndLineBox, CB_GETCOUNT, 0, 0 ) == 0 ) + { + return FALSE; + } + + // select current entry in line box + iLineBoxCurrent = SendMessage ( + hwndLineBox, + CB_GETITEMDATA, + SendMessage( hwndLineBox, CB_GETCURSEL, 0, 0 ), + 0 + ); + // empty address list box + SendMessage ( hwndAddressBox, CB_RESETCONTENT, 0, 0); + + // get all the address for this line + for ( iAddress = 0; iAddress < gnAddr[iLineBoxCurrent]; ++iAddress ) + { + pszAddressName = GetAddressName( iLineBoxCurrent, iAddress ); + + // if this address if fails, try the next one + if ( !pszAddressName ) + continue; + + iItem = SendMessage ( + hwndAddressBox, + CB_ADDSTRING, + 0, + (LPARAM) (LPCSTR) (pszAddressName) + ); + + // error, bail out + if ( iItem == CB_ERR || iItem == CB_ERRSPACE ) + return FALSE; + + errCode = SendMessage ( + hwndAddressBox, + CB_SETITEMDATA, + (WPARAM) iItem, + (LPARAM) iAddress + ); + + if ( iLineBoxCurrent == giCurrentLine ) + { + if(iAddress == giCurrentAddress) + { + iItemCurrent = iItem; + } + else + { + // if the item we are putting is before the + // "current" item, we must increment iItemCur + // to reflect that something is being placed + // before it, due to sorting + if ( iItemCurrent != -1 && iItem <= iItemCurrent ) + { + ++iItemCurrent; + } + } + } + + DialerFree( pszAddressName ); + } + + if ( iLineBoxCurrent != giCurrentLine ) + { + // if we're not looking at the current line + // then highlight address 0 + iItemCurrent = 0; + } + + SendMessage ( + hwndAddressBox, + CB_SETCURSEL, + iItemCurrent, + 0 + ); + return TRUE; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID ManageAssistedTelephony(VOID) +{ + DWORD errCode; + LPLINEREQMAKECALL lpRequestBuffer; + + lpRequestBuffer = (LPLINEREQMAKECALL) DialerAlloc( sizeof( LINEREQMAKECALL ) ); + if ( !lpRequestBuffer ) + { + goto error; + } + + // bring window to front + SetForegroundWindow(ghWndMain); + + // get next queued request. + errCode = lineGetRequest ( + ghLineApp, + LINEREQUESTMODE_MAKECALL, + lpRequestBuffer + + ); + if ( errCode ) + { + // if no more call requests pending, reset flag. + if ( errCode == LINEERR_NOREQUEST ) + { + gfCallRequest = FALSE; + } + else + { + errString ( ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK ); + } + goto error; + } + + + // if a line has not been selected + if ( giCurrentLine == (DWORD)-1 ) + { + if (!DialogBoxParam ( + ghInst, + MAKEINTRESOURCE(IDD_CONNECTUSING), + ghWndMain, + (DLGPROC) ConnectUsingProc, + INVALID_LINE + )) + { + // failed to get a line + goto error; + } + } + + // make the reuested call. + InitiateCall ( + lpRequestBuffer->szDestAddress, + lpRequestBuffer->szCalledParty + ); + +error : + if ( lpRequestBuffer ) + { + DialerFree( lpRequestBuffer ); + } + return; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID DialerLineClose() +{ + DWORD errCode; + + if ( gCurrentLineInfo.hLine ) + { + if ( errCode = lineClose ( gCurrentLineInfo.hLine ) ) + { + errString ( ghWndMain, errCode, MB_ICONSTOP | MB_OK ); + } + gCurrentLineInfo.hLine = NULL; + } + + + // re-initialize TAPI if it needs to be re-initialized + if ( gfNeedToReinit ) + { + CloseTAPI(); + + errCode = InitializeTAPI(); + if(errCode) + { + errString(ghWndMain, errCode, MB_APPLMODAL | MB_ICONEXCLAMATION ); + DialerCleanup(); // terminate program if we can't init + return; + } + + errCode = lineRegisterRequestRecipient ( + ghLineApp, + 0, + LINEREQUESTMODE_MAKECALL, + TRUE + ); + if (errCode) + { + errString(ghWndMain, errCode, MB_ICONEXCLAMATION | MB_OK ); + } + + gfNeedToReinit = FALSE; + } +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +int errString( HWND hWndOwner, UINT errCode, UINT uFlags ) +{ + PTSTR ptStrTitle; + PTSTR ptStrError; + int nResult; + BOOL bDefault = FALSE; + + ptStrTitle = DialerAlloc( MAXBUFSIZE ); + if ( NULL == ptStrTitle ) + { + // Now, _this_ is a problem. + return 0; + } + + ptStrError = DialerAlloc( MAXBUFSIZE ); + if ( NULL == ptStrError ) + { + // Now, _this_ is a problem. + DialerFree( ptStrTitle); + return 0; + } + + switch(errCode) + { + case ERR_NOLINES: + errCode = ikszErrNoVoiceLine; + break; + + case ERR_NOVOICELINE: + errCode = ikszErrNoVoiceLine; + break; + + case ERR_LINECLOSE: + errCode = ikszErrLineClose; + break; + + case ERR_911WARN: + errCode = ikszWarningFor911; + break; + + case ERR_NEWDEFAULT: + errCode = ikszWarningNewDefault; + break; + + case LINEERR_NODRIVER: + errCode = ikszErrLineInitNoDriver; + break; + + case LINEERR_NODEVICE: + errCode = ikszErrLineInitNoDevice; + break; + + case LINEERR_INIFILECORRUPT: + errCode = ikszErrLineInitBadIniFile ; + break; + + case LINEERR_NOMEM: + errCode = ikszErrOOM; + break; + + case LINEERR_INCOMPATIBLEAPIVERSION: + errCode = ikszErrLineInitWrongDrivers ; + break; + + case LINEERR_OPERATIONFAILED: + errCode = ikszErrTAPI; + break; + + case LINEERR_INVALADDRESS: + errCode = ikszErrInvalAddress; + break; + + case LINEERR_ADDRESSBLOCKED: + errCode = ikszErrAddrBlocked; + break; + + case LINEERR_BILLINGREJECTED: + errCode = ikszErrBillingRejected; + break; + + case LINEERR_RESOURCEUNAVAIL: + case LINEERR_ALLOCATED: + case LINEERR_INUSE: + errCode = ikszErrResUnavail; + break; + + case LINEERR_NOMULTIPLEINSTANCE: + errCode = ikszErrNoMultipleInstance; + break; + + case LINEERR_INVALCALLSTATE: + errCode = ikszErrInvalCallState; + break; + + case LINEERR_INVALCOUNTRYCODE: + errCode = ikszErrInvalidCountryCode; + break; + + default: + bDefault = TRUE; + break; + + } + + + if (bDefault) + { + // if using default error, get TAPI's + // error message from FormatError() + if (!FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, + (LPCVOID)GetModuleHandle(TEXT("TAPI32.DLL")), + (DWORD)TAPIERROR_FORMATMESSAGE(errCode), + 0, + (LPTSTR)ptStrError, + MAXBUFSIZE, + NULL)) + { + // if this fails, fall back on default + LoadString( ghInst, ikszErrDefault, ptStrError, MAXBUFSIZE); + } + + } + else // not the default error message + { + + if ( 0 == LoadString( ghInst, errCode, ptStrError, MAXBUFSIZE ) ) + { +#if DBG + TCHAR buf[200]; + wsprintf( buf, "Cannot load string: hinst:0x%08lx errcode: %ld", (DWORD)ghInst,(DWORD)errCode); + OutputDebugString( buf ); + MessageBox( NULL, buf, "Dialer", MB_OK); +#endif + + LoadString( ghInst, ikszErrDefault, ptStrError, MAXBUFSIZE ); + } + } + + LoadString( ghInst, ikszWarningTitle, ptStrTitle, MAXBUFSIZE ); + + nResult = MessageBox( hWndOwner, ptStrError, ptStrTitle, uFlags ); + + + DialerFree( ptStrTitle ); + DialerFree( ptStrError ); + + + return nResult; +} + + +/* + * Name : + * FitTextToButton + * + * Arguements : + * hDlg handle for the dialog in which this button is embedded + * nButtonID button id of this button + * szName Name to fit on the button. Max size TAPIMAXCALLEDPARTYSIZE + * + * Return : + * None + * + * Comments : + * Function first checks to see if the button text specified fits in the + * button. If it does not it truncates it appropriately and adds trailing + * ellipses. + */ +VOID FitTextToButton ( HWND hDlg, INT nButtonID, LPSTR szName ) +{ + + HDC hDC; + HFONT hFont, hOldFont; + HWND hWnd; + + do + { + // calculate number of chars. that can fit on + // the button + int nLen; + RECT rect; + SIZE size; + POINT pt; + char buf [TAPIMAXCALLEDPARTYSIZE + 1]; + + // get button dimensions + hWnd = GetDlgItem( hDlg, nButtonID ); + if ( hWnd == NULL ) + break; + + if ( !GetClientRect( hWnd, &rect ) ) + break; + + // get character dimensions + hDC = GetDC( hWnd ); + if ( hDC == NULL ) + break; + + hFont = (HFONT) SendMessage( hWnd, WM_GETFONT, 0, 0 ); + if ( hFont == NULL ) + hOldFont = SelectObject( hDC, GetStockObject( SYSTEM_FONT ) ); + else + hOldFont = SelectObject( hDC, hFont ); + + // add an extra char at the end to compensate for + // leading space, + lstrcpy ( buf, szName ); + nLen = lstrlen( buf ); + buf [ nLen ] = 'X'; + buf [ nLen + 1 ] = '\0'; + + if ( !GetTextExtentPoint32( hDC, buf, nLen + 1, &size ) ) + break; + + pt.x = size.cx; + if ( !LPtoDP( hDC, &pt, 1 ) ) + break; + + // check if name fits on button + if ( pt.x > rect.right ) + { + // find how much of the name fits + int i = 0; + + nLen = lstrlen( szName ); + for ( i = 0; i < nLen; i++ ) + { + buf[ i ] = szName[ i ]; + // an extra char is stuffed to compensate for the + // leading space left by the left alignment + buf [ i + 1 ] = 'X'; + buf [ i + 2 ] = '\0'; + + // break out in cases of error condition + if ( !GetTextExtentPoint32( hDC, buf, i + 2, &size ) ) + { + i = nLen; + break; + } + + pt.x = size.cx; + if ( !LPtoDP( hDC, &pt, 1 ) ) + { + i = nLen; + break; + } + + if ( pt.x > rect.right ) + break; + } + + // error + if ( i >= nLen ) + break; + + // name is too long. truncate and add ellipses + szName [i - 3] = '\0'; + lstrcat( szName, "..." ); + } + + } while( FALSE ); + + if ( hDC ) + { + SelectObject( hDC, hOldFont ); + ReleaseDC( hWnd, hDC ); + } + + return; +} + + + +/* + * Name : + * Is911 + * + * Arguements : + * lpTransOut - Translated address contained the dialable string + * + * Returns + * TRUE - If number to be dialed (in the US) is prefixed by 911 + * FALSE - Otherwise + * + * Comments + * + */ +BOOL Is911 ( LPLINETRANSLATEOUTPUT lpTransOut ) +{ + + DWORD i = 0, j = 0; + LPSTR lpDialDigits = (LPSTR)lpTransOut + lpTransOut-> dwDialableStringOffset; + char sz3Pref [ 4 ] = ""; + + + // if this is not the US + if ( lpTransOut-> dwCurrentCountry != 1 ) + return FALSE; + + // skip non digit characters and extract + // the first 3 digits in the dialable number + for ( i = 0, j = 0; i < lpTransOut-> dwDialableStringSize ; i++ ) + { + if ( ISDIGIT( lpDialDigits[i] ) ) + { + sz3Pref[ j++ ] = lpDialDigits [ i ]; + sz3Pref[ j ] = '\0'; + if ( j == 3 ) + break; + } + } + + if ( !lstrcmp( sz3Pref, "911" ) ) + { + return TRUE; + } + + return FALSE; +} + + +/* + * Name : + * MakeCanonicalNumber + * + * Arguements : + * szNumber Number to convert into canonical form. Max size TAPIMAXDESTADDRESSSIZE + * szCanNumber Canonical representation of number specified in szNumber + * + * Return : + * TRUE If the conversion was successful. + * FALSE otherwise + * + * Comments : + * Function first checks if given number is already in canonical form. + * If it is, it returns. If it is not, then it performs the conversion. + */ + +BOOL MakeCanonicalNumber ( LPCSTR szNumber, LPSTR szCanNumber ) +{ + char szDigits [ TAPIMAXDESTADDRESSSIZE ]; + char szPref [ TAPIMAXDESTADDRESSSIZE ]; + + BOOL bRes = FALSE; + + INT errCode = -1; + INT nLenPref, nLenDigits, cPos, i; + + DWORD dwSize = 0; + DWORD dwInd = 0; + + LPLINETRANSLATEOUTPUT lpTransOut = NULL; + LPLINETRANSLATECAPS lpTransCaps = NULL; + + + dwSize = sizeof ( LINETRANSLATEOUTPUT ); + do + { + lpTransOut = ( LPLINETRANSLATEOUTPUT ) DialerAlloc ( dwSize ); + if ( !lpTransOut ) + { + errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK ); + goto error; + } + + lpTransOut-> dwTotalSize = dwSize; + errCode = lineTranslateAddress ( + ghLineApp, + giCurrentLine, + gCurrentLineInfo.dwAPIVersion, + szNumber, + 0, + 0, + lpTransOut + ); + if ( errCode ) + { + goto error; + } + + if ( lpTransOut-> dwNeededSize <= lpTransOut-> dwTotalSize ) + break; + + dwSize = lpTransOut-> dwNeededSize; + DialerFree( lpTransOut ); + + } while( TRUE ); + + + // check if input number is already in + // canonical form. + if ( lpTransOut-> dwTranslateResults & LINETRANSLATERESULT_CANONICAL ) + goto error; + + // ensure country is the USA. + if ( lpTransOut-> dwCurrentCountry != 1 ) + goto error; + + + // Extract the digits from given string + // allowed formatting characters that are ignored are + // space, (, ), -, . + // presence of other characters will render the string invalid. + + // find the prefix of the address upto the | mark. + // the rest of the string can be ignored + nLenPref = strcspn ( szNumber, "|" ); + strncpy( szPref, szNumber, nLenPref ); + szPref[ nLenPref ] = '\0'; + + // if string is not composed entirely of digits + // and allowable formating characters, quit conversion + if ( strspn( szPref, " 0123456789()-." ) != (size_t) nLenPref ) + goto error; + + // collect digits ignoring formating characters. + szDigits[ 0 ] = '\0'; + for ( i = 0, nLenDigits = 0; i < nLenPref; i++ ) + { + if ( ISDIGIT( szNumber[ i ] ) ) + { + szDigits[ nLenDigits++ ] = szNumber[ i ]; + } + } + szDigits[ nLenDigits ] = '\0'; + + // if "internal" number + if ( nLenDigits < LOCAL_NUMBER ) + goto error; + + switch ( nLenDigits ) + { + // Local number ( 7 digits) preceeded by a 0/1 + // Strip leading 0/1 and treat as a local number + case EXTENDED_LOCAL_NUMBER: + if ( szDigits[ 0 ] == '0' || szDigits[ 0 ] == '1' ) + { + nLenDigits--; + memmove( szDigits, &(szDigits[1]), nLenDigits ); + szDigits[ nLenDigits ] = '\0'; + + cPos = strcspn( szPref, "01" ); + nLenPref--; + memmove( &(szPref[ cPos ]), &(szPref[ cPos + 1 ]), nLenPref - cPos ); + szPref[ nLenPref ] = '\0'; + } + else + { + goto error; + } + + case LOCAL_NUMBER : + { + LPLINELOCATIONENTRY lpLocLst; + + // if leading digit is 0 or 1, it is + // illegal in the US + if ( szDigits[ 0 ] == '0' || szDigits[ 0 ] == '1' ) + { + goto error; + } + + // get area code nformation for local number + dwSize = sizeof( LINETRANSLATECAPS ); + do + { + lpTransCaps = (LPLINETRANSLATECAPS) DialerAlloc( dwSize ); + if ( !lpTransCaps ) + { + errString( ghWndMain, LINEERR_NOMEM, MB_ICONSTOP | MB_OK ); + goto error; + } + + lpTransCaps-> dwTotalSize = dwSize; + errCode = lineGetTranslateCaps ( + ghLineApp, + gCurrentLineInfo.dwAPIVersion, + lpTransCaps + ); + if ( errCode ) + { + errString( ghWndMain, errCode, MB_ICONSTOP | MB_OK ); + goto error; + } + + if ( lpTransCaps-> dwNeededSize <= lpTransCaps-> dwTotalSize ) + { + break; + } + + dwSize = lpTransCaps-> dwNeededSize; + DialerFree( lpTransCaps ); + + } while ( TRUE ); + + // skip entries till you locate information for current location + dwSize = sizeof( LINELOCATIONENTRY ); + lpLocLst = (LPLINELOCATIONENTRY) ( (LPSTR) lpTransCaps + + lpTransCaps-> dwLocationListOffset ); + + for ( dwInd = 0; dwInd < lpTransCaps-> dwNumLocations ; dwInd++ ) + { + if ( lpLocLst[ dwInd ].dwPermanentLocationID == lpTransCaps-> dwCurrentLocationID ) + break; + } + + // current location no found ????? + // login error + if ( dwInd == lpTransCaps-> dwNumLocations ) + { + goto error; + } + + // construct canonical form as + szCanNumber[ 0 ]= '\0'; + lstrcat( szCanNumber, "+1 (" ); + lstrcat( szCanNumber, (LPSTR) lpTransCaps + lpLocLst[ dwInd ].dwCityCodeOffset ); + lstrcat( szCanNumber, ") " ); + lstrcat( szCanNumber, szDigits ); + + cPos = strcspn( szNumber, "|" ); + if ( cPos != lstrlen( szNumber ) ) + { + lstrcat( szCanNumber, &(szNumber[ cPos ]) ); + } + + bRes = TRUE; + break; + } + + case EXTENDED_LONG_DISTANCE_NUMBER: + { + // Long distance number ( 10 digits) preceeded by a 0/1 + // Strip leading 0/1 and treat as a long distance number + if ( szDigits[ 0 ] == '0' || szDigits[ 0 ] == '1' ) + { + nLenDigits--; + memmove( szDigits, &(szDigits[1]), nLenDigits ); + szDigits[ nLenDigits ] = '\0'; + + cPos = strcspn( szPref, "01" ); + nLenPref--; + memmove( &(szPref[ cPos ]), &(szPref[ cPos + 1 ]), nLenPref - cPos ); + szPref[ nLenPref ] = '\0'; + } + else + { + goto error; + } + + } + + case LONG_DISTANCE_NUMBER: + { + // if first or fourth digit is 0/1, illegal number + if ( szDigits[ 0 ] == '0' || szDigits[ 0 ] == '1' || + szDigits[ 3 ] == '0' || szDigits[ 3 ] == '1' ) + { + goto error; + } + + szCanNumber[ 0 ] = '\0'; + lstrcat( szCanNumber, "+1 (" ); + strncat( szCanNumber, szDigits, 3 ); + lstrcat( szCanNumber, ") " ); + + lstrcat( szCanNumber, &(szDigits[ 3 ]) ); + + bRes = TRUE; + } + break; + + default : + goto error; + } + +error: + if ( lpTransOut ) + DialerFree( lpTransOut ); + + if ( lpTransCaps ) + DialerFree( lpTransCaps ); + + return bRes; +} + + +/* + * Name : + * AmpersandCompensate + * + * Arguements : + * lpszSrc : Src string containing &s + * lpszDst : Dest string + * + * Return : + * + * Comments : + * Copies string pointed to by lpszSrc to lpszDst character by + * character. If an & is encountered in this process in lpszSrc + * it is copied as && into lpszDst. + * Assumes lpszDst and lpszSrc are of size TAPIMAXCALLEDPARTYSIZE + */ +VOID AmpersandCompensate ( LPCSTR lpszSrc, LPSTR lpszDst ) +{ + // check if the name has an & in it. If so replace + // it with &&. + INT cCnt, cInd; + + for ( cCnt = 0, cInd = 0; + cInd < TAPIMAXCALLEDPARTYSIZE; + cInd++, cCnt++ ) + { + if ( lpszSrc[ cCnt ] == '&' ) + { + lpszDst[ cInd++ ] = '&'; + } + lpszDst[ cInd ] = lpszSrc[ cCnt ]; + + if ( lpszSrc[ cCnt ] == '\0' ) + break; + } + + // make sure string is null terminated. + lpszDst[ TAPIMAXCALLEDPARTYSIZE - 1 ] = '\0'; + + return; +} + + + /* + * Name : + * AmpersandDeCompensate + * + * Arguements : + * lpszSrc : Src string containing &s + * lpszDst : Dest string + * + * Return : + * + * Comments : + * Copies string pointed to by lpszSrc to lpszDst character by + * character. If an && is encountered in this process in lpszSrc + * it is copied as & into lpszDst. + * Assumes lpszDst and lpszSrc are of size TAPIMAXCALLEDPARTYSIZE + */ + VOID AmpersandDeCompensate ( LPCSTR lpszSrc, LPSTR lpszDst ) + { + // check if the name has an & in it. If so replace + // it with &&. + INT cCnt, cInd; + + for ( cCnt = 0, cInd = 0; + cInd < TAPIMAXCALLEDPARTYSIZE; + cInd++, cCnt++ ) + { + if ( ( lpszSrc[ cInd ] == '&' ) && + ( lpszSrc[ cInd + 1 ] == '&' ) ) + { + cInd++; + } + lpszDst[ cCnt ] = lpszSrc[ cInd ] ; + + if ( lpszSrc [ cInd ] == '\0' ) + { + break; + } + } + + lpszDst[ TAPIMAXCALLEDPARTYSIZE - 1 ] = '\0'; + + return; + } diff --git a/private/tapi/dev/apps/dialer/nextver/dialer.def b/private/tapi/dev/apps/dialer/nextver/dialer.def new file mode 100644 index 000000000..b40ab0af1 --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/dialer.def @@ -0,0 +1,9 @@ +NAME DIALER +;STUB 'WINSTUB.EXE' +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE +HEAPSIZE 2048 +STACKSIZE 8192 + +EXPORTS + MainWndProc diff --git a/private/tapi/dev/apps/dialer/nextver/dialer.h b/private/tapi/dev/apps/dialer/nextver/dialer.h new file mode 100644 index 000000000..6f5832862 --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/dialer.h @@ -0,0 +1,51 @@ +/*++ BUILD Version: 0001 // Increment this if a change has global effects + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + dialer.h + +Abstract: + + Header file for dialer + +Author: + + Dan Knudson (DanKn) 05-Apr-1995 + +Revision History: + + Jeremy Horwitz (t-jereh) 30-May-1995 + +--*/ + + +#define TAPI_VERSION_1_0 0x00010003 +#define TAPI_VERSION_1_4 0x00010004 +#define TAPI_VERSION_2_0 0x00020000 +#define TAPI_CURRENT_VERSION TAPI_VERSION_2_0 + +#include <windows.h> +#include "tapi.h" +#include "resource.h" +#include "dialhelp.h" + + +#define MENU_CHOICE 1 // for Connect Using dialog... +#define INVALID_LINE 2 // if INVALID_LINE, turn off CANCEL + // button and add extra text... + +#define MAXNUMLENGTH 64 +#define MAXBUFSIZE 256 +#define NSPEEDDIALS 8 // Dialer supports 8 configurable speed dial entries. +#define NLASTDIALED 20 // Dialer keeps track of the 20 last dialed numbers. + +#define ERR_NONE 0 +#define ERR_NOVOICELINE 1 +#define ERR_LINECLOSE 2 +#define ERR_NOLINES 3 +#define ERR_911WARN 4 +#define ERR_NEWDEFAULT 5 + +#define itoa(x,y,z) _itoa(x,y,z) diff --git a/private/tapi/dev/apps/dialer/nextver/dialer.ico b/private/tapi/dev/apps/dialer/nextver/dialer.ico Binary files differnew file mode 100644 index 000000000..44ccbca29 --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/dialer.ico diff --git a/private/tapi/dev/apps/dialer/nextver/dialer.mak b/private/tapi/dev/apps/dialer/nextver/dialer.mak new file mode 100644 index 000000000..3c4a04bea --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/dialer.mak @@ -0,0 +1,389 @@ +# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 +# TARGTYPE "Win32 (MIPS) Application" 0x0501 + +!IF "$(CFG)" == "" +CFG=Win32 (80x86) Debug +!MESSAGE No configuration specified. Defaulting to Win32 (80x86) Debug. +!ENDIF + +!IF "$(CFG)" != "Win32 (80x86) Release" && "$(CFG)" != "Win32 (80x86) Debug" &&\ + "$(CFG)" != "Win32 (MIPS) Debug" && "$(CFG)" != "Win32 (MIPS) Release" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "dialer.mak" CFG="Win32 (80x86) Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Win32 (80x86) Release" (based on "Win32 (x86) Application") +!MESSAGE "Win32 (80x86) Debug" (based on "Win32 (x86) Application") +!MESSAGE "Win32 (MIPS) Debug" (based on "Win32 (MIPS) Application") +!MESSAGE "Win32 (MIPS) Release" (based on "Win32 (MIPS) Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "Win32 (MIPS) Debug" + +!IF "$(CFG)" == "Win32 (80x86) Release" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "WinRel" +# PROP BASE Intermediate_Dir "WinRel" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "WinRel" +# PROP Intermediate_Dir "WinRel" +OUTDIR=.\WinRel +INTDIR=.\WinRel + +ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +MTL=MkTypLib.exe +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /W3 /GX /YX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /c +CPP_PROJ=/nologo /W3 /GX /YX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\ + "_MBCS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/ /c +CPP_OBJS=.\WinRel/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"DIALER.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# SUBTRACT BASE BSC32 /Iu +# ADD BSC32 /nologo +# SUBTRACT BSC32 /Iu +BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc" +BSC32_SBRS= \ + $(INTDIR)/DIALER.SBR + +$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib mfc30.lib mfco30.lib mfcd30.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:I386 +# ADD LINK32 tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:I386 +LINK32_FLAGS=tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\ + uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /INCREMENTAL:no\ + /PDB:$(OUTDIR)/"dialer.pdb" /MACHINE:I386 /OUT:$(OUTDIR)/"dialer.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/DIALER.res \ + $(INTDIR)/DIALER.OBJ + +$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Win32 (80x86) Debug" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "WinDebug" +# PROP BASE Intermediate_Dir "WinDebug" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "WinDebug" +# PROP Intermediate_Dir "WinDebug" +OUTDIR=.\WinDebug +INTDIR=.\WinDebug + +ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +MTL=MkTypLib.exe +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /c +CPP_PROJ=/nologo /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D\ + "_MBCS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/\ + /Fd$(OUTDIR)/"dialer.pdb" /c +CPP_OBJS=.\WinDebug/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"DIALER.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# SUBTRACT BASE BSC32 /Iu +# ADD BSC32 /nologo +# SUBTRACT BSC32 /Iu +BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc" +BSC32_SBRS= \ + $(INTDIR)/DIALER.SBR + +$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib mfc30d.lib mfco30d.lib mfcd30d.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:I386 +# ADD LINK32 tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:I386 +LINK32_FLAGS=tapi32.lib version.lib kernel32.lib user32.lib gdi32.lib\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\ + uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:windows /INCREMENTAL:yes\ + /PDB:$(OUTDIR)/"dialer.pdb" /DEBUG /MACHINE:I386 /OUT:$(OUTDIR)/"dialer.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/DIALER.res \ + $(INTDIR)/DIALER.OBJ + +$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Win32 (MIPS) Debug" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 1 +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "WinDebug" +# PROP Intermediate_Dir "WinDebug" +OUTDIR=.\WinDebug +INTDIR=.\WinDebug + +ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +MTL=MkTypLib.exe +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MD /Gt0 /QMOb2000 /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /Gt0 /QMOb2000 /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "WIN32" /FR /c +CPP_PROJ=/nologo /Gt0 /QMOb2000 /W3 /GX /Zi /YX /Od /D "_DEBUG" /D "_WINDOWS"\ + /D "_MBCS" /D "WIN32" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/\ + /Fd$(OUTDIR)/"dialer.pdb" /c +CPP_OBJS=.\WinDebug/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"dialer.res" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# SUBTRACT BASE BSC32 /Iu +# ADD BSC32 /nologo +# SUBTRACT BSC32 /Iu +BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc" +BSC32_SBRS= \ + $(INTDIR)/dialer.sbr + +$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib odbc32.lib mfc30d.lib mfco30d.lib mfcd30d.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:MIPS +# ADD LINK32 version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /DEBUG /MACHINE:MIPS +LINK32_FLAGS=version.lib kernel32.lib user32.lib gdi32.lib winspool.lib\ + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO\ + /SUBSYSTEM:windows /PDB:$(OUTDIR)/"dialer.pdb" /DEBUG /MACHINE:MIPS\ + /OUT:$(OUTDIR)/"dialer.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/dialer.res \ + $(INTDIR)/dialer.obj + +$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Win32 (MIPS) Release" + +# PROP BASE Use_MFC 2 +# PROP BASE Use_Debug_Libraries 0 +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "WinRel" +# PROP Intermediate_Dir "WinRel" +OUTDIR=.\WinRel +INTDIR=.\WinRel + +ALL : $(OUTDIR)/dialer.exe $(OUTDIR)/dialer.bsc + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +MTL=MkTypLib.exe +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MD /Gt0 /QMOb2000 /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /c +# ADD CPP /nologo /Gt0 /QMOb2000 /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "WIN32" /FR /c +CPP_PROJ=/nologo /Gt0 /QMOb2000 /W3 /GX /YX /O2 /D "NDEBUG" /D "_WINDOWS" /D\ + "_MBCS" /D "WIN32" /FR$(INTDIR)/ /Fp$(OUTDIR)/"dialer.pch" /Fo$(INTDIR)/ /c +CPP_OBJS=.\WinRel/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +RSC_PROJ=/l 0x409 /fo$(INTDIR)/"dialer.res" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# SUBTRACT BASE BSC32 /Iu +# ADD BSC32 /nologo +# SUBTRACT BSC32 /Iu +BSC32_FLAGS=/nologo /o$(OUTDIR)/"dialer.bsc" +BSC32_SBRS= \ + $(INTDIR)/dialer.sbr + +$(OUTDIR)/dialer.bsc : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +# ADD BASE LINK32 user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib odbc32.lib mfc30.lib mfco30.lib mfcd30.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:MIPS +# ADD LINK32 version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /MACHINE:MIPS +LINK32_FLAGS=version.lib kernel32.lib user32.lib gdi32.lib winspool.lib\ + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO\ + /SUBSYSTEM:windows /PDB:$(OUTDIR)/"dialer.pdb" /MACHINE:MIPS\ + /OUT:$(OUTDIR)/"dialer.exe" +DEF_FILE= +LINK32_OBJS= \ + $(INTDIR)/dialer.res \ + $(INTDIR)/dialer.obj + +$(OUTDIR)/dialer.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +################################################################################ +# Begin Group "Source Files" + +################################################################################ +# Begin Source File + +SOURCE=.\DIALER.RC +DEP_DIALE=\ + .\dialer.ico + +!IF "$(CFG)" == "Win32 (80x86) Release" + +$(INTDIR)/DIALER.res : $(SOURCE) $(DEP_DIALE) $(INTDIR) + $(RSC) $(RSC_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 (80x86) Debug" + +$(INTDIR)/DIALER.res : $(SOURCE) $(DEP_DIALE) $(INTDIR) + $(RSC) $(RSC_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 (MIPS) Debug" + +$(INTDIR)/dialer.res : $(SOURCE) $(DEP_GENER) $(INTDIR) + $(RSC) $(RSC_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 (MIPS) Release" + +$(INTDIR)/dialer.res : $(SOURCE) $(DEP_GENER) $(INTDIR) + $(RSC) $(RSC_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DIALER.C +DEP_DIALER=\ + .\DIALER.H\ + ..\..\INC\TAPI.H\ + .\dialhelp.h + +!IF "$(CFG)" == "Win32 (80x86) Release" + +$(INTDIR)/DIALER.OBJ : $(SOURCE) $(DEP_DIALER) $(INTDIR) + +!ELSEIF "$(CFG)" == "Win32 (80x86) Debug" + +$(INTDIR)/DIALER.OBJ : $(SOURCE) $(DEP_DIALER) $(INTDIR) + +!ELSEIF "$(CFG)" == "Win32 (MIPS) Debug" + +$(INTDIR)/dialer.obj : $(SOURCE) $(DEP_GENERI) $(INTDIR) + +!ELSEIF "$(CFG)" == "Win32 (MIPS) Release" + +$(INTDIR)/dialer.obj : $(SOURCE) $(DEP_GENERI) $(INTDIR) + +!ENDIF + +# End Source File +# End Group +# End Project +################################################################################ diff --git a/private/tapi/dev/apps/dialer/nextver/dialer.rc b/private/tapi/dev/apps/dialer/nextver/dialer.rc new file mode 100644 index 000000000..157bf41dd --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/dialer.rc @@ -0,0 +1,419 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""windows.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALER DIALOG PRELOAD DISCARDABLE 50, 50, 194, 168 +STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU +CAPTION "Phone Dialer" +MENU IDM_MENU +CLASS "DialerClass" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "",IDD_DRECTSEPARATOR,"Static",SS_ETCHEDHORZ | + WS_DISABLED,0,0,194,1 + LTEXT "&Number to dial:",IDD_DNUMTODIAL,7,7,90,10 + COMBOBOX IDD_DCOMBO,7,21,90,104,CBS_DROPDOWN | CBS_AUTOHSCROLL | + WS_VSCROLL | WS_GROUP | WS_TABSTOP | ES_NOHIDESEL + DEFPUSHBUTTON "&Dial",IDD_DDIAL,7,38,90,14,WS_DISABLED | WS_GROUP + CONTROL "\n1",IDD_DBUTTON1,"Button",BS_OWNERDRAW,14,62,23,20 + CONTROL "ABC\n2",IDD_DBUTTON2,"Button",BS_OWNERDRAW,40,62,23,20 + CONTROL "DEF\n3",IDD_DBUTTON3,"Button",BS_OWNERDRAW,66,62,23,20 + CONTROL "GHI\n4",IDD_DBUTTON4,"Button",BS_OWNERDRAW,14,86,23,20 + CONTROL "JKL\n5",IDD_DBUTTON5,"Button",BS_OWNERDRAW,40,86,23,20 + CONTROL "MNO\n6",IDD_DBUTTON6,"Button",BS_OWNERDRAW,66,86,23,20 + CONTROL "PQRS\n7",IDD_DBUTTON7,"Button",BS_OWNERDRAW,14,110,23, + 20 + CONTROL "TUV\n8",IDD_DBUTTON8,"Button",BS_OWNERDRAW,40,110,23,20 + CONTROL "WXYZ\n9",IDD_DBUTTON9,"Button",BS_OWNERDRAW,66,110,23, + 20 + CONTROL "\n*",IDD_DBUTTONSTAR,"Button",BS_OWNERDRAW,14,134,23,20 + CONTROL "\n0",IDD_DBUTTON0,"Button",BS_OWNERDRAW,40,134,23,20 + CONTROL "\n#",IDD_DBUTTONPOUND,"Button",BS_OWNERDRAW,66,134,23, + 20 + GROUPBOX "Speed dial",IDD_DSPEEDDIALGRP,103,7,84,154 + LTEXT "&1",IDD_DSPEEDDIALTEXT1,109,24,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL1,117,21,63,14,BS_LEFT | WS_GROUP + LTEXT "&2",IDD_DSPEEDDIALTEXT2,109,41,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL2,117,38,63,14,BS_LEFT | WS_GROUP + LTEXT "&3",IDD_DSPEEDDIALTEXT3,109,58,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL3,117,55,63,14,BS_LEFT | WS_GROUP + LTEXT "&4",IDD_DSPEEDDIALTEXT4,109,75,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL4,117,72,63,14,BS_LEFT | WS_GROUP + LTEXT "&5",IDD_DSPEEDDIALTEXT5,109,92,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL5,117,89,63,14,BS_LEFT | WS_GROUP + LTEXT "&6",IDD_DSPEEDDIALTEXT6,109,109,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL6,117,106,63,14,BS_LEFT | WS_GROUP + LTEXT "&7",IDD_DSPEEDDIALTEXT7,109,126,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL7,117,123,63,14,BS_LEFT | WS_GROUP + LTEXT "&8",IDD_DSPEEDDIALTEXT8,109,143,7,10 + PUSHBUTTON "",IDD_DSPEEDDIAL8,117,140,63,14,BS_LEFT | WS_GROUP +END + +IDD_SD1 DIALOG DISCARDABLE 12, 29, 165, 173 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP +CAPTION "Edit Speed Dial" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Choose a button from the group below.", + IDD_SD1TEXTCHOOSE,7,7,140,10 + LTEXT "1",IDD_SD1SPEEDDIALTEXT1,7,27,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL1,16,24,63,14,BS_LEFT | WS_GROUP + LTEXT "2",IDD_SD1SPEEDDIALTEXT2,7,44,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL2,16,41,63,14,BS_LEFT | WS_GROUP + LTEXT "3",IDD_SD1SPEEDDIALTEXT3,7,61,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL3,16,58,63,14,BS_LEFT | WS_GROUP + LTEXT "4",IDD_SD1SPEEDDIALTEXT4,7,78,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL4,16,75,63,14,BS_LEFT | WS_GROUP + LTEXT "5",IDD_SD1SPEEDDIALTEXT5,86,27,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL5,95,24,63,14,BS_LEFT | WS_GROUP + LTEXT "6",IDD_SD1SPEEDDIALTEXT6,86,44,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL6,95,41,63,14,BS_LEFT | WS_GROUP + LTEXT "7",IDD_SD1SPEEDDIALTEXT7,86,61,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL7,95,58,63,14,BS_LEFT | WS_GROUP + LTEXT "8",IDD_SD1SPEEDDIALTEXT8,86,78,8,10 + PUSHBUTTON "",IDD_SD1SPEEDDIAL8,95,75,63,14,BS_LEFT | WS_GROUP + LTEXT "",IDD_SD1RECTSEPARATOR,7,96,151,8,WS_DISABLED | NOT + WS_GROUP + LTEXT "Enter a name and number for the selected button.", + IDD_SD1TEXTENTER,7,104,160,10 + LTEXT "&Name:",IDD_SD1TEXTNAME,16,119,29,10 + EDITTEXT IDD_SD1EDITNAME,16,130,63,14,ES_AUTOHSCROLL + LTEXT "N&umber to dial:",IDD_SD1TEXTNUMBER,95,119,53,10 + EDITTEXT IDD_SD1EDITNUMBER,95,130,63,14,ES_AUTOHSCROLL + PUSHBUTTON "&Save",IDOK,55,152,50,14,WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,108,152,50,14 +END + +IDD_SD2 DIALOG DISCARDABLE 12, 29, 158, 91 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP +CAPTION "Program Speed Dial" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Enter a name and number to save on this button.", + IDD_SD2TEXTENTER,7,7,85,21 + DEFPUSHBUTTON "&Save",IDOK,98,7,53,14,WS_GROUP + PUSHBUTTON "Save and &Dial",IDD_SD2SAVEANDDIAL,98,24,53,14, + WS_DISABLED | WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,98,41,53,14 + LTEXT "&Name:",IDD_SD2TEXTNAME,7,30,29,10 + EDITTEXT IDD_SD2EDITNAME,7,41,63,14,ES_AUTOHSCROLL + LTEXT "N&umber to dial:",IDD_SD2TEXTNUMBER,7,59,53,10 + EDITTEXT IDD_SD2EDITNUMBER,7,70,63,14,ES_AUTOHSCROLL +END + +IDD_CONNECTUSING DIALOG PRELOAD DISCARDABLE 50, 50, 260, 105 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CONTEXTHELP +CAPTION "Connect Using" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "&Line:",IDD_CUTEXTLINE,7,16,79,10,NOT WS_GROUP + COMBOBOX IDD_CULISTLINE,7,27,173,97,CBS_DROPDOWNLIST | CBS_SORT | + WS_GROUP | WS_TABSTOP | WS_VSCROLL + LTEXT "&Address:",IDD_CUTEXTADDRESS,7,43,79,10,NOT WS_GROUP + COMBOBOX IDD_CULISTADDRESS,7,53,173,82,CBS_DROPDOWNLIST | + CBS_SORT | WS_GROUP | WS_TABSTOP | WS_VSCROLL + CONTROL "Use Phone Dialer to handle &voice call requests from other programs", + IDD_CUSIMPLETAPICHKBOX,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,72,230,10 + PUSHBUTTON "Line &Properties...",IDD_CUPROPERTIES,190,26,63,14 + DEFPUSHBUTTON "OK",IDOK,146,84,50,14,WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,203,84,50,14,WS_GROUP +END + +IDD_ABOUT DIALOG DISCARDABLE 22, 38, 227, 100 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "About Phone Dialer" +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_DIALER,IDD_AICON,10,5,18,20 + LTEXT "",IDD_ATEXTTITLE,38,5,127,10,SS_NOPREFIX | NOT WS_GROUP + LTEXT "Copyright © 1993-1996 Microsoft. All Rights Reserved.", + IDD_ATEXTCOPYRIGHT,38,35,179,20,SS_NOPREFIX | NOT + WS_GROUP + DEFPUSHBUTTON "OK",IDOK,177,5,40,14 +END + +IDD_INUSE DIALOG DISCARDABLE 22, 38, 199, 81 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Line In Use" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "OK",IDOK,36,58,53,16 + ICON IDI_LINEBUSY,IDD_IUICON,10,5,18,20 + LTEXT "The selected line or address is in use by another program or device on the line. Your call can not be placed at this time.", + IDD_IUTEXT1,45,5,144,27,SS_NOPREFIX | NOT WS_GROUP + LTEXT "Try your call again later.",IDD_IUTEXT2,45,40,114,12, + SS_NOPREFIX | NOT WS_GROUP +END + +IDD_CALLFAILED DIALOG DISCARDABLE 22, 38, 199, 73 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Call Failed" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "OK",IDOK,72,50,53,16 + ICON IDI_LINEBUSY,IDD_IUICON,10,5,18,20 + LTEXT "",IDD_CFTEXT,45,5,144,40,SS_NOPREFIX | NOT WS_GROUP +END + +IDD_DIALING DIALOG DISCARDABLE 0, 0, 172, 62 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Dialing" +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "&Hang Up",IDCANCEL,9,37,50,14 + RTEXT "Currently dialing:",IDD_DGNUMBER,9,9,52,9 + LTEXT "",IDD_DGNUMBERTEXT,63,9,100,9 + LTEXT "",IDD_DGNAMETEXT,63,23,100,9 +END + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDM_MENU MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "E&xit", IDM_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT + MENUITEM "&Copy\tCtrl+C", IDM_EDIT_COPY + MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE + MENUITEM "&Delete\tDel", IDM_EDIT_DELETE + MENUITEM SEPARATOR + MENUITEM "&Speed Dial...", IDM_EDIT_SPEEDDIAL + END + POPUP "&Tools" + BEGIN + MENUITEM "&Connect Using...", IDM_CONNECTUSING + MENUITEM "&Dialing Properties...", IDM_LOCATION + END + POPUP "&Help" + BEGIN + MENUITEM "&Help Topics", IDM_HELP_CONTENTS + MENUITEM "&What's This?", IDM_HELP_WHATSTHIS + MENUITEM SEPARATOR + MENUITEM "&About Phone Dialer", IDM_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +#if WINNT +IDI_DIALER ICON DISCARDABLE "DIALER.ICO" +IDI_LINEBUSY ICON DISCARDABLE "LINEBUSY.ICO" +#else +IDI_DIALER ICON DISCARDABLE "..\\DIALER.ICO" +IDI_LINEBUSY ICON DISCARDABLE "..\\LINEBUSY.ICO" +#endif +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDA_DIALER ACCELERATORS DISCARDABLE +BEGIN + "1", IDD_DSPEEDDIAL1, VIRTKEY, ALT, NOINVERT + "2", IDD_DSPEEDDIAL2, VIRTKEY, ALT, NOINVERT + "3", IDD_DSPEEDDIAL3, VIRTKEY, ALT, NOINVERT + "4", IDD_DSPEEDDIAL4, VIRTKEY, ALT, NOINVERT + "5", IDD_DSPEEDDIAL5, VIRTKEY, ALT, NOINVERT + "6", IDD_DSPEEDDIAL6, VIRTKEY, ALT, NOINVERT + "7", IDD_DSPEEDDIAL7, VIRTKEY, ALT, NOINVERT + "8", IDD_DSPEEDDIAL8, VIRTKEY, ALT, NOINVERT + "C", IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT + "D", IDD_DDIAL, VIRTKEY, ALT, NOINVERT + "N", IDM_ACCEL_NUMTODIAL, VIRTKEY, ALT, NOINVERT + "V", IDM_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT + VK_INSERT, IDM_EDIT_PASTE, VIRTKEY, SHIFT, NOINVERT + "X", IDM_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + + + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 4,0,1259,1 + PRODUCTVERSION 4,0,1259,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "Microsoft Corporation\0" + VALUE "FileDescription", "Microsoft® Windows(TM) Phone Dialer\0" + VALUE "FileVersion", "4.00\0" + VALUE "InternalName", "Phone Dialer\0" + VALUE "LegalCopyright", "Copyright © Microsoft Corporation 1996. All Rights Reserved.\0" + VALUE "OriginalFilename", "dialer.exe\0" + VALUE "ProductName", "Microsoft(R) Windows NT(TM) Operating System\0" + VALUE "ProductVersion", "4.00\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + ikszAppName "Dialer" + ikszAppFriendlyName "Phone Dialer" +END + +STRINGTABLE DISCARDABLE +BEGIN + ikszErrDefault "An internal error occurred in Phone Dialer.\nQuit and restart Phone Dialer." + ikszErrOOM "There was not enough memory to continue.\nQuit one or more programs, and then try again." + ikszErrTAPI "Windows Telephony was unable to complete an operation requested by Phone Dialer.\nQuit and restart Phone Dialer." + ikszErrNoVoiceLine "Phone Dialer was unable to find a telephone device or modem to use to dial voice calls.\nIn Control Panel, double-click the Modems icon to install a modem, or install another telephone device to use for dialing calls." +END + +STRINGTABLE DISCARDABLE +BEGIN + ikszWarningTapiReInit "Phone Dialer cannot successfully start.\nQuit all other telephony programs, and then try again." + ikszErrLineClose "Your call was cancelled because the Telephony device driver closed the line." + ikszDisconnectedNoDialTone + "A dial tone was not detected. Please check your telephone cable connections, and be sure the line is not in use by someone else." +END + +STRINGTABLE DISCARDABLE +BEGIN + ikszErrLineInitBadIniFile + "Configuration information relating to Telephony services appears to be corrupt.\nPlease check the configuration of telephone devices in the control panel." + ikszErrLineInitNoDriver "One of the components of the Telephony device driver is missing.\nUse the Control Panel to set up the driver properly." + ikszErrLineInitNoDevice "The selected device has been removed from your computer. Please select a different device for dialing." + ikszErrNoMultipleInstance + "You have two copies of the same Telephony driver installed.\nUse the Control Panel to remove one of the copies." +END + +STRINGTABLE DISCARDABLE +BEGIN + ikszErrInvalAddress "The specified phone number either contains invalid characters, or is incorrectly formatted.\nClick on the number box with the right mouse button to see more information." + ikszErrLineInitWrongDrivers + "One or more telephone device drivers are incompatible with TAPI.DLL.\nInstall an updated version." + ikszErrAddrBlocked "The specified phone number cannot be dialed on the selected line device because it is blocked at the telephone switch." + ikszErrBillingRejected "The billing information specified as part of the phone number has been rejected.\nCheck to make sure you've entered it correctly, and then try again." + ikszErrResUnavail "Another program is using the selected Telephony device.\nTry again after the other program completes." + ikszErrInvalidCountryCode "The country code you entered is invalid.\nPlease check the phone number again." +END + +STRINGTABLE DISCARDABLE +BEGIN + ikszDisconnectedReject "The call was rejected by the called party." + ikszDisconnectedBusy "The called number is busy." + ikszDisconnectedNoAnswer "There was no answer." + ikszDisconnectedCantDo "The call cannot be completed as dialed." + ikszDisconnectedNetwork "The call failed due to network congestion." + ikszDisconnectedIncompatible + "Equipment at the called number is incompatible with your equipment." + ikszErrInvalCallState "The Telephony device driver is unable to respond to your request at this time." +END + +STRINGTABLE DISCARDABLE +BEGIN + ikszWarningTitle "Warning" + ikszWarningFor911 "Using your current location and calling card selection, dialing this number could result in a emergency services call to 911. Are you sure you want to dial this call ?" + ikszWarningNewDefault "Your preferred device selection is not available. A new device has been selected by default. If you wish to change the selection use the 'Connect Using' option under the 'Tools' menu" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/private/tapi/dev/apps/dialer/nextver/dialhelp.h b/private/tapi/dev/apps/dialer/nextver/dialhelp.h new file mode 100644 index 000000000..54084e44c --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/dialhelp.h @@ -0,0 +1,29 @@ +// +// (c) 1995 Microsoft Corporation. All Rights Reserved. +// +#define IDH_DIALER_CHANGE_DIAL_HELPER 1000 +#define IDH_DIALER_CHANGE_DIGITS 1001 +#define IDH_DIALER_CHANGE_OPTIONS 1002 +#define IDH_DIALER_CHANGE_REDIAL_BUTTON 1003 +#define IDH_DIALER_DIALING_LOGNAME 1004 +#define IDH_DIALER_DIALING_STATUS 1005 +#define IDH_DIALER_HANGUP 1006 +#define IDH_DIALER_LOG_IN 1007 +#define IDH_DIALER_LOG_OUT 1008 +#define IDH_DIALER_OPTIONS_ADDRESS 1009 +#define IDH_DIALER_OPTIONS_LINE 1010 +#define IDH_DIALER_OPTIONS_NONVOICE 1011 +#define IDH_DIALER_OPTIONS_VOICE 1012 +#define IDH_DIALER_PAUSE_CONTINUE 1013 +#define IDH_DIALER_SPEED_CHOOSE 1014 +#define IDH_DIALER_SPEED_NAME 1015 +#define IDH_DIALER_SPEED_NUMBER 1016 +#define IDH_DIALER_SPEED_SAVE 1017 +#define IDH_DIALER_SPEED_SAVE_DIAL 1018 +#define IDH_DIALER_DIAL_NUMBER 1019 +#define IDH_DIALER_DIAL_SPEED_CHOOSE 1020 +#define IDH_DIALER_DIAL_BUTTON 1021 +#define IDH_DIALER_DIAL_KEYPAD 1022 +#define IDH_DIALER_LOG 1023 +#define IDH_DIALER_OPTIONS_PROPERTIES 1024 +#define IDH_DIALER_BUTTONS 1025 diff --git a/private/tapi/dev/apps/dialer/nextver/linebusy.ico b/private/tapi/dev/apps/dialer/nextver/linebusy.ico Binary files differnew file mode 100644 index 000000000..589f2671b --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/linebusy.ico diff --git a/private/tapi/dev/apps/dialer/nextver/makefile b/private/tapi/dev/apps/dialer/nextver/makefile new file mode 100644 index 000000000..f1084966b --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/makefile @@ -0,0 +1,29 @@ +!if "$(OS)" == "Windows_NT" + +!INCLUDE $(NTMAKEENV)\makefile.def + +!else + +############################################################################## +# +# Dialer.exe Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\.. + +VERSIONLIST=debug retail + +DEPENDNAME=depend.mk + +COMMONMKFILE=makefile.def + +IS_OEM=TRUE +IS_32 = TRUE + +!include $(ROOT)\dev\master.mk + +!endif + diff --git a/private/tapi/dev/apps/dialer/nextver/makefile.def b/private/tapi/dev/apps/dialer/nextver/makefile.def new file mode 100644 index 000000000..1eb194df8 --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/makefile.def @@ -0,0 +1,50 @@ +############################################################################## +# +# Dialer Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\..\.. + + +IS_OEM=1 +WANT_C932=1 +IS_32 = TRUE +WIN32=1 + +DEPENDNAME=..\depend.mk + +DRVNAME=dialer +TARGETS=dialer.exe + +DEFENTRY = WinMain + +SRCDIR=.. + +BUILD_COFF=1 + +L32EXE=dialer.exe # Name of exe. +L32DEF=..\dialer.def # Our def file. +L32MAP=dialer.map # Our map file. +L32SYM=dialer.sym # Our sym file. +L32LIBS= \ + $(W32LIBID)\user32.lib \ + $(W32LIBID)\gdi32.lib \ + $(W32LIBID)\kernel32.lib \ + $(DEVROOT)\sdk\lib\tapi32.lib \ + $(DEVROOT)\tools\c932\lib\oldnames.lib \ + $(DEVROOT)\tools\c932\lib\msvcrt.lib \ + $(DEVROOT)\sdk\lib\shell32.lib + +L32RES=dialer.res # Resource file. +L32OBJS = dialer.obj + +!include $(ROOT)\dev\master.mk + +CFLAGS=$(CFLAGS) -DWIN32=100 -DWIN_32=100 -Og + +!IF "$(VERDIR)" == "debug" +CFLAGS = $(CFLAGS) -DDBG=1 +!endif diff --git a/private/tapi/dev/apps/dialer/nextver/nt.mak b/private/tapi/dev/apps/dialer/nextver/nt.mak new file mode 100644 index 000000000..a93df1f2d --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/nt.mak @@ -0,0 +1,27 @@ +!include <ntwin32.mak> + +!ifndef MYDEBUG +MYDEBUG = 0 +!endif + +!if $(MYDEBUG) +L_FLAGS = $(linkdebug) +!else +L_FLAGS = +!endif + +APPLIBS=\telephon\tapi\lib\tapi32.lib + +OBJS=ui.obj vars.obj tb.obj widget.obj + +all: tb.exe + +.c.obj: + $(cc) -DTAPI_1_1 $(cdebug) $(cflags) $(cvars) $*.c + +tb.rbj: tb.rc + $(rc) -DTAPI_1_1 $(rcvars) -r -fo tb.res tb.rc + cvtres -$(CPU) tb.res -o tb.rbj + +tb.exe: $(OBJS) tb.rbj tb.def + $(link) $(L_FLAGS) $(guiflags) -out:tb14.exe $(OBJS) tb.rbj $(APPLIBS) $(guilibsdll) diff --git a/private/tapi/dev/apps/dialer/nextver/resource.h b/private/tapi/dev/apps/dialer/nextver/resource.h new file mode 100644 index 000000000..0296f8654 --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/resource.h @@ -0,0 +1,155 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by dialer.RC +// +#define IDI_DIALER 1 +#define IDD_DDIAL 1 +#define IDI_LINEBUSY 116 +#define IDA_DIALER 117 +#define IDM_MENU 118 +#define IDD_DIALER 200 +#define IDD_DCOMBO 201 +#define IDD_DBUTTON1 202 +#define IDD_DBUTTON2 203 +#define IDD_DBUTTON3 204 +#define IDD_DBUTTON4 205 +#define IDD_DBUTTON5 206 +#define IDD_DBUTTON6 207 +#define IDD_DBUTTON7 208 +#define IDD_DBUTTON8 209 +#define IDD_DBUTTON9 210 +#define IDD_DBUTTON0 211 +#define IDD_DBUTTONSTAR 212 +#define IDD_DBUTTONPOUND 213 +#define IDD_DSPEEDDIAL1 214 +#define IDD_DSPEEDDIAL2 215 +#define IDD_DSPEEDDIAL3 216 +#define IDD_DSPEEDDIAL4 217 +#define IDD_DSPEEDDIAL5 218 +#define IDD_DSPEEDDIAL6 219 +#define IDD_DSPEEDDIAL7 220 +#define IDD_DSPEEDDIAL8 221 +#define IDD_DSPEEDDIALGRP 222 +#define IDD_DNUMTODIAL 223 +#define IDD_DRECTSEPARATOR 224 +#define IDD_DSPEEDDIALTEXT1 225 +#define IDD_DSPEEDDIALTEXT2 226 +#define IDD_DSPEEDDIALTEXT3 227 +#define IDD_DSPEEDDIALTEXT4 228 +#define IDD_DSPEEDDIALTEXT5 229 +#define IDD_DSPEEDDIALTEXT6 230 +#define IDD_DSPEEDDIALTEXT7 231 +#define IDD_DSPEEDDIALTEXT8 232 +#define IDD_SD1 300 +#define IDD_SD1SPEEDDIAL1 301 +#define IDD_SD1SPEEDDIAL2 302 +#define IDD_SD1SPEEDDIAL3 303 +#define IDD_SD1SPEEDDIAL4 304 +#define IDD_SD1SPEEDDIAL5 305 +#define IDD_SD1SPEEDDIAL6 306 +#define IDD_SD1SPEEDDIAL7 307 +#define IDD_SD1SPEEDDIAL8 308 +#define IDD_SD1EDITNAME 317 +#define IDD_SD1EDITNUMBER 318 +#define IDD_SD1TEXTCHOOSE 319 +#define IDD_SD1TEXTENTER 320 +#define IDD_SD1TEXTNAME 321 +#define IDD_SD1TEXTNUMBER 322 +#define IDD_SD1RECTSEPARATOR 323 +#define IDD_SD1SPEEDDIALTEXT1 324 +#define IDD_SD1SPEEDDIALTEXT2 325 +#define IDD_SD1SPEEDDIALTEXT3 326 +#define IDD_SD1SPEEDDIALTEXT4 327 +#define IDD_SD1SPEEDDIALTEXT5 328 +#define IDD_SD1SPEEDDIALTEXT6 329 +#define IDD_SD1SPEEDDIALTEXT7 330 +#define IDD_SD1SPEEDDIALTEXT8 331 +#define IDD_SD2 400 +#define IDD_SD2SAVEANDDIAL 401 +#define IDD_SD2EDITNAME 402 +#define IDD_SD2EDITNUMBER 403 +#define IDD_SD2TEXTENTER 404 +#define IDD_SD2TEXTNAME 405 +#define IDD_SD2TEXTNUMBER 406 +#define IDD_CONNECTUSING 500 +#define IDD_CULISTLINE 501 +#define IDD_CULISTADDRESS 502 +#define IDD_CUSIMPLETAPICHKBOX 503 +#define IDD_CUTEXTLINE 504 +#define IDD_CUTEXTADDRESS 505 +#define IDD_CUPROPERTIES 506 +#define IDD_ABOUT 700 +#define IDD_AICON 701 +#define IDD_ATEXTTITLE 702 +#define IDD_ATEXTVERSION 703 +#define IDD_ATEXTWINMODE 704 +#define IDD_ATEXTFREEMEM 705 +#define IDD_ATEXTRESOURCE 706 +#define IDD_ATEXTCOPYRIGHT 707 +#define IDD_INUSE 900 +#define IDD_IUICON 901 +#define ikszAppName 901 +#define IDD_IUTEXT1 902 +#define ikszAppFriendlyName 902 +#define IDD_IUTEXT2 903 +#define ikszErrDefault 940 +#define ikszErrOOM 941 +#define ikszErrTAPI 942 +#define ikszErrNoVoiceLine 943 +#define ikszErrInvalAddress 945 +#define ikszErrLineInitWrongDrivers 949 +#define ikszErrAddrBlocked 950 +#define ikszErrBillingRejected 952 +#define ikszErrResUnavail 956 +#define ikszWarningTitle 977 +#define ikszWarningRegisterSTapi 978 +#define ikszWarningFor911 978 +#define ikszWarningNewDefault 979 +#define IDM_EXIT 1000 +#define IDM_EDIT_CUT 1001 +#define IDM_EDIT_COPY 1002 +#define IDD_DGNUMBERTEXT 1002 +#define IDM_EDIT_PASTE 1003 +#define IDM_EDIT_DELETE 1004 +#define IDD_DGNAMETEXT 1004 +#define IDM_EDIT_SPEEDDIAL 1005 +#define IDM_CONNECTUSING 1006 +#define IDM_LOCATION 1008 +#define IDM_HELP_CONTENTS 1010 +#define IDM_ABOUT 1011 +#define IDM_ACCEL_NUMTODIAL 1012 +#define ikszErrLineInitBadIniFile 1013 +#define IDM_ACCEL_HELP 1013 +#define ikszErrLineInitNoDriver 1014 +#define ikszErrBadTAPIAddr 1015 +#define IDM_HELP_WHATSTHIS 1015 +#define ikszErrLineInitNoDevice 1016 +#define ikszErrNoMultipleInstance 1020 +#define IDD_CALLFAILED 1300 +#define IDD_CFTEXT 1301 +#define ikszWarning911 1544 +#define ikszDisconnectedReject 1545 +#define ikszDisconnectedBusy 1546 +#define ikszDisconnectedNoAnswer 1547 +#define ikszDisconnectedCantDo 1548 +#define ikszDisconnectedNetwork 1549 +#define ikszDisconnectedIncompatible 1550 +#define ikszErrInvalCallState 1551 +#define ikszWarningTapiReInit 1552 +#define ikszErrLineClose 1553 +#define ikszDisconnectedNoDialTone 1554 +#define ikszErrInvalidCountryCode 1555 +#define IDD_DIALING 9115 +#define IDD_CUERRORTEXT -1 +#define IDD_DGNUMBER -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 9116 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1005 +#define _APS_NEXT_SYMED_VALUE 9101 +#endif +#endif diff --git a/private/tapi/dev/apps/dialer/nextver/sources b/private/tapi/dev/apps/dialer/nextver/sources new file mode 100644 index 000000000..0e80d7fe8 --- /dev/null +++ b/private/tapi/dev/apps/dialer/nextver/sources @@ -0,0 +1,59 @@ +!IF 0 + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + +Author: + + John Rogers (JohnRo) 25-Oct-1991 + +Notes: + + Commented description of this file is in \nt\public\oak\bin\sources.tpl + +Revision History: + +!ENDIF + + +MAJORCOMP=net +MINORCOMP=tapi + +TARGETNAME=dialer +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=PROGRAM + +TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\comdlg32.lib \ + $(BASEDIR)\public\sdk\lib\*\shell32.lib \ + $(BASEDIR)\public\sdk\lib\*\tapi32.lib +!if 0 +# $(BASEDIR)\public\sdk\lib\*\oldnames.lib +!endif + +INCLUDES=.;$(BASEDIR)\public\sdk\inc + +USE_CRTDLL=1 + +SOURCES=dialer.c \ + dialer.rc + +C_DEFINES=-DWINVER=0x0400 + +UMTYPE=windows + +UMENTRY=winmain + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF diff --git a/private/tapi/dev/apps/dialer/nt.mak b/private/tapi/dev/apps/dialer/nt.mak new file mode 100644 index 000000000..a93df1f2d --- /dev/null +++ b/private/tapi/dev/apps/dialer/nt.mak @@ -0,0 +1,27 @@ +!include <ntwin32.mak> + +!ifndef MYDEBUG +MYDEBUG = 0 +!endif + +!if $(MYDEBUG) +L_FLAGS = $(linkdebug) +!else +L_FLAGS = +!endif + +APPLIBS=\telephon\tapi\lib\tapi32.lib + +OBJS=ui.obj vars.obj tb.obj widget.obj + +all: tb.exe + +.c.obj: + $(cc) -DTAPI_1_1 $(cdebug) $(cflags) $(cvars) $*.c + +tb.rbj: tb.rc + $(rc) -DTAPI_1_1 $(rcvars) -r -fo tb.res tb.rc + cvtres -$(CPU) tb.res -o tb.rbj + +tb.exe: $(OBJS) tb.rbj tb.def + $(link) $(L_FLAGS) $(guiflags) -out:tb14.exe $(OBJS) tb.rbj $(APPLIBS) $(guilibsdll) diff --git a/private/tapi/dev/apps/dialer/resource.h b/private/tapi/dev/apps/dialer/resource.h new file mode 100644 index 000000000..0296f8654 --- /dev/null +++ b/private/tapi/dev/apps/dialer/resource.h @@ -0,0 +1,155 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by dialer.RC +// +#define IDI_DIALER 1 +#define IDD_DDIAL 1 +#define IDI_LINEBUSY 116 +#define IDA_DIALER 117 +#define IDM_MENU 118 +#define IDD_DIALER 200 +#define IDD_DCOMBO 201 +#define IDD_DBUTTON1 202 +#define IDD_DBUTTON2 203 +#define IDD_DBUTTON3 204 +#define IDD_DBUTTON4 205 +#define IDD_DBUTTON5 206 +#define IDD_DBUTTON6 207 +#define IDD_DBUTTON7 208 +#define IDD_DBUTTON8 209 +#define IDD_DBUTTON9 210 +#define IDD_DBUTTON0 211 +#define IDD_DBUTTONSTAR 212 +#define IDD_DBUTTONPOUND 213 +#define IDD_DSPEEDDIAL1 214 +#define IDD_DSPEEDDIAL2 215 +#define IDD_DSPEEDDIAL3 216 +#define IDD_DSPEEDDIAL4 217 +#define IDD_DSPEEDDIAL5 218 +#define IDD_DSPEEDDIAL6 219 +#define IDD_DSPEEDDIAL7 220 +#define IDD_DSPEEDDIAL8 221 +#define IDD_DSPEEDDIALGRP 222 +#define IDD_DNUMTODIAL 223 +#define IDD_DRECTSEPARATOR 224 +#define IDD_DSPEEDDIALTEXT1 225 +#define IDD_DSPEEDDIALTEXT2 226 +#define IDD_DSPEEDDIALTEXT3 227 +#define IDD_DSPEEDDIALTEXT4 228 +#define IDD_DSPEEDDIALTEXT5 229 +#define IDD_DSPEEDDIALTEXT6 230 +#define IDD_DSPEEDDIALTEXT7 231 +#define IDD_DSPEEDDIALTEXT8 232 +#define IDD_SD1 300 +#define IDD_SD1SPEEDDIAL1 301 +#define IDD_SD1SPEEDDIAL2 302 +#define IDD_SD1SPEEDDIAL3 303 +#define IDD_SD1SPEEDDIAL4 304 +#define IDD_SD1SPEEDDIAL5 305 +#define IDD_SD1SPEEDDIAL6 306 +#define IDD_SD1SPEEDDIAL7 307 +#define IDD_SD1SPEEDDIAL8 308 +#define IDD_SD1EDITNAME 317 +#define IDD_SD1EDITNUMBER 318 +#define IDD_SD1TEXTCHOOSE 319 +#define IDD_SD1TEXTENTER 320 +#define IDD_SD1TEXTNAME 321 +#define IDD_SD1TEXTNUMBER 322 +#define IDD_SD1RECTSEPARATOR 323 +#define IDD_SD1SPEEDDIALTEXT1 324 +#define IDD_SD1SPEEDDIALTEXT2 325 +#define IDD_SD1SPEEDDIALTEXT3 326 +#define IDD_SD1SPEEDDIALTEXT4 327 +#define IDD_SD1SPEEDDIALTEXT5 328 +#define IDD_SD1SPEEDDIALTEXT6 329 +#define IDD_SD1SPEEDDIALTEXT7 330 +#define IDD_SD1SPEEDDIALTEXT8 331 +#define IDD_SD2 400 +#define IDD_SD2SAVEANDDIAL 401 +#define IDD_SD2EDITNAME 402 +#define IDD_SD2EDITNUMBER 403 +#define IDD_SD2TEXTENTER 404 +#define IDD_SD2TEXTNAME 405 +#define IDD_SD2TEXTNUMBER 406 +#define IDD_CONNECTUSING 500 +#define IDD_CULISTLINE 501 +#define IDD_CULISTADDRESS 502 +#define IDD_CUSIMPLETAPICHKBOX 503 +#define IDD_CUTEXTLINE 504 +#define IDD_CUTEXTADDRESS 505 +#define IDD_CUPROPERTIES 506 +#define IDD_ABOUT 700 +#define IDD_AICON 701 +#define IDD_ATEXTTITLE 702 +#define IDD_ATEXTVERSION 703 +#define IDD_ATEXTWINMODE 704 +#define IDD_ATEXTFREEMEM 705 +#define IDD_ATEXTRESOURCE 706 +#define IDD_ATEXTCOPYRIGHT 707 +#define IDD_INUSE 900 +#define IDD_IUICON 901 +#define ikszAppName 901 +#define IDD_IUTEXT1 902 +#define ikszAppFriendlyName 902 +#define IDD_IUTEXT2 903 +#define ikszErrDefault 940 +#define ikszErrOOM 941 +#define ikszErrTAPI 942 +#define ikszErrNoVoiceLine 943 +#define ikszErrInvalAddress 945 +#define ikszErrLineInitWrongDrivers 949 +#define ikszErrAddrBlocked 950 +#define ikszErrBillingRejected 952 +#define ikszErrResUnavail 956 +#define ikszWarningTitle 977 +#define ikszWarningRegisterSTapi 978 +#define ikszWarningFor911 978 +#define ikszWarningNewDefault 979 +#define IDM_EXIT 1000 +#define IDM_EDIT_CUT 1001 +#define IDM_EDIT_COPY 1002 +#define IDD_DGNUMBERTEXT 1002 +#define IDM_EDIT_PASTE 1003 +#define IDM_EDIT_DELETE 1004 +#define IDD_DGNAMETEXT 1004 +#define IDM_EDIT_SPEEDDIAL 1005 +#define IDM_CONNECTUSING 1006 +#define IDM_LOCATION 1008 +#define IDM_HELP_CONTENTS 1010 +#define IDM_ABOUT 1011 +#define IDM_ACCEL_NUMTODIAL 1012 +#define ikszErrLineInitBadIniFile 1013 +#define IDM_ACCEL_HELP 1013 +#define ikszErrLineInitNoDriver 1014 +#define ikszErrBadTAPIAddr 1015 +#define IDM_HELP_WHATSTHIS 1015 +#define ikszErrLineInitNoDevice 1016 +#define ikszErrNoMultipleInstance 1020 +#define IDD_CALLFAILED 1300 +#define IDD_CFTEXT 1301 +#define ikszWarning911 1544 +#define ikszDisconnectedReject 1545 +#define ikszDisconnectedBusy 1546 +#define ikszDisconnectedNoAnswer 1547 +#define ikszDisconnectedCantDo 1548 +#define ikszDisconnectedNetwork 1549 +#define ikszDisconnectedIncompatible 1550 +#define ikszErrInvalCallState 1551 +#define ikszWarningTapiReInit 1552 +#define ikszErrLineClose 1553 +#define ikszDisconnectedNoDialTone 1554 +#define ikszErrInvalidCountryCode 1555 +#define IDD_DIALING 9115 +#define IDD_CUERRORTEXT -1 +#define IDD_DGNUMBER -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 9116 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1005 +#define _APS_NEXT_SYMED_VALUE 9101 +#endif +#endif diff --git a/private/tapi/dev/apps/dialer/sources b/private/tapi/dev/apps/dialer/sources new file mode 100644 index 000000000..0e80d7fe8 --- /dev/null +++ b/private/tapi/dev/apps/dialer/sources @@ -0,0 +1,59 @@ +!IF 0 + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + +Author: + + John Rogers (JohnRo) 25-Oct-1991 + +Notes: + + Commented description of this file is in \nt\public\oak\bin\sources.tpl + +Revision History: + +!ENDIF + + +MAJORCOMP=net +MINORCOMP=tapi + +TARGETNAME=dialer +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=PROGRAM + +TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\comdlg32.lib \ + $(BASEDIR)\public\sdk\lib\*\shell32.lib \ + $(BASEDIR)\public\sdk\lib\*\tapi32.lib +!if 0 +# $(BASEDIR)\public\sdk\lib\*\oldnames.lib +!endif + +INCLUDES=.;$(BASEDIR)\public\sdk\inc + +USE_CRTDLL=1 + +SOURCES=dialer.c \ + dialer.rc + +C_DEFINES=-DWINVER=0x0400 + +UMTYPE=windows + +UMENTRY=winmain + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF diff --git a/private/tapi/dev/apps/dialer/version.rc b/private/tapi/dev/apps/dialer/version.rc new file mode 100644 index 000000000..7d824cc20 --- /dev/null +++ b/private/tapi/dev/apps/dialer/version.rc @@ -0,0 +1,66 @@ +// +// (c) 1995 Microsoft Corporation. All Rights Reserved. +// +/* Version Numbering stuff */ + +#define VER_FILEDESCRIPTION_STR "Microsoft\256 Windows(TM) Phone Dialer" +#define VER_INTERNALNAME_STR "Phone Dialer" +#define VER_ORIGINALFILENAME_STR "dialer.exe" + +#ifdef SDKRELEASE +#include <ver.h> + +#define VER_PRODUCTVERSION_STR "1.00.150" +#define VER_PRODUCTVERSION 1,0,0,150 + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VER_PRODUCTVERSION +PRODUCTVERSION VER_PRODUCTVERSION +FILEFLAGSMASK VS_FF_DEBUG | VS_FF_PRERELEASE +FILEFLAGS VS_FF_DEBUG | VS_FF_PRERELEASE +FILEOS VOS__WINDOWS16 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", "Microsoft Corporation", "\0" + VALUE "FileDescription", VER_FILEDESCRIPTION_STR, "\0" + VALUE "FileVersion", VER_PRODUCTVERSION_STR, "\0" + VALUE "InternalName", VER_INTERNALNAME_STR, "\0" + VALUE "LegalCopyright", "Copyright 1995 Microsoft Corp", "\0" + VALUE "OriginalFilename",VER_ORIGINALFILENAME_STR, "\0" + VALUE "ProductName", "Windows Telephony", "\0" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR, "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + /* the following line should be extended for localized versions */ + VALUE "Translation", 0x0409, 0x04E4 + END +END +#else + + +// Is the following FLAG good to use for this? +#ifdef NT_INST +#include <ntverp.h> +#else +#include <version.h> +#endif + +#define VER_LEGALCOPYRIGHT_STR "Copyright \251 Microsoft Corporation 1995. All Rights Reserved." + +#define VER_FILETYPE VFT_APP +#define VER_FILESUBTYPE VFT2_UNKNOWN + +#include <common.ver> + +// ///////////////////////////////////////////////////////////////////////// +// ///////////////////////////////////////////////////////////////////////// + +// #include <tapiver.h> +// #include <common.ver> +#endif diff --git a/private/tapi/dev/apps/dialer/win31.mak b/private/tapi/dev/apps/dialer/win31.mak new file mode 100644 index 000000000..0481e0d68 --- /dev/null +++ b/private/tapi/dev/apps/dialer/win31.mak @@ -0,0 +1,39 @@ +!ifndef TAPI_1_1 +TAPI_1_1 = 0 +!endif + +!ifndef MYDEBUG +MYDEBUG = 0 +!endif + +!if $(TAPI_1_1) +TAPI_VER_FLAGS = -DTAPI_1_1 +TAPILIB = ..\..\lib\i386\tapi.lib +TAPIINC = -I..\..\inc +TARGET = ..\..\lib\i386\tb1416.exe +!else +TAPI_VER_FLAGS = +TAPILIB = ..\..\lib\tapi10\tapi.lib +TAPIINC = -I..\..\inc\tapi10 +TARGET = ..\..\lib\i386\tb13.exe +!endif + +!if $(MYDEBUG) +C_FLAGS = -AL -G2s -W3 -GA -GEf -Zp /Od /Oi /Zi +!else +C_FLAGS = -AL -G2s -W3 -GA -GEf -Zp /Od /Oi +!endif + + +OBJS=ui.obj vars.obj tb.obj widget.obj + +all : $(TARGET) + +.c.obj: + cl -c $(TAPI_VER_FLAGS) $(TAPIINC) $(C_FLAGS) $*.c + +$(TARGET) : $(OBJS) tb.def tb.rc + rc -r $(TAPI_VER_FLAGS) tb.rc + link $(OBJS),$(TARGET),tb.map,libw.lib /MAP:FULL /COD /NOD:llibce llibcew commdlg $(TAPILIB),tb.def + rc -k tb.res $(TARGET) + mapsym tb diff --git a/private/tapi/dev/apps/dirs b/private/tapi/dev/apps/dirs new file mode 100644 index 000000000..556cbb1a4 --- /dev/null +++ b/private/tapi/dev/apps/dirs @@ -0,0 +1,27 @@ +!IF 0 + +Copyright (c) 1989-92 Microsoft Corporation + +Module Name: + + dirs. + +Abstract: + + This file specifies the subdirectories of the current directory that + contain component makefiles. + + +Author: + + Steve Wood (stevewo) 17-Apr-1990 + +NOTE: Commented description of this file is in \nt\public\oak\bin\dirs.tpl + +!ENDIF + +DIRS=\ + tb \ + dialer \ + tapitna \ + tapiupr diff --git a/private/tapi/dev/apps/enumtapi/depend.mk b/private/tapi/dev/apps/enumtapi/depend.mk new file mode 100644 index 000000000..beb7ce4bb --- /dev/null +++ b/private/tapi/dev/apps/enumtapi/depend.mk @@ -0,0 +1 @@ +.\enumtapi.obj: ..\enumtapi.c diff --git a/private/tapi/dev/apps/enumtapi/enumtapi.c b/private/tapi/dev/apps/enumtapi/enumtapi.c new file mode 100644 index 000000000..f6c737477 --- /dev/null +++ b/private/tapi/dev/apps/enumtapi/enumtapi.c @@ -0,0 +1,257 @@ +#include <windows.h> +#include <tapi.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +char szAppName[] = "TapiTest"; + +#define APIVERSION 0x00010004 + +// TAPI global variables. +HINSTANCE hInstance; +HLINEAPP hLineApp; +DWORD dwNumDevs; +long lReturn; + +void CALLBACK lineCallbackFunc( + DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance, + DWORD dwParam1, DWORD dwParam2, DWORD dwParam3); +void PrintTapiLines(DWORD dwDeviceID); + +int main (int argc, char * argv[], char * envp[]) +{ + MSG msg; + DWORD i; + + // Prime the message queue + PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); + + hInstance = GetModuleHandle(NULL); + + if (lReturn = lineInitialize(&hLineApp, hInstance, lineCallbackFunc, + szAppName, &dwNumDevs)) + { + printf("lineInitialize failed: %li.\n", lReturn); + return 0; + } + + if (dwNumDevs) + { + printf( + "<- dwDeviceID\n" + "| <- Max dwAPIVersion\n" + "| | <- Number of addresses\n" + "| | | <- Supports voice comm/datamodem calls?\n" + "| | | | <- Call in progress?\n" + "| | | | | <- Any application waiting for calls?\n" + "| | | | | | <- Service Povider - Line Device Name\n" + "V V V V V V V\n" + ); + for (i=0;i<dwNumDevs;i++) + { + PrintTapiLines(i); + } + } + else + printf("No TAPI Line devices installed.\n"); + + lineShutdown(hLineApp); +} + +void PrintTapiLines(DWORD dwDeviceID) +{ + BOOL bSupportsDataComm = TRUE; + + DWORD dwApiVersion; + LINEEXTENSIONID ExtensionID; + HLINE hLine; + DWORD dwAddressID = 0; + + VARSTRING SmallVarString; + + BYTE bufferLDC[4096]; + LPLINEDEVCAPS lpLineDevCaps = (LPLINEDEVCAPS) bufferLDC; + + BYTE bufferLDS[4096]; + LPLINEDEVSTATUS lpLineDevStatus = (LPLINEDEVSTATUS) bufferLDS; + + static BYTE bufferLPL[4096]; + static LPLINEPROVIDERLIST lpLineProviderList = + (LPLINEPROVIDERLIST) bufferLPL; + static LPLINEPROVIDERENTRY lpLineProviderEntry; + DWORD dwCount; + + char * lpszLineName; + char szLineUnavail[] = "Line Unavailable"; + char szLineUnnamed[] = "Line Unnamed"; + char szLineNameEmpty[] = "Line Name is Empty"; + + lpLineDevCaps ->dwTotalSize = sizeof(bufferLDC); + lpLineDevStatus ->dwTotalSize = sizeof(bufferLDS); + lpLineProviderList->dwTotalSize = sizeof(bufferLPL); + SmallVarString .dwTotalSize = sizeof(VARSTRING); + + if (!lpLineProviderEntry) + { + lpLineProviderList->dwTotalSize = sizeof(bufferLPL); + lineGetProviderList(0x00010004, lpLineProviderList); + lpLineProviderEntry = (LPLINEPROVIDERENTRY) + ((BYTE *) lpLineProviderList + + lpLineProviderList->dwProviderListOffset); + } + + printf("%-2lu, ", dwDeviceID); + + lReturn = lineNegotiateAPIVersion (hLineApp, dwDeviceID, + 0x00010003, 0x00FF0004, &dwApiVersion, &ExtensionID); + + if (lReturn) + { + printf("lineNegotiateAPIVersion error: %li\n", lReturn); + return; + } + + printf("%lx.%lx, ", (dwApiVersion&0xFFFF0000)/0x00010000, + dwApiVersion&0x0000FFFF); + + lReturn = lineNegotiateAPIVersion (hLineApp, dwDeviceID, + APIVERSION, APIVERSION, &dwApiVersion, &ExtensionID); + + if (lReturn == LINEERR_INCOMPATIBLEAPIVERSION) + bSupportsDataComm = FALSE; + else if (lReturn) + { + printf("lineNegotiateAPIVersion error: %li\n", lReturn); + return; + } + +//printf("\r\nAbout to call linegetdevcaps"); + + lReturn = lineGetDevCaps(hLineApp, dwDeviceID, + dwApiVersion, 0, lpLineDevCaps); + +//printf("\r\nDone\r\n"); + + if (lReturn) + { + printf("lineGetDevCaps error: %li\n", lReturn); + return; + } + +//printf("\r\nprint\r\n"); + + printf("%lu, ", lpLineDevCaps->dwNumAddresses); + +//printf("\r\nDone2\r\n"); + + // TODO list available bearer modes + + if (!(lpLineDevCaps->dwBearerModes & LINEBEARERMODE_VOICE )) + bSupportsDataComm = FALSE; + + if (!(lpLineDevCaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM)) + bSupportsDataComm = FALSE; + + if (!(lpLineDevCaps->dwLineFeatures & LINEFEATURE_MAKECALL)) + bSupportsDataComm = FALSE; + + lReturn = lineOpen(hLineApp, dwDeviceID, &hLine, + dwApiVersion, 0, 0, LINECALLPRIVILEGE_NONE, 0, 0); + + if(lReturn == LINEERR_ALLOCATED) + { + printf("Line is already in use by a non-TAPI app or another TSP\n"); + return; + } + + if (lReturn) + { + printf("lineOpen error: %li\n", lReturn); + return; + } + + // Make sure the "comm/datamodem" device class is supported + // Note that we don't want any of the 'extra' information + // normally returned in the VARSTRING structure. All we care + // about is if lineGetID succeeds. + lReturn = lineGetID(hLine, 0, 0, LINECALLSELECT_LINE, + &SmallVarString, "comm/datamodem"); + + if (lReturn) + bSupportsDataComm = FALSE; + + if (bSupportsDataComm) + printf("Y, "); + else + printf("N, "); + + // TODO list calls already in progress. + + lReturn = lineGetLineDevStatus(hLine, lpLineDevStatus); + if (lReturn) + { + printf("lineGetLineDevStatus error: %li\n", lReturn); + return; + } + + if (lpLineDevStatus->dwNumActiveCalls || + lpLineDevStatus->dwNumOnHoldCalls || + lpLineDevStatus->dwNumOnHoldPendCalls) + printf("Y, "); + else + printf("N, "); + + if (lpLineDevStatus->dwOpenMediaModes) + printf("Y, "); + else + printf("N, "); + + + dwCount = lpLineProviderList->dwNumProviders; + while(dwCount--) + { + if (HIWORD(lpLineDevCaps->dwPermanentLineID) == + lpLineProviderEntry[dwCount].dwPermanentProviderID) + { + printf("%s - ", (char *) + ((BYTE *) lpLineProviderList + + lpLineProviderEntry[dwCount].dwProviderFilenameOffset)); + dwCount = 1; + break; + } + } + if (dwCount != 1) + printf("Unknown TSP - "); + + if ((lpLineDevCaps -> dwLineNameSize) && + (lpLineDevCaps -> dwLineNameOffset) && + (lpLineDevCaps -> dwStringFormat == STRINGFORMAT_ASCII)) + { + // This is the name of the device. + lpszLineName = (char *) + ((BYTE *) lpLineDevCaps + lpLineDevCaps -> dwLineNameOffset); + + if (lpszLineName[0] != '\0') + { + // If the device name is not null terminated, null + // terminate it. Yes, this looses the end character. + // Its a bug in the service provider. + lpszLineName[lpLineDevCaps->dwLineNameSize-1] = '\0'; + } + else // Line name started with a NULL. + lpszLineName = szLineNameEmpty; + } + else // DevCaps doesn't have a valid line name. Unnamed. + lpszLineName = szLineUnnamed; + + printf("%s\n",lpszLineName); + lineClose(hLine); +} + + +void CALLBACK lineCallbackFunc( + DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance, + DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) +{ +} diff --git a/private/tapi/dev/apps/enumtapi/makefile b/private/tapi/dev/apps/enumtapi/makefile new file mode 100644 index 000000000..b72e1a9ac --- /dev/null +++ b/private/tapi/dev/apps/enumtapi/makefile @@ -0,0 +1,30 @@ + +!if "$(OS)" == "Windows_NT" + +!INCLUDE $(NTMAKEENV)\makefile.def + +!else + +############################################################################## +# +# enumtapi.exe Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\.. + +VERSIONLIST=debug retail + +DEPENDNAME=depend.mk + +COMMONMKFILE=makefile.def + +IS_OEM=TRUE +IS_32 = TRUE + +!include $(ROOT)\dev\master.mk + +!endif + diff --git a/private/tapi/dev/apps/enumtapi/makefile.def b/private/tapi/dev/apps/enumtapi/makefile.def new file mode 100644 index 000000000..df65e8ef8 --- /dev/null +++ b/private/tapi/dev/apps/enumtapi/makefile.def @@ -0,0 +1,53 @@ +############################################################################## +# +# enumtapi Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\..\.. + + +WANT_C1032=1 +IS_32 = TRUE +WIN32=1 +IS_OEM = TRUE + +DEPENDNAME=..\depend.mk + +DRVNAME=enumtapi +TARGETS=enumtapi.exe + +SRCDIR=.. + +#BUILD_COFF=1 + +DEFENTRY=main +DEFSUBSYSTEM=CONSOLE + +L32EXE=enumtapi.exe # Name of exe. +#L32DEF=..\enumtapi.def # Our def file. +L32MAP=enumtapi.map # Our map file. +L32LIBS= \ + $(W32LIBID)\kernel32.lib \ + $(W32LIBID)\user32.lib \ + $(ROOT)\dev\tools\c1032\lib\msvcrt.lib \ + $(W32LIBID)\tapi32.lib \ + +#L32RES=enumtapi.res # Resource file. + +L32OBJS = enumtapi.obj + + +L32FLAGS=$(L32FLAGS) /PDB:enumtapi.pdb /MAP:enumtapi.map + +!include $(ROOT)\dev\master.mk + + +#CFLAGS=$(CFLAGS) -DWIN32=100 -DWIN_32=100 -Od -Fc +CFLAGS=$(CFLAGS) -DWIN32=100 -DWIN_32=100 -Og + +!IF "$(VERDIR)" == "debug" +CFLAGS = $(CFLAGS) -DDBG=1 +!endif diff --git a/private/tapi/dev/apps/extidgen/depend.mk b/private/tapi/dev/apps/extidgen/depend.mk new file mode 100644 index 000000000..3157782dc --- /dev/null +++ b/private/tapi/dev/apps/extidgen/depend.mk @@ -0,0 +1,3 @@ +.\extidgen.obj: ..\extidgen.c + +.\extidgen.res: ..\extidgen.rc diff --git a/private/tapi/dev/apps/extidgen/extidgen.c b/private/tapi/dev/apps/extidgen/extidgen.c new file mode 100644 index 000000000..d94abd5ed --- /dev/null +++ b/private/tapi/dev/apps/extidgen/extidgen.c @@ -0,0 +1,73 @@ +#include <windows.h> +#include <rpcdce.h> + + +int WINAPI WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow + ) +{ + TCHAR buf[1024]; + TCHAR buf2[1024]; + HANDLE hclipbuf; + LPVOID clipbuf; + + union { + UUID uuid; + DWORD dwData[4]; + }u; + + +// +// wsprintf (buf, "\nMicrosoft Extension ID Generator v%s\n", version); +// lstrcat(buf, "Copyright 1993-1995 Microsoft Corporation. All Rights Reserved.\n"); +// lstrcat(buf, "A component of the Windows Telephony Software Development Kit.\n\n"); +// lstrcat(buf, "Usage: EXTIDGEN\n"); + + + if (UuidCreate ((UUID *)&u)) + { + wsprintf (buf, "An extended media mode ID could not be generated.\n(You must have NetBIOS loaded to generate an extension ID.)\n"); + MessageBox(NULL, buf, "ExtIdGen", MB_OK); + } + else + { + int i; + + + hclipbuf = GlobalAlloc( GPTR, sizeof(buf) ); + clipbuf = GlobalLock( hclipbuf ); + + + wsprintf (buf, "You may use the following extension ID as your TAPI extended media mode:\n"); + wsprintf (clipbuf, "\r\n"); + + for (i = 0; i < 4; i++) + { + wsprintf(buf2, "dwExtensionID%u = 0x%08lX;\r\n", i, u.dwData[i]); + lstrcat( buf, buf2 ); + lstrcat( clipbuf, buf2 ); + } + + + lstrcat( buf, "\r\nThis program will now exit. Should the ID be copied to the clipboard before exiting?"); + + i = MessageBox(NULL, buf, "ExtIdGen", MB_YESNO); + + + if ( IDYES == i ) + { + OpenClipboard( NULL ); + EmptyClipboard(); + SetClipboardData( CF_TEXT, hclipbuf ); + CloseClipboard(); + } + + } + +// GlobalFreePtr( clipbuf ); + + return 0; +} diff --git a/private/tapi/dev/apps/extidgen/extidgen.rc b/private/tapi/dev/apps/extidgen/extidgen.rc new file mode 100644 index 000000000..be2ac06be --- /dev/null +++ b/private/tapi/dev/apps/extidgen/extidgen.rc @@ -0,0 +1,27 @@ +#include "windows.h" + +#if TAPI_NT +#include <ntverp.h> +#else +#include <version.h> +#endif + +#define VER_FILEDESCRIPTION_STR "Microsoft\256 Windows(TM) TAPI Extended Media Mode ID Generator" +#define VER_INTERNALNAME_STR "ExtIDGen" +#define VER_ORIGINALFILENAME_STR "EXTIDGEN.EXE" +#define VER_LEGALCOPYRIGHT_YEARS "1996" + +//#undef VER_PRODUCTVERSION +//#undef VER_PRODUCTVERSION_STR +//#define VER_PRODUCTVERSION 1.00.0.0000 +//#define VER_PRODUCTVERSION_STR "1.00.0.0000" + + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT2_UNKNOWN + +#include <common.ver> + +// ///////////////////////////////////////////////////////////////////////// +// ///////////////////////////////////////////////////////////////////////// + diff --git a/private/tapi/dev/apps/extidgen/makefile b/private/tapi/dev/apps/extidgen/makefile new file mode 100644 index 000000000..cbc1f027e --- /dev/null +++ b/private/tapi/dev/apps/extidgen/makefile @@ -0,0 +1,30 @@ + +!if "$(OS)" == "Windows_NT" + +!INCLUDE $(NTMAKEENV)\makefile.def + +!else + +############################################################################## +# +# extidgen Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\.. + +VERSIONLIST=debug retail + +DEPENDNAME=depend.mk + +COMMONMKFILE=makefile.def + +IS_OEM=TRUE +IS_32 = TRUE + +!include $(ROOT)\dev\master.mk + +!endif + diff --git a/private/tapi/dev/apps/extidgen/makefile.def b/private/tapi/dev/apps/extidgen/makefile.def new file mode 100644 index 000000000..74f7b012d --- /dev/null +++ b/private/tapi/dev/apps/extidgen/makefile.def @@ -0,0 +1,57 @@ +!if "$(OS)" == "Windows_NT" + +!INCLUDE $(NTMAKEENV)\makefile.def + +!else + +############################################################################## +# +# extidgen Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\..\.. + +IS_32 = TRUE +IS_OEM = TRUE +WANT_C932=TUE + +DEPENDNAME=..\depend.mk + +TARGETS=extidgen.exe extidgen.sym + +BUILD_COFF=1 + +SRCDIR=.. + +#DEFENTRY=main + +L32EXE=extidgen.exe # Name of exe. +# L32DEF=..\extidgen.def # Our def file. +L32MAP=extidgen.map # Our map file. +L32RES=extidgen.res +L32LIBS=\ + $(ROOT)\dev\tools\c932\lib\rpcrt4.lib \ + $(ROOT)\dev\lib\kernel32.lib \ + $(ROOT)\dev\lib\user32.lib \ + $(ROOT)\dev\tools\c932\lib\msvcrt.lib +#..\llibce.lib ..\rpc.lib + + +# L32RES=extidgen.res # Resource file. + +L32OBJS=extidgen.obj + +!include $(ROOT)\dev\master.mk + + +CFLAGS=$(CFLAGS) -DCHICOBUILD=1 + + +!IF "$(VERDIR)" == "debug" +CFLAGS = $(CFLAGS) -DDBG=1 +!endif + +!endif diff --git a/private/tapi/dev/apps/extidgen/sources b/private/tapi/dev/apps/extidgen/sources new file mode 100644 index 000000000..d8fef11b4 --- /dev/null +++ b/private/tapi/dev/apps/extidgen/sources @@ -0,0 +1,25 @@ +MAJORCOMP=net +MINORCOMP=tapi + +TARGETNAME=ExtIDGen +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=PROGRAM +TARGETLIBS= \ + $(BASEDIR)\public\sdk\lib\*\kernel32.lib + +INCLUDES=$(BASEDIR)\public\sdk\inc;. + +UMENTRY=WinMain + +C_DEFINES=-DWINVER=0x0400 -DTAPI_NT=1 + +USE_CRTDLL=1 + +SOURCES=extidgen.c \ + extidgen.rc + +UMTYPE=windows + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF diff --git a/private/tapi/dev/apps/rstress/app2/app2.cpp b/private/tapi/dev/apps/rstress/app2/app2.cpp new file mode 100644 index 000000000..37e72a4b9 --- /dev/null +++ b/private/tapi/dev/apps/rstress/app2/app2.cpp @@ -0,0 +1,1215 @@ +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +#include "clntapp.h" + +////////////////////////////////////////////////////////////////////////////// +// GLOBALS +////////////////////////////////////////////////////////////////////////////// +HINSTANCE ghInstance; +HWND ghMainWnd; +ReplyStruct * pReplyStruct; +CRITICAL_SECTION csReply; +DWORD dwNumLines; +DWORD dwNumInits; +DWORD dwSleep; +DWORD dwNumThreads; +DWORD dwThreadSleep; +TCHAR szFileName[MAX_PATH]; +BOOL gbLogging; + +BOOL InitializeVariables(LPTSTR lpszCommandLine); +BOOL ESPLine(HLINEAPP hLineApp, + DWORD dwDeviceID); +BOOL ESPInstalled(); +LINEDEVCAPS * LineGetDevCaps (HLINEAPP hLineApp, + DWORD dwDeviceID); +LINEDEVSTATUS* LineGetLineDevStatus(HLINE hLine); + + + +TCHAR gszRStressKey[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Telephony\\RStress"); +TCHAR gszPlacementValue[] = TEXT("WindowPlacement"); + +DWORD MyTToL(LPTSTR lpszBuf); +void MyIToT(int i, TCHAR * szBuf); +DWORD MyRand(); +TCHAR MyToTLower(TCHAR tc); + +///////////////////////////////////////////////////////////////////////////// +// +// MACRO for logging tapi error. +// must have a local variable dwProcess ID and dwThreadID +// +///////////////////////////////////////////////////////////////////////////// +#define LOGTAPIERROR(lpszFunctionName, lRes) \ + { \ + if ((LONG)(lRes) < 0) \ + { \ + LogTapiError(lpszFunctionName, lRes, dwProcessID, dwThreadID); \ + } \ + } + +// random number stuff +#define MAX_SHORT 0xFFFF +#define BCONST 12345 + +typedef LONG (*SCENARIOPROC)(HANDLE); + +DWORD dwPrivs[] = + { + LINECALLPRIVILEGE_NONE, + LINECALLPRIVILEGE_MONITOR, + LINECALLPRIVILEGE_OWNER, + LINECALLPRIVILEGE_MONITOR | LINECALLPRIVILEGE_OWNER + }; + +DWORD dwModes[] = + { + LINEMEDIAMODE_UNKNOWN, + LINEMEDIAMODE_INTERACTIVEVOICE, + LINEMEDIAMODE_AUTOMATEDVOICE, + LINEMEDIAMODE_DATAMODEM, + LINEMEDIAMODE_G3FAX, + LINEMEDIAMODE_TDD, + LINEMEDIAMODE_G4FAX, + LINEMEDIAMODE_DIGITALDATA, + LINEMEDIAMODE_TELETEX, + LINEMEDIAMODE_VIDEOTEX, + LINEMEDIAMODE_TELEX, + LINEMEDIAMODE_MIXED, + LINEMEDIAMODE_ADSI, + LINEMEDIAMODE_VOICEVIEW, + }; + +int nummodes = sizeof(dwModes)/sizeof(DWORD); +int numprivs = sizeof(dwPrivs)/sizeof(DWORD); + +SCENARIOPROC ScenarioProcs[] = + { + Scenario4 + }; + +////////////////////////////////////////////////////////////////////////////// +// +// WinMain() +// +////////////////////////////////////////////////////////////////////////////// + +int WINAPI WinMainCRTStartup() + +//int WINAPI WinMain ( +//HINSTANCE hInstance, +// HINSTANCE hPrevInstance, +// LPSTR lpszCmdLine, +// int nCmdShow) +{ + MSG msg; + DWORD dwThreadID; + + ghInstance = GetModuleHandle(NULL); + + if (!CreateMainWindow(SW_SHOWNORMAL)) + { + return 0; + } + + InitializeVariables(GetCommandLine()); + + if (!ESPInstalled()) + { + return 0; + } + + + if (szFileName[0] == 0) + { +// MessageBox(NULL, TEXT("Failed to create log"), NULL, MB_OK); + return 0; + + } + + if (!InitLogging()) + { +// MessageBox(NULL, TEXT("Failed to create log"), NULL, MB_OK); + return 0; + } + + + CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)StartThreads, + NULL, + 0, + &dwThreadID); + + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return 1; +} + +////////////////////////////////////////////////////////////////////////////// +// +// CreateMainWindow() +// +////////////////////////////////////////////////////////////////////////////// +BOOL CreateMainWindow (int nCmdShow) +{ + WNDCLASS wc; + static TCHAR szClassName[] = TEXT("TapiClientWndClass"); + + wc.style = 0; + wc.lpfnWndProc = MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = ghInstance; + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.lpszMenuName = NULL; + wc.lpszClassName = szClassName; + + + if (!RegisterClass(&wc)) + { + return FALSE; + } + + ghMainWnd = CreateWindow(szClassName, + TEXT("Tapi Client App"), + WS_OVERLAPPEDWINDOW, + 0, + 0, + GetSystemMetrics(SM_CXSCREEN)/2, + GetSystemMetrics(SM_CYSCREEN)/2, + NULL, + NULL, + ghInstance, + NULL); + + if (ghMainWnd == NULL) + { + return FALSE; + } + + + + { + WINDOWPLACEMENT pwp; + HKEY hKey; + DWORD dwDataSize; + DWORD dwDataType; + + + + pwp.length = sizeof(WINDOWPLACEMENT); + + RegOpenKeyEx( + HKEY_CURRENT_USER, + gszRStressKey, + 0, + KEY_ALL_ACCESS, + &hKey + ); + + if ( RegQueryValueEx( + hKey, + gszPlacementValue, + 0, + &dwDataType, + (LPBYTE)&pwp, + &dwDataSize + ) ) + { + ShowWindow(ghMainWnd, nCmdShow); + } + else + { + SetWindowPlacement( ghMainWnd, &pwp ); + } + + + RegCloseKey( hKey ); + } + + + UpdateWindow(ghMainWnd); + return TRUE; +} + + +////////////////////////////////////////////////////////////////////////////// +// +// MainWndProc() +// +////////////////////////////////////////////////////////////////////////////// +LRESULT CALLBACK MainWndProc (HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) + { + case WM_DESTROY: + { + WINDOWPLACEMENT pwp; + HKEY hKey; + DWORD dwDisposition; + + + pwp.length = sizeof(WINDOWPLACEMENT); + + GetWindowPlacement( hwnd, &pwp ); + + RegCreateKeyEx( + HKEY_CURRENT_USER, + gszRStressKey, + 0, + TEXT(""), + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + 0, + &hKey, + &dwDisposition + ); + + RegSetValueEx( + hKey, + gszPlacementValue, + 0, + REG_BINARY, + (LPBYTE)&pwp, + sizeof(WINDOWPLACEMENT) + ); + + RegCloseKey( hKey ); + + + ExitProcess(0); +// PostQuitMessage(0); + } + break; + + case WM_QUIT: + ExitProcess(0); + break; + + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + return 0; +} + +BOOL InitializeVariables(LPTSTR lpszCommandLine) +{ + int i, j; + TCHAR szBuff[64]; + TCHAR tFlag; + + dwNumLines = NUMLINES; + dwNumInits = NUMINITS; + dwNumThreads = NUMTHREADS; + dwSleep = SLEEPTIME; + dwThreadSleep = THREADSLEEP; + szFileName[0] = 0; + gbLogging = FALSE; + + while (*lpszCommandLine && *lpszCommandLine != '/') + { + lpszCommandLine ++; + } + + if (!*lpszCommandLine) + { + return TRUE; + } + + while (*lpszCommandLine != NULL) + { + while((*lpszCommandLine == ' ') || + (*lpszCommandLine == '/') || + (*lpszCommandLine == '\t')) + { + lpszCommandLine++; + } + + tFlag = *lpszCommandLine; + + lpszCommandLine++; + + if (*lpszCommandLine == ':') + { + lpszCommandLine++; + } + + switch (MyToTLower(tFlag)) + { + case 'f': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ') ) + { + szFileName[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + break; + } + case 'l': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwNumLines = MyTToL(szBuff); + break; + + } + + + case 'i': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwNumInits = (DWORD) MyTToL(szBuff); + break; + + } + + case 't': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwNumThreads = (DWORD) MyTToL(szBuff); + + break; + + } + + case 's': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwSleep = (DWORD) MyTToL(szBuff); + + break; + + } + + case 'h': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwThreadSleep = (DWORD) MyTToL(szBuff); + break; + + } + case 'g': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + lpszCommandLine++; + } + + gbLogging = TRUE; + break; + + } + + } + } + + return TRUE; +} + + +LONG StartThreads(DWORD dwHold) +{ + int i, iThreads, j, iLoc; + LPHANDLE pHandles; + DWORD dwThreadID; + + pHandles = (LPHANDLE)GlobalAlloc(GPTR, sizeof(HANDLE) * dwNumThreads); + + InitializeCriticalSection(&csReply); + InitReplyStruct(); + + iThreads = dwNumThreads; + + for (i = 0; i < iThreads; i++) + { + pHandles[i] = CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)ScenarioProcs[0], + NULL, + 0, + &dwThreadID); + + Sleep(dwThreadSleep); + + } + + iLoc = 0; + + while (iThreads > MAXIMUM_WAIT_OBJECTS) + { + WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, + (LPHANDLE)pHandles[iLoc], + TRUE, + INFINITE); + + iThreads -= MAXIMUM_WAIT_OBJECTS; + iLoc += MAXIMUM_WAIT_OBJECTS; + } + + WaitForMultipleObjects(iThreads, + (LPHANDLE)(&(pHandles[iLoc])), + TRUE, + INFINITE); + + { + WINDOWPLACEMENT pwp; + HKEY hKey; + DWORD dwDisposition; + + + pwp.length = sizeof(WINDOWPLACEMENT); + + GetWindowPlacement( ghMainWnd, &pwp ); + + RegCreateKeyEx( + HKEY_CURRENT_USER, + gszRStressKey, + 0, + TEXT(""), + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + 0, + &hKey, + &dwDisposition + ); + + RegSetValueEx( + hKey, + gszPlacementValue, + 0, + REG_BINARY, + (LPBYTE)&pwp, + sizeof(WINDOWPLACEMENT) + ); + + RegCloseKey( hKey ); + } + + + ExitProcess(1); + + return 1; +} + +void CALLBACK LineCallbackFunc(DWORD dwDevice, + DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + + return; +} + +void HandleLineDevState(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + return; +} + + +void HandleLineReply(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + DWORD dwProcessID, dwThreadID; + + dwProcessID = GetCurrentProcessId(); + dwThreadID = GetCurrentThreadId(); + + LOGTAPIERROR(TEXT("LINE_REPLY"), dwParam2); + + SignalReply(dwParam1, dwParam2); + + return; +} + +void HandleLineCallState(DWORD dwDevice, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + LONG lResult; + DWORD dwThreadID, dwProcessID; + + switch (dwParam1) + { + case LINECALLSTATE_CONNECTED: + SignalConnected((HCALL)dwDevice); + break; + + case LINECALLSTATE_DISCONNECTED: + SignalDisconnected((HCALL)dwDevice, FALSE); + break; + + case LINECALLSTATE_IDLE: + + dwThreadID = GetCurrentThreadId(); + dwProcessID = GetCurrentProcessId(); + + SignalDisconnected((HCALL)dwDevice, TRUE); + lResult = lineDeallocateCall((HCALL)dwDevice); + + LOGTAPIERROR(TEXT("lineDeallocateCall"), lResult); + + break; + + case LINECALLSTATE_BUSY: + SignalError((HCALL)dwDevice); + break; + + default: + break; + } +} + +void HandleLineCallInfo(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ +} + +void HandleLineClose(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ +} + + +LONG Scenario4(LPVOID lpv) +{ + HLINEAPP hLineApp; + HCALL* phCall; + HLINE hLine; + DWORD dwNumDevs; + int i; + + phCall = (HCALL *)GlobalAlloc(GPTR, 10000*sizeof(HCALL)); + + lineInitialize(&hLineApp, + ghInstance, + LineCallbackFunc, + TEXT(""), + &dwNumDevs); + + lineOpen(hLineApp, + 0, + &hLine, + TAPI_VERSION, + 0, + 0, + LINECALLPRIVILEGE_NONE, + LINEMEDIAMODE_UNKNOWN, + NULL); + + while (TRUE) + { + i = 10000; + + while (i--) + { + + lineMakeCall(hLine, + &phCall[i], + TEXT("55555"), + 0, + NULL); + + } + + lineClose(hLine); + + lineOpen(hLineApp, + 0, + &hLine, + TAPI_VERSION, + 0, + 0, + LINECALLPRIVILEGE_NONE, + LINEMEDIAMODE_UNKNOWN, + NULL); + +// Sleep(0); + } + + ExitThread(0); + + return 1; +} + +void InitReplyStruct() +{ + EnterCriticalSection(&csReply); + + pReplyStruct = (ReplyStruct *)GlobalAlloc(GPTR, sizeof(ReplyStruct)); + pReplyStruct->pNext = NULL; + + LeaveCriticalSection(&csReply); +} + +DWORD AddReplyStruct() +{ + static DWORD dwStaticID = 0; + ReplyStruct* prs, * prsHold; + DWORD dwRetVal; + + EnterCriticalSection(&csReply); + + dwStaticID++; + + dwRetVal = dwStaticID; + + prs = (ReplyStruct *)GlobalAlloc(GPTR, sizeof(ReplyStruct)); + memset(prs, 0, sizeof(ReplyStruct)); + prs->dwID = dwStaticID; + + prsHold = pReplyStruct; + pReplyStruct = prs; + pReplyStruct->pNext = prsHold; + + LeaveCriticalSection(&csReply); + + return dwRetVal; +} + +void DeleteReplyStruct(DWORD dwID) +{ + ReplyStruct * prsDelete, * prsHold; + + EnterCriticalSection(&csReply); + + prsDelete = pReplyStruct; + + while (prsDelete) + { + if (prsDelete->dwID == dwID) + break; + + prsDelete = prsDelete->pNext; + } + + if (!prsDelete) + { + return; + } + + prsHold = prsDelete->pNext; + + if (!prsHold) + { + return; + } + + memcpy(prsDelete, prsHold, sizeof(ReplyStruct)); + + GlobalFree(prsHold); + + LeaveCriticalSection(&csReply); +} + +void SignalReply(DWORD dwReplyID, DWORD dwError) +{ + ReplyStruct * prsHold; + + EnterCriticalSection(&csReply); + + prsHold = pReplyStruct; + + while (prsHold) + { + if (prsHold->dwReplyID == dwReplyID) + { + prsHold->bSignaled = TRUE; + if ((LONG)dwError < 0) + prsHold->bError = TRUE; + break; + } + + prsHold = prsHold->pNext; + } + + LeaveCriticalSection(&csReply); +} + +void SetReplyID(DWORD dwID, DWORD dwReplyID) +{ + ReplyStruct * prsHold; + + EnterCriticalSection(&csReply); + + prsHold = pReplyStruct; + + while (prsHold) + { + if (prsHold->dwID == dwID) + { + prsHold->dwReplyID = dwReplyID; + break; + } + + prsHold = prsHold->pNext; + } + + LeaveCriticalSection(&csReply); +} + +void SetCallHandle(DWORD dwID, HCALL* phCall) +{ + ReplyStruct * prsHold; + + EnterCriticalSection(&csReply); + + prsHold = pReplyStruct; + + while (prsHold) + { + if (prsHold->dwID == dwID) + break; + + prsHold = prsHold->pNext; + } + + if (prsHold) + { + prsHold->phCall = phCall; + } + + LeaveCriticalSection(&csReply); +} + +void SignalConnected(HCALL hCall) +{ + ReplyStruct * prsHold; + + EnterCriticalSection(&csReply); + + prsHold = pReplyStruct; + + while (prsHold) + { + if (prsHold->phCall != NULL) + { + if (*(prsHold->phCall) == hCall) + { + prsHold->bConnected = TRUE; + break; + } + } + + prsHold = prsHold->pNext; + } + + LeaveCriticalSection(&csReply); +} + +void SignalDisconnected(HCALL hCall, BOOL fTimeToDie) +{ + ReplyStruct * prsHold; + + EnterCriticalSection(&csReply); + + prsHold = pReplyStruct; + + while (prsHold) + { + if (prsHold->phCall != NULL) + { + if (*(prsHold->phCall) == hCall) + { + prsHold->bConnected = FALSE; + + // + // Is the call IDLE and about to be + // terminated? + // + if ( fTimeToDie ) + { + // + // Zero out our hCall so we don't try to + // use it anywhere... + // + *(prsHold->phCall) = 0; + } + + break; + } + } + + prsHold = prsHold->pNext; + } + + LeaveCriticalSection(&csReply); +} + +void SignalError(HCALL hCall) +{ + ReplyStruct * prsHold; + + EnterCriticalSection(&csReply); + + prsHold = pReplyStruct; + + while (prsHold) + { + if (prsHold->phCall != NULL) + { + if (*(prsHold->phCall) == hCall) + { + prsHold->bError = TRUE; + break; + } + } + + prsHold = prsHold->pNext; + } + + LeaveCriticalSection(&csReply); +} + +BOOL GetSignaled(DWORD dwID) +{ + ReplyStruct * pRS; + BOOL bRetVal; + + EnterCriticalSection(&csReply); + + pRS = pReplyStruct; + + while (pRS) + { + if (pRS->dwID == dwID) + { + bRetVal = pRS->bSignaled; + break; + } + + pRS = pRS->pNext; + } + + LeaveCriticalSection(&csReply); + + return bRetVal; +} + + +BOOL GetConnected(DWORD dwID) +{ + ReplyStruct * pRS; + BOOL bRetVal; + + EnterCriticalSection(&csReply); + + pRS = pReplyStruct; + + while (pRS) + { + if (pRS->dwID == dwID) + { + bRetVal = pRS->bConnected; + break; + } + + pRS = pRS->pNext; + } + + LeaveCriticalSection(&csReply); + + return bRetVal; +} + +BOOL GetError(DWORD dwID) +{ + ReplyStruct * pRS; + BOOL bRetVal; + + EnterCriticalSection(&csReply); + + pRS = pReplyStruct; + + while (pRS) + { + if (pRS->dwID == dwID) + { + bRetVal = pRS->bError; + break; + } + + pRS = pRS->pNext; + } + + LeaveCriticalSection(&csReply); + + return bRetVal; +} + +void ClearError(DWORD dwID) +{ + ReplyStruct * pRS; + + EnterCriticalSection(&csReply); + + pRS = pReplyStruct; + + while (pRS) + { + if (pRS->dwID == dwID) + { + pRS->bError = FALSE; + break; + } + + pRS = pRS->pNext; + } + + LeaveCriticalSection(&csReply); +} + +#define SZPROVIDERINFO TEXT("ESP v2.0") + +BOOL ESPInstalled() +{ + HLINEAPP hLineApp; + LINEDEVCAPS * pLDC; + DWORD dwDeviceID, dwCount; + LPTSTR lpszName; + int i; + + for (i = 0; i < 5; i++) + { + if (lineInitialize(&hLineApp, + ghInstance, + LineCallbackFunc, + TEXT(""), + &dwDeviceID) == 0) + { + for (dwCount = 0; dwCount < dwDeviceID; dwCount ++) + { + if (ESPLine(hLineApp, + dwCount)) + { + return TRUE; + } + } + + lineShutdown(hLineApp); + + Sleep(5000); + } + } + return FALSE; +} + + +BOOL ESPLine(HLINEAPP hLineApp, + DWORD dwDeviceID) +{ + LINEDEVCAPS * pLDC; + LPTSTR lpszName; + + pLDC = LineGetDevCaps(hLineApp, + dwDeviceID); + + if (!pLDC) + { + return FALSE; + } + + lpszName = (LPTSTR) ( ( (LPBYTE)pLDC ) + pLDC->dwProviderInfoOffset); + + if (!lstrcmpi(lpszName, + SZPROVIDERINFO)) + { + LocalFree(pLDC); + return TRUE; + } + + LocalFree(pLDC); + return FALSE; + +} + +LINEDEVCAPS * LineGetDevCaps (HLINEAPP hLineApp, + DWORD dwDeviceID) +{ + LONG lRetVal; + LINEDEVCAPS * pLineDevCaps; + static DWORD dwMaxNeededSize = sizeof(LINEDEVCAPS); + + pLineDevCaps = (LINEDEVCAPS *)LocalAlloc(LPTR, dwMaxNeededSize); + for (;;) + { + if (pLineDevCaps == NULL) + { + return NULL; + } + pLineDevCaps->dwTotalSize = dwMaxNeededSize; + lRetVal = lineGetDevCaps(hLineApp, + dwDeviceID, + TAPI_VERSION, + 0, + pLineDevCaps); + if (lRetVal < 0) + { + LocalFree((HLOCAL)pLineDevCaps); + return NULL; + } + if (pLineDevCaps->dwNeededSize <= dwMaxNeededSize) + { + return pLineDevCaps; + } + else + { + dwMaxNeededSize = pLineDevCaps->dwNeededSize; + pLineDevCaps = (LINEDEVCAPS *)LocalReAlloc((HLOCAL)pLineDevCaps, + dwMaxNeededSize, + LMEM_MOVEABLE); + } + } +} + +LINEDEVSTATUS * LineGetLineDevStatus (HLINE hLine) +{ + LONG lRetVal; + LINEDEVSTATUS* pLineDevStatus; + static DWORD dwMaxNeededSize = sizeof(LINEDEVSTATUS); + + pLineDevStatus = (LINEDEVSTATUS *)LocalAlloc(LPTR, dwMaxNeededSize); + for (;;) + { + if (pLineDevStatus == NULL) + { + return NULL; + } + pLineDevStatus->dwTotalSize = dwMaxNeededSize; + lRetVal = lineGetLineDevStatus(hLine, + pLineDevStatus); + + if ((lRetVal != LINEERR_STRUCTURETOOSMALL) && (lRetVal < 0)) + { + LocalFree((HLOCAL)pLineDevStatus); + return NULL; + } + + if (pLineDevStatus->dwNeededSize <= dwMaxNeededSize) + { + return pLineDevStatus; + } + else + { + dwMaxNeededSize = pLineDevStatus->dwNeededSize; + pLineDevStatus = (LINEDEVSTATUS *)LocalReAlloc((HLOCAL)pLineDevStatus, + dwMaxNeededSize, + LMEM_MOVEABLE); + } + } +} + +#define ISDIGIT(c) ( ( (c) >= '0') && ( (c) <= '9') ) + +DWORD MyTToL(LPTSTR lpszBuf) +{ + DWORD dwReturn = 0; + + while (*lpszBuf && ISDIGIT(*lpszBuf)) + { + dwReturn = dwReturn*10 + (*lpszBuf - '0'); + lpszBuf++; + } + + return dwReturn; +} + +DWORD MyRand() +{ + static DWORD RandSeed = GetTickCount(); + + RandSeed = (RandSeed*BCONST+1) % MAX_SHORT; + + return RandSeed; +} + +void MyIToT(int i, TCHAR * szBuf) +{ + wsprintf(szBuf, TEXT("%d"), i); + + return; +} + +TCHAR MyToTLower(TCHAR tc) +{ + if ((tc <= 'z') && (tc >= 'a')) + return tc; + + return tc-'A'+'a'; +} diff --git a/private/tapi/dev/apps/rstress/app2/clntapp.h b/private/tapi/dev/apps/rstress/app2/clntapp.h new file mode 100644 index 000000000..b60117025 --- /dev/null +++ b/private/tapi/dev/apps/rstress/app2/clntapp.h @@ -0,0 +1,80 @@ +#include <windows.h> +#include <tapi.h> + +#define TAPI_VERSION 0x00010004 +#define NUMLINES 200 +#define NUMINITS 200 +#define SZAPPNAME TEXT("TapiClientApp") +#define SLEEPTIME 2000 +#define NUMTHREADS 20 +#define THREADSLEEP 15000 // up to 15 seconds +#define GLOBALTIMEOUT 10000 // 10 seconds +////////////////////////////////////////////////////////////////////////////// +// PROTOTYPES +////////////////////////////////////////////////////////////////////////////// +static BOOL CreateMainWindow (int nCmdShow); + +static LRESULT CALLBACK MainWndProc (HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); + +BOOL SetupEnvironment (int argc, char * argv[], char * szFileName); + +void CALLBACK LineCallbackFunc(DWORD dwDevice, + DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineDevState(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineReply(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineCallState(DWORD dwDevice, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineCallInfo(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineClose(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +LONG Scenario1(LPVOID lpv); +LONG Scenario2(LPVOID lpv); +LONG Scenario3(LPVOID lpv); +LONG Scenario4(LPVOID lpv); +LONG StartThreads(DWORD dwHold); + +typedef struct _ReplyStruct +{ + HCALL * phCall; + DWORD dwReplyID; + BOOL bSignaled; + BOOL bConnected; + BOOL bError; + DWORD dwID; + struct _ReplyStruct * pNext; +} ReplyStruct; + +void InitReplyStruct(); +DWORD AddReplyStruct(); +void DeleteReplyStruct(DWORD dwID); +void SignalReply(DWORD dwReplyID, DWORD); +void SetReplyID(DWORD dwID, DWORD dwReplyID); +void SetCallHandle(DWORD dwID, HCALL * phCall); +void SignalConnected(HCALL hCall); +void SignalDisconnected(HCALL hCall, BOOL); +BOOL GetSignaled(DWORD dwID); +BOOL GetConnected(DWORD dwID); +BOOL GetError(DWORD dwID); +void ClearError(DWORD dwID); +void SignalError(HCALL hCall); + +BOOL InitLogging(); +void CloseLogging(); +TCHAR * FormatTime(LONG dwTime); +void LogTapiError(LPTSTR lpszFunction, LONG lResult, DWORD dwProcessID, DWORD dwThreadID); diff --git a/private/tapi/dev/apps/rstress/app2/logging.cpp b/private/tapi/dev/apps/rstress/app2/logging.cpp new file mode 100644 index 000000000..2a116e441 --- /dev/null +++ b/private/tapi/dev/apps/rstress/app2/logging.cpp @@ -0,0 +1,210 @@ +#include "clntapp.h" + +HANDLE hLogFile; +extern TCHAR szFileName[MAX_PATH]; +CRITICAL_SECTION csFile; +extern BOOL gbLogging; + +LPTSTR lpszLineErrs[] = +{ + TEXT("SUCCESS"), + TEXT("ALLOCATED"), + TEXT("BADDEVICEID"), + TEXT("BEARERMODEUNAVAIL"), + TEXT("inval err code (0x80000004)"), // 0x80000004 isn't valid err code + TEXT("CALLUNAVAIL"), + TEXT("COMPLETIONOVERRUN"), + TEXT("CONFERENCEFULL"), + TEXT("DIALBILLING"), + TEXT("DIALDIALTONE"), + TEXT("DIALPROMPT"), + TEXT("DIALQUIET"), + TEXT("INCOMPATIBLEAPIVERSION"), + TEXT("INCOMPATIBLEEXTVERSION"), + TEXT("INIFILECORRUPT"), + TEXT("INUSE"), + TEXT("INVALADDRESS"), // 0x80000010 + TEXT("INVALADDRESSID"), + TEXT("INVALADDRESSMODE"), + TEXT("INVALADDRESSSTATE"), + TEXT("INVALAPPHANDLE"), + TEXT("INVALAPPNAME"), + TEXT("INVALBEARERMODE"), + TEXT("INVALCALLCOMPLMODE"), + TEXT("INVALCALLHANDLE"), + TEXT("INVALCALLPARAMS"), + TEXT("INVALCALLPRIVILEGE"), + TEXT("INVALCALLSELECT"), + TEXT("INVALCALLSTATE"), + TEXT("INVALCALLSTATELIST"), + TEXT("INVALCARD"), + TEXT("INVALCOMPLETIONID"), + TEXT("INVALCONFCALLHANDLE"), // 0x80000020 + TEXT("INVALCONSULTCALLHANDLE"), + TEXT("INVALCOUNTRYCODE"), + TEXT("INVALDEVICECLASS"), + TEXT("INVALDEVICEHANDLE"), + TEXT("INVALDIALPARAMS"), + TEXT("INVALDIGITLIST"), + TEXT("INVALDIGITMODE"), + TEXT("INVALDIGITS"), + TEXT("INVALEXTVERSION"), + TEXT("INVALGROUPID"), + TEXT("INVALLINEHANDLE"), + TEXT("INVALLINESTATE"), + TEXT("INVALLOCATION"), + TEXT("INVALMEDIALIST"), + TEXT("INVALMEDIAMODE"), + TEXT("INVALMESSAGEID"), // 0x80000030 + TEXT("inval err code (0x80000031)"), // 0x80000031 isn't valid err code + TEXT("INVALPARAM"), + TEXT("INVALPARKID"), + TEXT("INVALPARKMODE"), + TEXT("INVALPOINTER"), + TEXT("INVALPRIVSELECT"), + TEXT("INVALRATE"), + TEXT("INVALREQUESTMODE"), + TEXT("INVALTERMINALID"), + TEXT("INVALTERMINALMODE"), + TEXT("INVALTIMEOUT"), + TEXT("INVALTONE"), + TEXT("INVALTONELIST"), + TEXT("INVALTONEMODE"), + TEXT("INVALTRANSFERMODE"), + TEXT("LINEMAPPERFAILED"), // 0x80000040 + TEXT("NOCONFERENCE"), + TEXT("NODEVICE"), + TEXT("NODRIVER"), + TEXT("NOMEM"), + TEXT("NOREQUEST"), + TEXT("NOTOWNER"), + TEXT("NOTREGISTERED"), + TEXT("OPERATIONFAILED"), + TEXT("OPERATIONUNAVAIL"), + TEXT("RATEUNAVAIL"), + TEXT("RESOURCEUNAVAIL"), + TEXT("REQUESTOVERRUN"), + TEXT("STRUCTURETOOSMALL"), + TEXT("TARGETNOTFOUND"), + TEXT("TARGETSELF"), + TEXT("UNINITIALIZED"), // 0x80000050 + TEXT("USERUSERINFOTOOBIG"), + TEXT("REINIT"), + TEXT("ADDRESSBLOCKED"), + TEXT("BILLINGREJECTED"), + TEXT("INVALFEATURE"), + TEXT("NOMULTIPLEINSTANCE") +}; + +BOOL InitLogging() +{ + LONG dwTime; + DWORD dwLen; + + if (!gbLogging) + return TRUE; + + InitializeCriticalSection(&csFile); + + EnterCriticalSection(&csFile); + + hLogFile = CreateFile(szFileName, + GENERIC_WRITE, + 0, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + CloseHandle(hLogFile); + + LeaveCriticalSection(&csFile); + + return TRUE; +} + +void LogTapiError(LPTSTR lpszFunction, LONG lResult, DWORD dwProcessID, DWORD dwThreadID) +{ + TCHAR szBuffer[512]; + DWORD dwBytes; + char szCharBuffer[512]; + DWORD dwerror; + SYSTEMTIME st; + + if (!gbLogging) + return ; + + EnterCriticalSection(&csFile); + + if (hLogFile == 0) + { + LeaveCriticalSection(&csFile); + return; + } + + GetSystemTime(&st); + + wsprintf(szBuffer, + TEXT("%02d:%02d:%02d:%04d: PROCESS:%lu THREAD:%lu %s FAILED with %s\r\n"), + st.wHour, + st.wMinute, + st.wSecond, + st.wMilliseconds, + dwProcessID, + dwThreadID, + lpszFunction, + lpszLineErrs[LOWORD(lResult)]); + + WideCharToMultiByte(CP_ACP, + 0, + szBuffer, + -1, + szCharBuffer, + 512, + NULL, + NULL); + + while (TRUE) + { + // wait until file is available + hLogFile = CreateFile(szFileName, + GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (hLogFile == INVALID_HANDLE_VALUE) + { + Sleep(1000); + continue; + } + + break; + } + + + SetFilePointer(hLogFile, + 0, + NULL, + FILE_END); + + WriteFile(hLogFile, + szCharBuffer, + lstrlenA(szCharBuffer), + &dwBytes, + NULL); + + CloseHandle(hLogFile); + + LeaveCriticalSection(&csFile); + +} + +void CloseLogging() +{ + +// CloseHandle(hLogFile); +} + diff --git a/private/tapi/dev/apps/rstress/app2/makefile b/private/tapi/dev/apps/rstress/app2/makefile new file mode 100644 index 000000000..f1084966b --- /dev/null +++ b/private/tapi/dev/apps/rstress/app2/makefile @@ -0,0 +1,29 @@ +!if "$(OS)" == "Windows_NT" + +!INCLUDE $(NTMAKEENV)\makefile.def + +!else + +############################################################################## +# +# Dialer.exe Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\.. + +VERSIONLIST=debug retail + +DEPENDNAME=depend.mk + +COMMONMKFILE=makefile.def + +IS_OEM=TRUE +IS_32 = TRUE + +!include $(ROOT)\dev\master.mk + +!endif + diff --git a/private/tapi/dev/apps/rstress/app2/sources b/private/tapi/dev/apps/rstress/app2/sources new file mode 100644 index 000000000..a383c269b --- /dev/null +++ b/private/tapi/dev/apps/rstress/app2/sources @@ -0,0 +1,55 @@ +!IF 0 + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + +Author: + + John Rogers (JohnRo) 25-Oct-1991 + +Notes: + + Commented description of this file is in \nt\public\oak\bin\sources.tpl + +Revision History: + +!ENDIF + + +MAJORCOMP=net +MINORCOMP=tapi + +TARGETNAME=app2 +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=PROGRAM + +TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\shell32.lib \ + $(BASEDIR)\public\sdk\lib\*\tapi32l.lib \ + +INCLUDES=.;$(BASEDIR)\public\sdk\inc + +USE_NOLIBS=1 + +SOURCES=app2.cpp \ + logging.cpp + +C_DEFINES=-DWINVER=0x0400 -DUNICODE -DREALLY_USE_UNICODE -DTAPI_CURRENT_VERSION=0x00010004 + +UMTYPE=windows + +UMENTRY=winmain + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF diff --git a/private/tapi/dev/apps/rstress/client/makefile b/private/tapi/dev/apps/rstress/client/makefile new file mode 100644 index 000000000..f1084966b --- /dev/null +++ b/private/tapi/dev/apps/rstress/client/makefile @@ -0,0 +1,29 @@ +!if "$(OS)" == "Windows_NT" + +!INCLUDE $(NTMAKEENV)\makefile.def + +!else + +############################################################################## +# +# Dialer.exe Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\.. + +VERSIONLIST=debug retail + +DEPENDNAME=depend.mk + +COMMONMKFILE=makefile.def + +IS_OEM=TRUE +IS_32 = TRUE + +!include $(ROOT)\dev\master.mk + +!endif + diff --git a/private/tapi/dev/apps/rstress/client/sources b/private/tapi/dev/apps/rstress/client/sources new file mode 100644 index 000000000..21ec8d2d0 --- /dev/null +++ b/private/tapi/dev/apps/rstress/client/sources @@ -0,0 +1,54 @@ +!IF 0 + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + +Author: + + John Rogers (JohnRo) 25-Oct-1991 + +Notes: + + Commented description of this file is in \nt\public\oak\bin\sources.tpl + +Revision History: + +!ENDIF + + +MAJORCOMP=net +MINORCOMP=tapi + +TARGETNAME=tclient +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=PROGRAM + +TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\user32.lib \ + +INCLUDES=.;$(BASEDIR)\public\sdk\inc + +#USE_NOLIBS=1 +USE_CRTDLL=1 + +SOURCES=tclient.cpp + +C_DEFINES=-DWINVER=0x0400 + +UMTYPE=windows + +UMENTRY=winmain + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF diff --git a/private/tapi/dev/apps/rstress/client/tclient.cpp b/private/tapi/dev/apps/rstress/client/tclient.cpp new file mode 100644 index 000000000..90384bbde --- /dev/null +++ b/private/tapi/dev/apps/rstress/client/tclient.cpp @@ -0,0 +1,488 @@ +#include <windows.h> + +#define SZCLIENTAPP "clntapp.exe" +#define TAPI_VERSION1_4 0x00010004 + +char szFileDirectory[MAX_PATH + 1]; +char szFileName[MAX_PATH + 1]; +DWORD dwSleepTime = 2000; +DWORD dwNumApps = 15; +DWORD dwNumThreads = 10; +DWORD dwNumInits = 50; +DWORD dwNumLines = 50; +DWORD dwThreadSleep = 15000; +DWORD dwID; +BOOL bRun = TRUE; +BOOL gbNTSD = FALSE; + +HANDLE hDestroyEvent; +HINSTANCE ghInstance; +HWND ghMainWnd; + +LONG ThreadProc(LPVOID lpv); +BOOL CreateMainWindow (int nCmdShow); +LRESULT CALLBACK MainWndProc (HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); +void CALLBACK LineCallbackFunc (DWORD hDevice, + DWORD dwMessage, + DWORD dwInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void CreateFileName(); +BOOL InitializeVariables(LPTSTR lpszCommandLine); +DWORD MyTToL(LPTSTR lpszBuf); +TCHAR MyToTLower(TCHAR tc); + +//int WINAPI WinMainCRTStartup() +int WINAPI WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) +{ + MSG msg; + DWORD dwThreadID; + + ghInstance = GetModuleHandle(NULL); + + if (!CreateMainWindow(SW_SHOWNORMAL)) + { + return 0; + } + + hDestroyEvent = CreateEvent(NULL, + TRUE, + FALSE, + NULL); + + CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)ThreadProc, + NULL, + 0, + &dwThreadID); + + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return 1; +} + +BOOL CreateMainWindow (int nCmdShow) +{ + WNDCLASS wc; + static char szClassName[] = "TClientWndClass"; + RECT rc; + + wc.style = 0; + wc.lpfnWndProc = MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = ghInstance; + wc.hIcon = NULL; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.lpszMenuName = NULL; + wc.lpszClassName = szClassName; + + + if (!RegisterClass(&wc)) + { + return FALSE; + } + + ghMainWnd = CreateWindow( + szClassName, "", + WS_OVERLAPPEDWINDOW, + GetSystemMetrics(SM_CXSCREEN)-GetSystemMetrics(SM_CXSCREEN)/4, + 0, + GetSystemMetrics(SM_CXSCREEN)/4, + GetSystemMetrics(SM_CYSCREEN)/4, + NULL, NULL, ghInstance, NULL); + + if (ghMainWnd == NULL) + { + return FALSE; + } + + ShowWindow(ghMainWnd, SW_SHOWMINNOACTIVE); + UpdateWindow(ghMainWnd); + return TRUE; +} + +LRESULT CALLBACK MainWndProc (HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) + { + case WM_QUERYENDSESSION: + bRun = FALSE; + DestroyWindow(ghMainWnd); + return TRUE; + + case WM_CLOSE: + bRun = FALSE; + + DestroyWindow(ghMainWnd); + + return 0; + + case WM_DESTROY: + WaitForSingleObject(hDestroyEvent, + 15000); + +// PostQuitMessage(0); + ExitProcess(0); + break; + + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + + } + return 0; +} + +LONG ThreadProc(LPVOID lpv) +{ + STARTUPINFO si; + PROCESS_INFORMATION pi; + char szCommandLine[MAX_PATH+256]; + int i; + LPHANDLE pProcessHandles; + DWORD dwReturn; + + GetWindowsDirectory(szFileDirectory, + MAX_PATH); + + InitializeVariables(GetCommandLine()); + + pProcessHandles = (LPHANDLE)GlobalAlloc(GPTR, sizeof(HANDLE) * dwNumApps); + + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + + Sleep(1000); + + // start up initial ones + for (i = 0; i < (LONG)dwNumApps; ) + { + CreateFileName(); + + wsprintf(szCommandLine, + gbNTSD? + "ntsd -g -G %s /f:%s /l:%lu /i:%lu /s:%lu /t:%lu /h:%lu": + "%s /f:%s /l:%lu /i:%lu /s:%lu /t:%lu /h:%lu", + SZCLIENTAPP, + szFileName, + dwNumLines, + dwNumInits, + dwSleepTime, + dwNumThreads, + dwThreadSleep); + + if (CreateProcess(NULL, + szCommandLine, + NULL, + NULL, + FALSE, + NORMAL_PRIORITY_CLASS, + NULL, + NULL, + &si, + &pi)) + { + pProcessHandles[i] = pi.hProcess; + CloseHandle(pi.hThread); + i++; + } + + if (!bRun) + break; + + Sleep(dwThreadSleep); + } + + // keep starting up apps + while (bRun) + { + // wait for one to finish + dwReturn = WaitForMultipleObjects(dwNumApps, + pProcessHandles, + FALSE, + INFINITE); + + if ((dwReturn >= WAIT_OBJECT_0) && + (dwReturn < (WAIT_OBJECT_0 + dwNumApps))) + { + CreateFileName(); + + wsprintf(szCommandLine, + gbNTSD? + "ntsd -g -G %s /f:%s /l:%lu /i:%lu /s:%lu /t:%lu /h:%lu": + "%s /f:%s /l:%lu /i:%lu /s:%lu /t:%lu /h:%lu", + SZCLIENTAPP, + szFileName, + dwNumLines, + dwNumInits, + dwSleepTime, + dwNumThreads, + dwThreadSleep); + + while (!(CreateProcess(NULL, + szCommandLine, + NULL, + NULL, + FALSE, + NORMAL_PRIORITY_CLASS, + NULL, + NULL, + &si, + &pi))) + { + Sleep(5000); + } + + CloseHandle(pProcessHandles[dwReturn - WAIT_OBJECT_0]); + CloseHandle(pi.hThread); + pProcessHandles[dwReturn - WAIT_OBJECT_0] = pi.hProcess; + } + } + + // asked to terminate, but wait for all clntapps to finish + for (i = 0; i < (LONG)dwNumApps; i++) + { + TerminateProcess(pProcessHandles[i], + 0); + + CloseHandle(pProcessHandles[i]); + + } + + SetEvent(hDestroyEvent); + + return 1; +} + +///////////////////////////////////////////////// + +BOOL InitializeVariables(LPTSTR lpszCommandLine) +{ + int i, j; + TCHAR szBuff[64]; + TCHAR tFlag; + + while (*lpszCommandLine != '/') + { + lpszCommandLine ++; + } + + while (*lpszCommandLine != NULL) + { + while((*lpszCommandLine == ' ') || + (*lpszCommandLine == '/') || + (*lpszCommandLine == '\t')) + { + lpszCommandLine++; + } + + tFlag = *lpszCommandLine; + + lpszCommandLine++; + + if (*lpszCommandLine == ':') + { + lpszCommandLine++; + } + + switch (MyToTLower(tFlag)) + { + + case 'a': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwNumApps = (DWORD) MyTToL(szBuff); + break; + + } + + case 'l': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwNumLines = (DWORD) MyTToL(szBuff); + break; + + } + + case 'i': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwNumInits = (DWORD) MyTToL(szBuff); + break; + + } + + case 't': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwNumThreads = (DWORD) MyTToL(szBuff); + + break; + + } + + case 's': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwSleepTime = (DWORD) MyTToL(szBuff); + break; + + } + + case 'h': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwThreadSleep = (DWORD) MyTToL(szBuff); + break; + + } + + case 'f': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ') ) + { + szFileDirectory[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + break; + } + case 'g': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ') ) + { + lpszCommandLine++; + } + + gbNTSD = TRUE; + + break; + } + + default: + break; + } + } + + return TRUE; +} + +void CreateFileName() +{ + SYSTEMTIME st; + + GetSystemTime(&st); + + wsprintf(szFileName, + "%s\\TAPICLIENT%u.%u", + szFileDirectory, + st.wDay, + st.wHour); + + return; +} + +#define ISDIGIT(c) ( ( (c) >= '0') && ( (c) <= '9') ) + +DWORD MyTToL(LPTSTR lpszBuf) +{ + DWORD dwReturn = 0; + + while (ISDIGIT(*lpszBuf)) + { + dwReturn = dwReturn*10 + (*lpszBuf - '0'); + lpszBuf++; + } + + return dwReturn; +} + +TCHAR MyToTLower(TCHAR tc) +{ + if ((tc <= 'z') && (tc >= 'a')) + return tc; + + return tc-'A'+'a'; +} diff --git a/private/tapi/dev/apps/rstress/clntapp/clntapp.cpp b/private/tapi/dev/apps/rstress/clntapp/clntapp.cpp new file mode 100644 index 000000000..a36df0403 --- /dev/null +++ b/private/tapi/dev/apps/rstress/clntapp/clntapp.cpp @@ -0,0 +1,1635 @@ +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +#include "clntapp.h" + +////////////////////////////////////////////////////////////////////////////// +// GLOBALS +////////////////////////////////////////////////////////////////////////////// +HINSTANCE ghInstance; +HWND ghMainWnd; +ReplyStruct * pReplyStruct; +CRITICAL_SECTION csReply; +DWORD dwNumLines; +DWORD dwNumInits; +DWORD dwSleep; +DWORD dwNumThreads; +DWORD dwThreadSleep; +TCHAR szFileName[MAX_PATH]; +BOOL gbLogging; + +BOOL InitializeVariables(LPTSTR lpszCommandLine); +BOOL ESPLine(HLINEAPP hLineApp, + DWORD dwDeviceID); +BOOL ESPInstalled(); +LINEDEVCAPS * LineGetDevCaps (HLINEAPP hLineApp, + DWORD dwDeviceID); +LINEDEVSTATUS* LineGetLineDevStatus(HLINE hLine); + + + +TCHAR gszRStressKey[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Telephony\\RStress"); +TCHAR gszPlacementValue[] = TEXT("WindowPlacement"); + +DWORD MyTToL(LPTSTR lpszBuf); +void MyIToT(int i, TCHAR * szBuf); +DWORD MyRand(); +TCHAR MyToTLower(TCHAR tc); + +///////////////////////////////////////////////////////////////////////////// +// +// MACRO for logging tapi error. +// must have a local variable dwProcess ID and dwThreadID +// +///////////////////////////////////////////////////////////////////////////// +#define LOGTAPIERROR(lpszFunctionName, lRes) \ + { \ + if ((LONG)(lRes) < 0) \ + { \ + LogTapiError(lpszFunctionName, lRes, dwProcessID, dwThreadID); \ + } \ + } + +// random number stuff +#define MAX_SHORT 0xFFFF +#define BCONST 12345 + +typedef LONG (*SCENARIOPROC)(HANDLE); + +DWORD dwPrivs[] = + { + LINECALLPRIVILEGE_NONE, + LINECALLPRIVILEGE_MONITOR, + LINECALLPRIVILEGE_OWNER, + LINECALLPRIVILEGE_MONITOR | LINECALLPRIVILEGE_OWNER + }; + +DWORD dwModes[] = + { + LINEMEDIAMODE_UNKNOWN, + LINEMEDIAMODE_INTERACTIVEVOICE, + LINEMEDIAMODE_AUTOMATEDVOICE, + LINEMEDIAMODE_DATAMODEM, + LINEMEDIAMODE_G3FAX, + LINEMEDIAMODE_TDD, + LINEMEDIAMODE_G4FAX, + LINEMEDIAMODE_DIGITALDATA, + LINEMEDIAMODE_TELETEX, + LINEMEDIAMODE_VIDEOTEX, + LINEMEDIAMODE_TELEX, + LINEMEDIAMODE_MIXED, + LINEMEDIAMODE_ADSI, + LINEMEDIAMODE_VOICEVIEW, + }; + +int nummodes = sizeof(dwModes)/sizeof(DWORD); +int numprivs = sizeof(dwPrivs)/sizeof(DWORD); + +SCENARIOPROC ScenarioProcs[] = + { +// Scenario1, +// Scenario2, +// Scenario3, + Scenario4 + }; + +////////////////////////////////////////////////////////////////////////////// +// +// WinMain() +// +////////////////////////////////////////////////////////////////////////////// + +//int WINAPI WinMainCRTStartup() + +int WINAPI WinMain ( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) +{ + MSG msg; + DWORD dwThreadID; + + ghInstance = GetModuleHandle(NULL); + + if (!CreateMainWindow(SW_SHOWNORMAL)) + { + return 0; + } + + InitializeVariables(GetCommandLine()); + + if (!ESPInstalled()) + { + return 0; + } + + + if (szFileName[0] == 0) + { + MessageBox(NULL, TEXT("Failed to create log"), NULL, MB_OK); + return 0; + + } + + if (!InitLogging()) + { + MessageBox(NULL, TEXT("Failed to create log"), NULL, MB_OK); + return 0; + } + + + CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)StartThreads, + NULL, + 0, + &dwThreadID); + + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return 1; +} + +////////////////////////////////////////////////////////////////////////////// +// +// CreateMainWindow() +// +////////////////////////////////////////////////////////////////////////////// +BOOL CreateMainWindow (int nCmdShow) +{ + WNDCLASS wc; + static TCHAR szClassName[] = TEXT("TapiClientWndClass"); + + wc.style = 0; + wc.lpfnWndProc = MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = ghInstance; + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.lpszMenuName = NULL; + wc.lpszClassName = szClassName; + + + if (!RegisterClass(&wc)) + { + return FALSE; + } + + ghMainWnd = CreateWindow(szClassName, + TEXT("Tapi Client App"), + WS_OVERLAPPEDWINDOW, + 0, + 0, + GetSystemMetrics(SM_CXSCREEN)/2, + GetSystemMetrics(SM_CYSCREEN)/2, + NULL, + NULL, + ghInstance, + NULL); + + if (ghMainWnd == NULL) + { + return FALSE; + } + + + ShowWindow(ghMainWnd, SW_SHOWMINNOACTIVE); + + UpdateWindow(ghMainWnd); + return TRUE; +} + + +////////////////////////////////////////////////////////////////////////////// +// +// MainWndProc() +// +////////////////////////////////////////////////////////////////////////////// +LRESULT CALLBACK MainWndProc (HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) + { + case WM_QUERYENDSESSION: + case WM_ENDSESSION: + ExitProcess(0); + return TRUE; + break; + + case WM_DESTROY: + + ExitProcess(0); +// PostQuitMessage(0); + break; + + case WM_QUIT: + ExitProcess(0); + break; + + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + return 0; +} + +BOOL InitializeVariables(LPTSTR lpszCommandLine) +{ + int i, j; + TCHAR szBuff[64]; + TCHAR tFlag; + + dwNumLines = NUMLINES; + dwNumInits = NUMINITS; + dwNumThreads = NUMTHREADS; + dwSleep = SLEEPTIME; + dwThreadSleep = THREADSLEEP; + szFileName[0] = 0; + gbLogging = FALSE; + + while (*lpszCommandLine && *lpszCommandLine != '/') + { + lpszCommandLine ++; + } + + if (!*lpszCommandLine) + { + return TRUE; + } + + while (*lpszCommandLine != NULL) + { + while((*lpszCommandLine == ' ') || + (*lpszCommandLine == '/') || + (*lpszCommandLine == '\t')) + { + lpszCommandLine++; + } + + tFlag = *lpszCommandLine; + + lpszCommandLine++; + + if (*lpszCommandLine == ':') + { + lpszCommandLine++; + } + + switch (MyToTLower(tFlag)) + { + case 'f': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ') ) + { + szFileName[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + break; + } + + case 't': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwNumThreads = (DWORD) MyTToL(szBuff); + + break; + + } + + case 's': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwSleep = (DWORD) MyTToL(szBuff); + + break; + + } + + case 'h': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwThreadSleep = (DWORD) MyTToL(szBuff); + break; + + } + case 'g': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + lpszCommandLine++; + } + + gbLogging = TRUE; + break; + + } + + } + } + + return TRUE; +} + +/* +BOOL InitializeVariables(int argc, char * argv[]) +{ + int i, j; + char chFlag; + + i = 0; + + dwNumLines = NUMLINES; + dwNumInits = NUMINITS; + dwNumThreads = NUMTHREADS; + dwSleep = SLEEPTIME; + dwThreadSleep = THREADSLEEP; + szFileName[0] = 0; + + while (++i < argc) + { + j = 0; + if ((argv[i][j] == '/') || (argv[i][j] == '-') || (argv[i][j] == '+')) + j = 1; + + chFlag = argv[i][j++]; + + if (argv[i][j] == ':') + j++; + + switch(tolower(chFlag)) + { + case 'l': + sscanf(&argv[i][j], "%lu", &dwNumLines); + break; + + case 'i': + sscanf(&argv[i][j], "%lu", &dwNumInits); + break; + + case 't': + sscanf(&argv[i][j], "%lu", &dwNumThreads); + break; + + case 's': + sscanf(&argv[i][j], "%lu", &dwSleep); + break; + + case 'h': + sscanf(&argv[i][j], "%lu", &dwThreadSleep); + break; + + case 'f': + sscanf(&argv[i][j], "%s", szFileName); + break; + + default: + break; + } + } + + MessageBox(NULL, + szFileName, + NULL, + MB_OK); + + return TRUE; +} +*/ + +LONG StartThreads(DWORD dwHold) +{ + int i, iThreads, j, iLoc; + LPHANDLE pHandles; + DWORD dwThreadID; + + pHandles = (LPHANDLE)GlobalAlloc(GPTR, sizeof(HANDLE) * dwNumThreads); + + InitializeCriticalSection(&csReply); + InitReplyStruct(); + + iThreads = dwNumThreads; + + for (i = 0; i < iThreads; i++) + { + j = (DWORD)MyRand() * (sizeof(ScenarioProcs) / sizeof (SCENARIOPROC)) / MAX_SHORT; + + pHandles[i] = CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)ScenarioProcs[j], + NULL, + 0, + &dwThreadID); + + Sleep((DWORD)MyRand() * dwThreadSleep / MAX_SHORT); + + } + + iLoc = 0; + + while (iThreads > MAXIMUM_WAIT_OBJECTS) + { + WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, + (LPHANDLE)pHandles[iLoc], + TRUE, + INFINITE); + + iThreads -= MAXIMUM_WAIT_OBJECTS; + iLoc += MAXIMUM_WAIT_OBJECTS; + } + + WaitForMultipleObjects(iThreads, + (LPHANDLE)(&(pHandles[iLoc])), + TRUE, + INFINITE); + + { + WINDOWPLACEMENT pwp; + HKEY hKey; + DWORD dwDisposition; + + + pwp.length = sizeof(WINDOWPLACEMENT); + + GetWindowPlacement( ghMainWnd, &pwp ); + + RegCreateKeyEx( + HKEY_CURRENT_USER, + gszRStressKey, + 0, + TEXT(""), + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + 0, + &hKey, + &dwDisposition + ); + + RegSetValueEx( + hKey, + gszPlacementValue, + 0, + REG_BINARY, + (LPBYTE)&pwp, + sizeof(WINDOWPLACEMENT) + ); + + RegCloseKey( hKey ); + } + + + ExitProcess(1); + + return 1; +} + +void CALLBACK LineCallbackFunc(DWORD dwDevice, + DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + + switch(dwMsg) + { + case LINE_LINEDEVSTATE: + HandleLineDevState(dwParam1, + dwParam2, + dwParam3); + return; + case LINE_REPLY: + HandleLineReply(dwParam1, + dwParam2, + dwParam3); + return; + case LINE_CALLSTATE: + HandleLineCallState(dwDevice, + dwParam1, + dwParam2, + dwParam3); + return; + case LINE_CALLINFO: + HandleLineCallInfo(dwParam1, + dwParam2, + dwParam3); + return; + case LINE_CLOSE: + HandleLineClose(dwParam1, + dwParam2, + dwParam3); + return; + + default: + return; + } +} + +void HandleLineDevState(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + return; +} + + +void HandleLineReply(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + DWORD dwProcessID, dwThreadID; + + dwProcessID = GetCurrentProcessId(); + dwThreadID = GetCurrentThreadId(); + + LOGTAPIERROR(TEXT("LINE_REPLY"), dwParam2); + + SignalReply(dwParam1, dwParam2); + + return; +} + +void HandleLineCallState(DWORD dwDevice, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + LONG lResult; + DWORD dwThreadID, dwProcessID; + + switch (dwParam1) + { + case LINECALLSTATE_CONNECTED: + SignalConnected((HCALL)dwDevice); + break; + + case LINECALLSTATE_DISCONNECTED: + SignalDisconnected((HCALL)dwDevice, FALSE); + break; + + case LINECALLSTATE_IDLE: + + dwThreadID = GetCurrentThreadId(); + dwProcessID = GetCurrentProcessId(); + + SignalDisconnected((HCALL)dwDevice, TRUE); + lResult = lineDeallocateCall((HCALL)dwDevice); + + LOGTAPIERROR(TEXT("lineDeallocateCall"), lResult); + + break; + + case LINECALLSTATE_BUSY: + SignalError((HCALL)dwDevice); + break; + + default: + break; + } +} + +void HandleLineCallInfo(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ +} + +void HandleLineClose(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ +} + +LONG Scenario1(LPVOID lpv) +{ + HLINEAPP hLineApp; + HLINE hLine; + DWORD dwDeviceID, dwNumDevs, dwProcessID, dwThreadID; + int i; + int iMode, iPriv; + LONG lResult; + + dwProcessID = GetCurrentProcessId(); + dwThreadID = GetCurrentThreadId(); + + lResult = lineInitialize(&hLineApp, + ghInstance, + LineCallbackFunc, + SZAPPNAME, + &dwNumDevs); + + LOGTAPIERROR(TEXT("lineInitialize"), lResult); + + if (lResult < 0) + { + ExitThread(0); + return 0; + } + + i = MyRand() * dwNumLines / MAX_SHORT + 1; + + while (i--) + { + iMode = MyRand() * nummodes / MAX_SHORT; + iPriv = MyRand() * numprivs / MAX_SHORT; + dwDeviceID = (DWORD)(MyRand() * dwNumDevs / MAX_SHORT); + + lResult = lineOpen(hLineApp, + dwDeviceID, + &hLine, + TAPI_VERSION, + 0, + 0, + dwPrivs[iPriv], + dwModes[iMode], + NULL); + + LOGTAPIERROR(TEXT("lineOpen"), lResult); + + lResult = lineClose(hLine); + + LOGTAPIERROR(TEXT("lineClose"), lResult); + + Sleep(MyRand() * dwSleep / MAX_SHORT); + } + + lResult = lineShutdown(hLineApp); + + LOGTAPIERROR(TEXT("lineShutdown"), lResult); + + ExitThread(0); + + return 1; +} + +LONG Scenario2(LPVOID lpv) +{ + HLINEAPP hLineApp; + HLINE hLine; + DWORD dwDeviceID, dwNumDevs, dwThreadID, dwProcessID; + int i; + int iMode, iPriv; + LONG lResult; + + dwThreadID = GetCurrentThreadId(); + dwProcessID = GetCurrentProcessId(); + + i = MyRand() * dwNumLines / MAX_SHORT + 1; + + while (i--) + { + lResult = lineInitialize(&hLineApp, + ghInstance, + LineCallbackFunc, + SZAPPNAME, + &dwNumDevs); + + LOGTAPIERROR(TEXT("lineInitialize"), lResult); + if (lResult < 0) + { + break; + } + + iMode = MyRand() * nummodes / MAX_SHORT; + iPriv = MyRand() * numprivs / MAX_SHORT; + dwDeviceID = (DWORD)(MyRand() * dwNumDevs / MAX_SHORT); + + lResult = lineOpen(hLineApp, + dwDeviceID, + &hLine, + TAPI_VERSION, + 0, + 0, + dwPrivs[iPriv], + dwModes[iMode], + NULL); + LOGTAPIERROR(TEXT("lineOpen"), lResult); + + Sleep(MyRand() * dwSleep / MAX_SHORT); + + lResult = lineClose(hLine); + LOGTAPIERROR(TEXT("lineClose"), lResult); + + lResult = lineShutdown(hLineApp); + LOGTAPIERROR(TEXT("lineShutdown"), lResult); + } + + ExitThread(0); + + return 1; +} + +LONG Scenario3(LPVOID lpv) +{ + HLINEAPP * phLineApps; + HLINE * phLine; + DWORD dwDeviceID, dwNumDevs, dwThreadID, dwProcessID; + int i, k, iOpens, iInits; + int iMode, iPriv, iLineApp; + LONG lResult; + + dwThreadID = GetCurrentThreadId(); + dwProcessID = GetCurrentProcessId(); + + phLineApps = (HLINEAPP *)GlobalAlloc(GPTR, sizeof(HLINEAPP) * dwNumInits); + phLine = (HLINE *)GlobalAlloc(GPTR, sizeof(HLINE) * dwNumLines); + + i = MyRand() * dwNumLines / MAX_SHORT + 1; + + while (i--) + { + iInits = MyRand() * dwNumInits / MAX_SHORT; + + for (k = 0; k < iInits; k++) + { + lResult = lineInitialize(&phLineApps[k], + ghInstance, + LineCallbackFunc, + SZAPPNAME, + &dwNumDevs); + + LOGTAPIERROR(TEXT("lineInitialize"), lResult); + } + + iOpens = MyRand() * dwNumInits / MAX_SHORT; + + for (k = 0; k < iOpens; k++) + { + iMode = MyRand() * nummodes / MAX_SHORT; + iPriv = MyRand() * numprivs / MAX_SHORT; + dwDeviceID = (DWORD)(MyRand() * dwNumDevs / MAX_SHORT); + iLineApp = MyRand() * iInits / MAX_SHORT; + + lResult = lineOpen(phLineApps[iLineApp], + dwDeviceID, + &phLine[k], + TAPI_VERSION, + 0, + 0, + dwPrivs[iPriv], + dwModes[iMode], + NULL); + + LOGTAPIERROR(TEXT("lineOpen"), lResult); + } + + for (k = 0; k < iOpens; k++) + { + lResult = lineClose(phLine[k]); + + LOGTAPIERROR(TEXT("lineClose"), lResult); + } + for (k = 0; k < iInits; k++) + { + lResult = lineShutdown(phLineApps[k]); + + LOGTAPIERROR(TEXT("lineShutdown"), lResult); + } + } + + GlobalFree(phLineApps); + GlobalFree(phLine); + + ExitThread(0); + + return 1; +} + +LONG Scenario4(LPVOID lpv) +{ + HLINEAPP hLineApp; + HLINE hLine, hCallLine; + HCALL hCall; + DWORD dwDeviceID, dwReplyID, dwNumDevs, dwCallID; + DWORD dwThreadID, dwProcessID; + MSG msg; + int i, iMode, iPriv, k; + DWORD dwRS; + LINECALLINFO CI; + LINECALLSTATUS CS; + LINEDEVCAPS* pLDC; + LINEDEVSTATUS* pLDS; + LINEADDRESSSTATUS AS; + TCHAR szNumber[16]; + LONG lResult; + DWORD dwTime; + + dwThreadID = GetCurrentThreadId(); + dwProcessID = GetCurrentProcessId(); + + // i = MyRand() * dwNumLines / MAX_SHORT + 1; + + i = 10; + + while (i--) + { + lResult = lineInitialize(&hLineApp, + ghInstance, + LineCallbackFunc, + SZAPPNAME, + &dwNumDevs); + + LOGTAPIERROR(TEXT("linelineInitialize"), lResult); + if (lResult < 0) + { + break; + } + + iMode = MyRand() * nummodes / MAX_SHORT; + iPriv = MyRand() * numprivs / MAX_SHORT; + + while (TRUE) + { + dwDeviceID = (DWORD)(MyRand() * dwNumDevs / MAX_SHORT); + + pLDC = LineGetDevCaps(hLineApp, + dwDeviceID); + + if (pLDC) + { + LocalFree(pLDC); + } + + lResult = lineOpen(hLineApp, + dwDeviceID, + &hLine, + TAPI_VERSION, + 0, + 0, + dwPrivs[iPriv], + dwModes[iMode], + NULL); + LOGTAPIERROR(TEXT("lineOpen"), lResult); + + if (lResult < 0) + { + continue; + } + + pLDS = LineGetLineDevStatus(hLine); + + if (pLDS) + { + if ((pLDS->dwNumActiveCalls == 0) && ESPLine(hLineApp, dwDeviceID)) + { + LocalFree(pLDS); + break; + } + + LocalFree(pLDS); + + } + + lResult = lineClose(hLine); + LOGTAPIERROR(TEXT("lineClose"), lResult); + } + + while (TRUE) + { + dwCallID = (DWORD)(MyRand() * dwNumDevs / MAX_SHORT); + + pLDC = LineGetDevCaps(hLineApp, + dwCallID); + if (pLDC) + { + LocalFree(pLDC); + } + + lResult = lineOpen(hLineApp, + dwCallID, + &hCallLine, + TAPI_VERSION, + 0, + 0, + dwPrivs[iPriv], + dwModes[iMode], + NULL); + LOGTAPIERROR(TEXT("lineOpen"), lResult); + + if (lResult < 0) + { + continue; + } + + pLDS = LineGetLineDevStatus(hCallLine); + + if (pLDS) + { + lResult = lineClose(hCallLine); + LOGTAPIERROR(TEXT("lineClose"), lResult); + + if ((pLDS->dwNumActiveCalls == 0) && + (dwCallID != dwDeviceID) && + ESPLine(hLineApp, dwCallID)) + { + LocalFree(pLDS); + break; + } + + LocalFree(pLDS); + } + + } + + dwRS = AddReplyStruct(); + + MyIToT((int)dwCallID, szNumber); + + SetCallHandle(dwRS, &hCall); + + ClearError(dwRS); + + dwReplyID = lineMakeCall(hLine, + &hCall, + szNumber, + 0, + NULL); + + SetReplyID(dwRS, dwReplyID); + + if ((LONG)dwReplyID < 0) + { + LOGTAPIERROR(TEXT("lineMakeCall"), dwReplyID); + DeleteReplyStruct(dwRS); + lineClose(hLine); + lineShutdown(hLineApp); + + continue; + } + + dwTime = GetTickCount(); + while (TRUE) + { + AS.dwTotalSize = sizeof(AS); + CS.dwTotalSize = sizeof(CS); + CI.dwTotalSize = sizeof(CI); + + lResult = lineGetAddressStatus(hLine, + 0, + &AS); + LOGTAPIERROR(TEXT("lineGetAddressStatus"), lResult); + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + if (GetSignaled(dwRS)) + { + if (GetConnected(dwRS)) + { + break; + } + if (GetError(dwRS)) + { + + goto callerror; + } + } + + if ((GetTickCount() - dwTime) > GLOBALTIMEOUT) + { + goto callerror; + } + + Sleep(0); + } + + if (hCall) + { + lResult = lineGetCallStatus(hCall, + &CS); + LOGTAPIERROR(TEXT("lineGetCallStatus"), lResult); + + lResult = lineGetCallInfo(hCall, + &CI); + LOGTAPIERROR(TEXT("lineGetCallInfo"), lResult); + } + + ClearError(dwRS); + + if (hCall) + { + lResult = lineDrop(hCall, + NULL, + 0); + LOGTAPIERROR(TEXT("lineDrop"), lResult); + } + + dwTime = GetTickCount(); + + while (TRUE && hCall) + { + AS.dwTotalSize = sizeof(AS); + CS.dwTotalSize = sizeof(CS); + CI.dwTotalSize = sizeof(CI); + + lResult = lineGetAddressStatus(hLine, + 0, + &AS); + LOGTAPIERROR(TEXT("lineGetAddressStatus"), lResult); + + lResult = lineGetCallStatus(hCall, + &CS); + LOGTAPIERROR(TEXT("lineGetCallStatus"), lResult); + + lResult = lineGetCallInfo(hCall, + &CI); + LOGTAPIERROR(TEXT("lineGetCallInfo"), lResult); + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + if (!GetConnected(dwRS)) + { + break; + } + + if (GetError(dwRS)) + { + break; + } + + if ((GetTickCount() - dwTime) > GLOBALTIMEOUT) + { + goto callerror; + } + + Sleep(0); + } + +callerror: + + if ( hCall ) + { + lineDeallocateCall(hCall); + } + + DeleteReplyStruct(dwRS); + + lResult = lineClose(hLine); + LOGTAPIERROR(TEXT("lineClose"), lResult); + + lResult = lineShutdown(hLineApp); + LOGTAPIERROR(TEXT("lineShutdown"), lResult); + } + + ExitThread(0); + + return 1; +} + +void InitReplyStruct() +{ + EnterCriticalSection(&csReply); + + pReplyStruct = (ReplyStruct *)GlobalAlloc(GPTR, sizeof(ReplyStruct)); + pReplyStruct->pNext = NULL; + + LeaveCriticalSection(&csReply); +} + +DWORD AddReplyStruct() +{ + static DWORD dwStaticID = 0; + ReplyStruct* prs, * prsHold; + DWORD dwRetVal; + + EnterCriticalSection(&csReply); + + dwStaticID++; + + dwRetVal = dwStaticID; + + prs = (ReplyStruct *)GlobalAlloc(GPTR, sizeof(ReplyStruct)); + memset(prs, 0, sizeof(ReplyStruct)); + prs->dwID = dwStaticID; + + prsHold = pReplyStruct; + pReplyStruct = prs; + pReplyStruct->pNext = prsHold; + + LeaveCriticalSection(&csReply); + + return dwRetVal; +} + +void DeleteReplyStruct(DWORD dwID) +{ + ReplyStruct * prsDelete, * prsHold; + + EnterCriticalSection(&csReply); + + prsDelete = pReplyStruct; + + while (prsDelete) + { + if (prsDelete->dwID == dwID) + break; + + prsDelete = prsDelete->pNext; + } + + if (!prsDelete) + { + return; + } + + prsHold = prsDelete->pNext; + + if (!prsHold) + { + return; + } + + memcpy(prsDelete, prsHold, sizeof(ReplyStruct)); + + GlobalFree(prsHold); + + LeaveCriticalSection(&csReply); +} + +void SignalReply(DWORD dwReplyID, DWORD dwError) +{ + ReplyStruct * prsHold; + + EnterCriticalSection(&csReply); + + prsHold = pReplyStruct; + + while (prsHold) + { + if (prsHold->dwReplyID == dwReplyID) + { + prsHold->bSignaled = TRUE; + if ((LONG)dwError < 0) + prsHold->bError = TRUE; + break; + } + + prsHold = prsHold->pNext; + } + + LeaveCriticalSection(&csReply); +} + +void SetReplyID(DWORD dwID, DWORD dwReplyID) +{ + ReplyStruct * prsHold; + + EnterCriticalSection(&csReply); + + prsHold = pReplyStruct; + + while (prsHold) + { + if (prsHold->dwID == dwID) + { + prsHold->dwReplyID = dwReplyID; + break; + } + + prsHold = prsHold->pNext; + } + + LeaveCriticalSection(&csReply); +} + +void SetCallHandle(DWORD dwID, HCALL* phCall) +{ + ReplyStruct * prsHold; + + EnterCriticalSection(&csReply); + + prsHold = pReplyStruct; + + while (prsHold) + { + if (prsHold->dwID == dwID) + break; + + prsHold = prsHold->pNext; + } + + if (prsHold) + { + prsHold->phCall = phCall; + } + + LeaveCriticalSection(&csReply); +} + +void SignalConnected(HCALL hCall) +{ + ReplyStruct * prsHold; + + EnterCriticalSection(&csReply); + + prsHold = pReplyStruct; + + while (prsHold) + { + if (prsHold->phCall != NULL) + { + if (*(prsHold->phCall) == hCall) + { + prsHold->bConnected = TRUE; + break; + } + } + + prsHold = prsHold->pNext; + } + + LeaveCriticalSection(&csReply); +} + +void SignalDisconnected(HCALL hCall, BOOL fTimeToDie) +{ + ReplyStruct * prsHold; + + EnterCriticalSection(&csReply); + + prsHold = pReplyStruct; + + while (prsHold) + { + if (prsHold->phCall != NULL) + { + if (*(prsHold->phCall) == hCall) + { + prsHold->bConnected = FALSE; + + // + // Is the call IDLE and about to be + // terminated? + // + if ( fTimeToDie ) + { + // + // Zero out our hCall so we don't try to + // use it anywhere... + // + *(prsHold->phCall) = 0; + } + + break; + } + } + + prsHold = prsHold->pNext; + } + + LeaveCriticalSection(&csReply); +} + +void SignalError(HCALL hCall) +{ + ReplyStruct * prsHold; + + EnterCriticalSection(&csReply); + + prsHold = pReplyStruct; + + while (prsHold) + { + if (prsHold->phCall != NULL) + { + if (*(prsHold->phCall) == hCall) + { + prsHold->bError = TRUE; + break; + } + } + + prsHold = prsHold->pNext; + } + + LeaveCriticalSection(&csReply); +} + +BOOL GetSignaled(DWORD dwID) +{ + ReplyStruct * pRS; + BOOL bRetVal; + + EnterCriticalSection(&csReply); + + pRS = pReplyStruct; + + while (pRS) + { + if (pRS->dwID == dwID) + { + bRetVal = pRS->bSignaled; + break; + } + + pRS = pRS->pNext; + } + + LeaveCriticalSection(&csReply); + + return bRetVal; +} + + +BOOL GetConnected(DWORD dwID) +{ + ReplyStruct * pRS; + BOOL bRetVal; + + EnterCriticalSection(&csReply); + + pRS = pReplyStruct; + + while (pRS) + { + if (pRS->dwID == dwID) + { + bRetVal = pRS->bConnected; + break; + } + + pRS = pRS->pNext; + } + + LeaveCriticalSection(&csReply); + + return bRetVal; +} + +BOOL GetError(DWORD dwID) +{ + ReplyStruct * pRS; + BOOL bRetVal; + + EnterCriticalSection(&csReply); + + pRS = pReplyStruct; + + while (pRS) + { + if (pRS->dwID == dwID) + { + bRetVal = pRS->bError; + break; + } + + pRS = pRS->pNext; + } + + LeaveCriticalSection(&csReply); + + return bRetVal; +} + +void ClearError(DWORD dwID) +{ + ReplyStruct * pRS; + + EnterCriticalSection(&csReply); + + pRS = pReplyStruct; + + while (pRS) + { + if (pRS->dwID == dwID) + { + pRS->bError = FALSE; + break; + } + + pRS = pRS->pNext; + } + + LeaveCriticalSection(&csReply); +} + +#define SZPROVIDERINFO TEXT("ESP v2.0") + +BOOL ESPInstalled() +{ + HLINEAPP hLineApp; + LINEDEVCAPS * pLDC; + DWORD dwDeviceID, dwCount; + LPTSTR lpszName; + int i; + + for (i = 0; i < 5; i++) + { + if (lineInitialize(&hLineApp, + ghInstance, + LineCallbackFunc, + SZAPPNAME, + &dwDeviceID) == 0) + { + for (dwCount = 0; dwCount < dwDeviceID; dwCount ++) + { + if (ESPLine(hLineApp, + dwCount)) + { + return TRUE; + } + } + + lineShutdown(hLineApp); + + Sleep(5000); + } + } + return FALSE; +} + + +BOOL ESPLine(HLINEAPP hLineApp, + DWORD dwDeviceID) +{ + LINEDEVCAPS * pLDC; + LPTSTR lpszName; + + pLDC = LineGetDevCaps(hLineApp, + dwDeviceID); + + if (!pLDC) + { + return FALSE; + } + + lpszName = (LPTSTR) ( ( (LPBYTE)pLDC ) + pLDC->dwProviderInfoOffset); + + if (!lstrcmpi(lpszName, + SZPROVIDERINFO)) + { + LocalFree(pLDC); + return TRUE; + } + + LocalFree(pLDC); + return FALSE; + +} + +LINEDEVCAPS * LineGetDevCaps (HLINEAPP hLineApp, + DWORD dwDeviceID) +{ + LONG lRetVal; + LINEDEVCAPS * pLineDevCaps; + static DWORD dwMaxNeededSize = sizeof(LINEDEVCAPS); + + pLineDevCaps = (LINEDEVCAPS *)LocalAlloc(LPTR, dwMaxNeededSize); + for (;;) + { + if (pLineDevCaps == NULL) + { + return NULL; + } + pLineDevCaps->dwTotalSize = dwMaxNeededSize; + lRetVal = lineGetDevCaps(hLineApp, + dwDeviceID, + TAPI_VERSION, + 0, + pLineDevCaps); + if (lRetVal < 0) + { + LocalFree((HLOCAL)pLineDevCaps); + return NULL; + } + if (pLineDevCaps->dwNeededSize <= dwMaxNeededSize) + { + return pLineDevCaps; + } + else + { + dwMaxNeededSize = pLineDevCaps->dwNeededSize; + pLineDevCaps = (LINEDEVCAPS *)LocalReAlloc((HLOCAL)pLineDevCaps, + dwMaxNeededSize, + LMEM_MOVEABLE); + } + } +} + +LINEDEVSTATUS * LineGetLineDevStatus (HLINE hLine) +{ + LONG lRetVal; + LINEDEVSTATUS* pLineDevStatus; + static DWORD dwMaxNeededSize = sizeof(LINEDEVSTATUS); + + pLineDevStatus = (LINEDEVSTATUS *)LocalAlloc(LPTR, dwMaxNeededSize); + for (;;) + { + if (pLineDevStatus == NULL) + { + return NULL; + } + pLineDevStatus->dwTotalSize = dwMaxNeededSize; + lRetVal = lineGetLineDevStatus(hLine, + pLineDevStatus); + + if ((lRetVal != LINEERR_STRUCTURETOOSMALL) && (lRetVal < 0)) + { + LocalFree((HLOCAL)pLineDevStatus); + return NULL; + } + + if (pLineDevStatus->dwNeededSize <= dwMaxNeededSize) + { + return pLineDevStatus; + } + else + { + dwMaxNeededSize = pLineDevStatus->dwNeededSize; + pLineDevStatus = (LINEDEVSTATUS *)LocalReAlloc((HLOCAL)pLineDevStatus, + dwMaxNeededSize, + LMEM_MOVEABLE); + } + } +} + +#define ISDIGIT(c) ( ( (c) >= '0') && ( (c) <= '9') ) + +DWORD MyTToL(LPTSTR lpszBuf) +{ + DWORD dwReturn = 0; + + while (*lpszBuf && ISDIGIT(*lpszBuf)) + { + dwReturn = dwReturn*10 + (*lpszBuf - '0'); + lpszBuf++; + } + + return dwReturn; +} + +DWORD MyRand() +{ + static DWORD RandSeed = GetTickCount(); + + RandSeed = (RandSeed*BCONST+1) % MAX_SHORT; + + return RandSeed; +} + +void MyIToT(int i, TCHAR * szBuf) +{ + wsprintf(szBuf, TEXT("%d"), i); + + return; +} + +TCHAR MyToTLower(TCHAR tc) +{ + if ((tc <= 'z') && (tc >= 'a')) + return tc; + + return tc-'A'+'a'; +} diff --git a/private/tapi/dev/apps/rstress/clntapp/clntapp.h b/private/tapi/dev/apps/rstress/clntapp/clntapp.h new file mode 100644 index 000000000..9613265ab --- /dev/null +++ b/private/tapi/dev/apps/rstress/clntapp/clntapp.h @@ -0,0 +1,80 @@ +#include <windows.h> +#include <tapi.h> + +#define TAPI_VERSION 0x00010004 +#define NUMLINES 10 +#define NUMINITS 10 +#define SZAPPNAME "TapiClientApp" +#define SLEEPTIME 2000 +#define NUMTHREADS 20 +#define THREADSLEEP 15000 // up to 15 seconds +#define GLOBALTIMEOUT 10000 // 10 seconds +////////////////////////////////////////////////////////////////////////////// +// PROTOTYPES +////////////////////////////////////////////////////////////////////////////// +static BOOL CreateMainWindow (int nCmdShow); + +static LRESULT CALLBACK MainWndProc (HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); + +BOOL SetupEnvironment (int argc, char * argv[], char * szFileName); + +void CALLBACK LineCallbackFunc(DWORD dwDevice, + DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineDevState(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineReply(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineCallState(DWORD dwDevice, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineCallInfo(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineClose(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +LONG Scenario1(LPVOID lpv); +LONG Scenario2(LPVOID lpv); +LONG Scenario3(LPVOID lpv); +LONG Scenario4(LPVOID lpv); +LONG StartThreads(DWORD dwHold); + +typedef struct _ReplyStruct +{ + HCALL * phCall; + DWORD dwReplyID; + BOOL bSignaled; + BOOL bConnected; + BOOL bError; + DWORD dwID; + struct _ReplyStruct * pNext; +} ReplyStruct; + +void InitReplyStruct(); +DWORD AddReplyStruct(); +void DeleteReplyStruct(DWORD dwID); +void SignalReply(DWORD dwReplyID, DWORD); +void SetReplyID(DWORD dwID, DWORD dwReplyID); +void SetCallHandle(DWORD dwID, HCALL * phCall); +void SignalConnected(HCALL hCall); +void SignalDisconnected(HCALL hCall, BOOL); +BOOL GetSignaled(DWORD dwID); +BOOL GetConnected(DWORD dwID); +BOOL GetError(DWORD dwID); +void ClearError(DWORD dwID); +void SignalError(HCALL hCall); + +BOOL InitLogging(); +void CloseLogging(); +TCHAR * FormatTime(LONG dwTime); +void LogTapiError(LPTSTR lpszFunction, LONG lResult, DWORD dwProcessID, DWORD dwThreadID); diff --git a/private/tapi/dev/apps/rstress/clntapp/logging.cpp b/private/tapi/dev/apps/rstress/clntapp/logging.cpp new file mode 100644 index 000000000..2a116e441 --- /dev/null +++ b/private/tapi/dev/apps/rstress/clntapp/logging.cpp @@ -0,0 +1,210 @@ +#include "clntapp.h" + +HANDLE hLogFile; +extern TCHAR szFileName[MAX_PATH]; +CRITICAL_SECTION csFile; +extern BOOL gbLogging; + +LPTSTR lpszLineErrs[] = +{ + TEXT("SUCCESS"), + TEXT("ALLOCATED"), + TEXT("BADDEVICEID"), + TEXT("BEARERMODEUNAVAIL"), + TEXT("inval err code (0x80000004)"), // 0x80000004 isn't valid err code + TEXT("CALLUNAVAIL"), + TEXT("COMPLETIONOVERRUN"), + TEXT("CONFERENCEFULL"), + TEXT("DIALBILLING"), + TEXT("DIALDIALTONE"), + TEXT("DIALPROMPT"), + TEXT("DIALQUIET"), + TEXT("INCOMPATIBLEAPIVERSION"), + TEXT("INCOMPATIBLEEXTVERSION"), + TEXT("INIFILECORRUPT"), + TEXT("INUSE"), + TEXT("INVALADDRESS"), // 0x80000010 + TEXT("INVALADDRESSID"), + TEXT("INVALADDRESSMODE"), + TEXT("INVALADDRESSSTATE"), + TEXT("INVALAPPHANDLE"), + TEXT("INVALAPPNAME"), + TEXT("INVALBEARERMODE"), + TEXT("INVALCALLCOMPLMODE"), + TEXT("INVALCALLHANDLE"), + TEXT("INVALCALLPARAMS"), + TEXT("INVALCALLPRIVILEGE"), + TEXT("INVALCALLSELECT"), + TEXT("INVALCALLSTATE"), + TEXT("INVALCALLSTATELIST"), + TEXT("INVALCARD"), + TEXT("INVALCOMPLETIONID"), + TEXT("INVALCONFCALLHANDLE"), // 0x80000020 + TEXT("INVALCONSULTCALLHANDLE"), + TEXT("INVALCOUNTRYCODE"), + TEXT("INVALDEVICECLASS"), + TEXT("INVALDEVICEHANDLE"), + TEXT("INVALDIALPARAMS"), + TEXT("INVALDIGITLIST"), + TEXT("INVALDIGITMODE"), + TEXT("INVALDIGITS"), + TEXT("INVALEXTVERSION"), + TEXT("INVALGROUPID"), + TEXT("INVALLINEHANDLE"), + TEXT("INVALLINESTATE"), + TEXT("INVALLOCATION"), + TEXT("INVALMEDIALIST"), + TEXT("INVALMEDIAMODE"), + TEXT("INVALMESSAGEID"), // 0x80000030 + TEXT("inval err code (0x80000031)"), // 0x80000031 isn't valid err code + TEXT("INVALPARAM"), + TEXT("INVALPARKID"), + TEXT("INVALPARKMODE"), + TEXT("INVALPOINTER"), + TEXT("INVALPRIVSELECT"), + TEXT("INVALRATE"), + TEXT("INVALREQUESTMODE"), + TEXT("INVALTERMINALID"), + TEXT("INVALTERMINALMODE"), + TEXT("INVALTIMEOUT"), + TEXT("INVALTONE"), + TEXT("INVALTONELIST"), + TEXT("INVALTONEMODE"), + TEXT("INVALTRANSFERMODE"), + TEXT("LINEMAPPERFAILED"), // 0x80000040 + TEXT("NOCONFERENCE"), + TEXT("NODEVICE"), + TEXT("NODRIVER"), + TEXT("NOMEM"), + TEXT("NOREQUEST"), + TEXT("NOTOWNER"), + TEXT("NOTREGISTERED"), + TEXT("OPERATIONFAILED"), + TEXT("OPERATIONUNAVAIL"), + TEXT("RATEUNAVAIL"), + TEXT("RESOURCEUNAVAIL"), + TEXT("REQUESTOVERRUN"), + TEXT("STRUCTURETOOSMALL"), + TEXT("TARGETNOTFOUND"), + TEXT("TARGETSELF"), + TEXT("UNINITIALIZED"), // 0x80000050 + TEXT("USERUSERINFOTOOBIG"), + TEXT("REINIT"), + TEXT("ADDRESSBLOCKED"), + TEXT("BILLINGREJECTED"), + TEXT("INVALFEATURE"), + TEXT("NOMULTIPLEINSTANCE") +}; + +BOOL InitLogging() +{ + LONG dwTime; + DWORD dwLen; + + if (!gbLogging) + return TRUE; + + InitializeCriticalSection(&csFile); + + EnterCriticalSection(&csFile); + + hLogFile = CreateFile(szFileName, + GENERIC_WRITE, + 0, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + CloseHandle(hLogFile); + + LeaveCriticalSection(&csFile); + + return TRUE; +} + +void LogTapiError(LPTSTR lpszFunction, LONG lResult, DWORD dwProcessID, DWORD dwThreadID) +{ + TCHAR szBuffer[512]; + DWORD dwBytes; + char szCharBuffer[512]; + DWORD dwerror; + SYSTEMTIME st; + + if (!gbLogging) + return ; + + EnterCriticalSection(&csFile); + + if (hLogFile == 0) + { + LeaveCriticalSection(&csFile); + return; + } + + GetSystemTime(&st); + + wsprintf(szBuffer, + TEXT("%02d:%02d:%02d:%04d: PROCESS:%lu THREAD:%lu %s FAILED with %s\r\n"), + st.wHour, + st.wMinute, + st.wSecond, + st.wMilliseconds, + dwProcessID, + dwThreadID, + lpszFunction, + lpszLineErrs[LOWORD(lResult)]); + + WideCharToMultiByte(CP_ACP, + 0, + szBuffer, + -1, + szCharBuffer, + 512, + NULL, + NULL); + + while (TRUE) + { + // wait until file is available + hLogFile = CreateFile(szFileName, + GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (hLogFile == INVALID_HANDLE_VALUE) + { + Sleep(1000); + continue; + } + + break; + } + + + SetFilePointer(hLogFile, + 0, + NULL, + FILE_END); + + WriteFile(hLogFile, + szCharBuffer, + lstrlenA(szCharBuffer), + &dwBytes, + NULL); + + CloseHandle(hLogFile); + + LeaveCriticalSection(&csFile); + +} + +void CloseLogging() +{ + +// CloseHandle(hLogFile); +} + diff --git a/private/tapi/dev/apps/rstress/clntapp/makefile b/private/tapi/dev/apps/rstress/clntapp/makefile new file mode 100644 index 000000000..f1084966b --- /dev/null +++ b/private/tapi/dev/apps/rstress/clntapp/makefile @@ -0,0 +1,29 @@ +!if "$(OS)" == "Windows_NT" + +!INCLUDE $(NTMAKEENV)\makefile.def + +!else + +############################################################################## +# +# Dialer.exe Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\.. + +VERSIONLIST=debug retail + +DEPENDNAME=depend.mk + +COMMONMKFILE=makefile.def + +IS_OEM=TRUE +IS_32 = TRUE + +!include $(ROOT)\dev\master.mk + +!endif + diff --git a/private/tapi/dev/apps/rstress/clntapp/sources b/private/tapi/dev/apps/rstress/clntapp/sources new file mode 100644 index 000000000..0952d7472 --- /dev/null +++ b/private/tapi/dev/apps/rstress/clntapp/sources @@ -0,0 +1,56 @@ +!IF 0 + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + +Author: + + John Rogers (JohnRo) 25-Oct-1991 + +Notes: + + Commented description of this file is in \nt\public\oak\bin\sources.tpl + +Revision History: + +!ENDIF + + +MAJORCOMP=net +MINORCOMP=tapi + +TARGETNAME=clntapp +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=PROGRAM + +TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\shell32.lib \ + $(BASEDIR)\public\sdk\lib\*\tapi32l.lib + +INCLUDES=.;$(BASEDIR)\public\sdk\inc + +#USE_NOLIBS=1 +USE_CRTDLL=1 + +SOURCES=clntapp.cpp \ + logging.cpp + +C_DEFINES=-DWINVER=0x0400 -DUNICODE -DREALLY_USE_UNICODE -DTAPI_CURRENT_VERSION=0x00010004 + +UMTYPE=windows + +UMENTRY=winmain + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF diff --git a/private/tapi/dev/apps/rstress/dirs b/private/tapi/dev/apps/rstress/dirs new file mode 100644 index 000000000..047f7d933 --- /dev/null +++ b/private/tapi/dev/apps/rstress/dirs @@ -0,0 +1,4 @@ +DIRS=\ + client \ + clntapp \ + srvapp diff --git a/private/tapi/dev/apps/rstress/extrastr.bat b/private/tapi/dev/apps/rstress/extrastr.bat new file mode 100644 index 000000000..0dbbff64f --- /dev/null +++ b/private/tapi/dev/apps/rstress/extrastr.bat @@ -0,0 +1,22 @@ +@ECHO OFF + +IF "%PROCESSOR_ARCHITECTURE%" == "" GOTO DEFAULT + + +COPY \\TAPISTRESS\STRESS\%PROCESSOR_ARCHITECTURE%\*.* %windir%\SYSTEM32 +GOTO START + + + +:DEFAULT +ECHO NO PLATFORM SPECIFIED -- USING I386 +COPY \\TAPISTRESS\STRESS\x86\*.* %windir%\SYSTEM32 +GOTO START + + +:START +START SRVAPP /E:50 /F:\\TAPISTRESS\SERVERLOGS /G +START TCLIENT /A:3 /T:15 /S:0 /H:0 /F:\\TAPISTRESS\CLIENTLOGS + +:END + diff --git a/private/tapi/dev/apps/rstress/perfctr.h b/private/tapi/dev/apps/rstress/perfctr.h new file mode 100644 index 000000000..9308e5329 --- /dev/null +++ b/private/tapi/dev/apps/rstress/perfctr.h @@ -0,0 +1,22 @@ +// +// Offset definition file for extensible counter objects and counters +// +// These "relative" offsets must start at 0 and be multiples of 2 (i.e. +// even numbers). In the Open Procedure, they will be added to the +// "First Counter" and "First Help" values for the device they belong to, +// in order to determine the absolute location of the counter and +// object names and corresponding Explain text in the registry. +// +// This file is used by the extensible counter DLL code as well as the +// counter name and Explain text definition file (.INI) file that is used +// by LODCTR to load the names into the registry. +// +#define TAPIOBJ 0 +#define NUMLINES 2 +#define CURRENTOPENS 4 +#define TOTALOUTGOINGCALLS 6 +#define TOTALINCOMINGCALLS 8 + + + + diff --git a/private/tapi/dev/apps/rstress/regini.ini b/private/tapi/dev/apps/rstress/regini.ini new file mode 100644 index 000000000..a175fbf53 --- /dev/null +++ b/private/tapi/dev/apps/rstress/regini.ini @@ -0,0 +1,8 @@ +\registry\machine\SYSTEM\CurrentControlSet\Services +\registry\machine\SYSTEM\CurrentControlSet\Services\TapiSrv +\registry\machine\SYSTEM\CurrentControlSet\Services\TapiSrv\Performance + Library = REG_SZ TAPI32.DLL + Open = REG_SZ OpenTapiPerformanceData + Collect = REG_SZ CollectTapiPerformanceData + Close = REG_SZ CloseTapiPerformanceData +
\ No newline at end of file diff --git a/private/tapi/dev/apps/rstress/srvapp/logging.cpp b/private/tapi/dev/apps/rstress/srvapp/logging.cpp new file mode 100644 index 000000000..ad4df9642 --- /dev/null +++ b/private/tapi/dev/apps/rstress/srvapp/logging.cpp @@ -0,0 +1,390 @@ +#include "srvapp.h" + +HANDLE hLogFile; +extern BOOL gbLogging; + +LPSTR lpszLineErrs[] = +{ + "SUCCESS", + "ALLOCATED", + "BADDEVICEID", + "BEARERMODEUNAVAIL", + "inval err code (0x80000004)", // 0x80000004 isn't valid err code + "CALLUNAVAIL", + "COMPLETIONOVERRUN", + "CONFERENCEFULL", + "DIALBILLING", + "DIALDIALTONE", + "DIALPROMPT", + "DIALQUIET", + "INCOMPATIBLEAPIVERSION", + "INCOMPATIBLEEXTVERSION", + "INIFILECORRUPT", + "INUSE", + "INVALADDRESS", // 0x80000010 + "INVALADDRESSID", + "INVALADDRESSMODE", + "INVALADDRESSSTATE", + "INVALAPPHANDLE", + "INVALAPPNAME", + "INVALBEARERMODE", + "INVALCALLCOMPLMODE", + "INVALCALLHANDLE", + "INVALCALLPARAMS", + "INVALCALLPRIVILEGE", + "INVALCALLSELECT", + "INVALCALLSTATE", + "INVALCALLSTATELIST", + "INVALCARD", + "INVALCOMPLETIONID", + "INVALCONFCALLHANDLE", // 0x80000020 + "INVALCONSULTCALLHANDLE", + "INVALCOUNTRYCODE", + "INVALDEVICECLASS", + "INVALDEVICEHANDLE", + "INVALDIALPARAMS", + "INVALDIGITLIST", + "INVALDIGITMODE", + "INVALDIGITS", + "INVALEXTVERSION", + "INVALGROUPID", + "INVALLINEHANDLE", + "INVALLINESTATE", + "INVALLOCATION", + "INVALMEDIALIST", + "INVALMEDIAMODE", + "INVALMESSAGEID", // 0x80000030 + "inval err code (0x80000031)", // 0x80000031 isn't valid err code + "INVALPARAM", + "INVALPARKID", + "INVALPARKMODE", + "INVALPOINTER", + "INVALPRIVSELECT", + "INVALRATE", + "INVALREQUESTMODE", + "INVALTERMINALID", + "INVALTERMINALMODE", + "INVALTIMEOUT", + "INVALTONE", + "INVALTONELIST", + "INVALTONEMODE", + "INVALTRANSFERMODE", + "LINEMAPPERFAILED", // 0x80000040 + "NOCONFERENCE", + "NODEVICE", + "NODRIVER", + "NOMEM", + "NOREQUEST", + "NOTOWNER", + "NOTREGISTERED", + "OPERATIONFAILED", + "OPERATIONUNAVAIL", + "RATEUNAVAIL", + "RESOURCEUNAVAIL", + "REQUESTOVERRUN", + "STRUCTURETOOSMALL", + "TARGETNOTFOUND", + "TARGETSELF", + "UNINITIALIZED", // 0x80000050 + "USERUSERINFOTOOBIG", + "REINIT", + "ADDRESSBLOCKED", + "BILLINGREJECTED", + "INVALFEATURE", + "NOMULTIPLEINSTANCE" +}; + +BOOL InitLogging(LPSTR lpszFileDirectory) +{ + LPSTR lpszFileNameBuffer, lpszBuffer, lpszComputerNameBuffer; + SYSTEMTIME st; + DWORD dwSize; + HANDLE hUserFile; +#ifdef ENHANCE_LOG + SYSTEM_INFO SysInfo; + char lpszArchitecture[8]; +#endif + + + if (!gbLogging) + return TRUE; + + lpszFileNameBuffer = (LPSTR) LocalAlloc(LPTR, MAX_PATH+1); + + GetSystemTime(&st); + wsprintf(lpszFileNameBuffer, + "%s%s%02d%02d%02d", + lpszFileDirectory, + "\\TAPISTRESSSRV_", + st.wHour, + st.wMinute, + st.wSecond); + + hLogFile = CreateFile(lpszFileNameBuffer, + GENERIC_WRITE, + FILE_SHARE_READ, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (hLogFile == INVALID_HANDLE_VALUE) + { + hLogFile = 0; + LocalFree(lpszFileNameBuffer); + return FALSE; + } + + wsprintf(lpszFileNameBuffer, "%s\\users.txt", lpszFileDirectory); + + hUserFile = CreateFile(lpszFileNameBuffer, + GENERIC_WRITE, + FILE_SHARE_READ, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (hUserFile == INVALID_HANDLE_VALUE) + { + return FALSE; + } + + lpszBuffer = (LPSTR)GlobalAlloc(GPTR, 1024); + lpszComputerNameBuffer = (LPSTR)GlobalAlloc(GPTR, 1024); + + + SetFilePointer(hUserFile, + 0, + NULL, + FILE_END); + + dwSize = MAX_PATH; + + GetUserName(lpszFileNameBuffer, + &dwSize); + + dwSize = MAX_PATH; + + GetComputerName(lpszComputerNameBuffer, + &dwSize); + +#ifdef ENHANCE_LOG + GetSystemInfo(&SysInfo); + + switch (SysInfo.wProcessorArchitecture) { + case PROCESSOR_ARCHITECTURE_INTEL : + wsprintf(lpszArchitecture, "INTEL "); + break; + case PROCESSOR_ARCHITECTURE_ALPHA : + wsprintf(lpszArchitecture, "ALPHA "); + break; + case PROCESSOR_ARCHITECTURE_MIPS : + wsprintf(lpszArchitecture, "MIPS "); + break; + case PROCESSOR_ARCHITECTURE_PPC : + wsprintf(lpszArchitecture, "PPC "); + break; + case PROCESSOR_ARCHITECTURE_UNKNOWN : + wsprintf(lpszArchitecture, "UNKNOWN"); + break; + } + + wsprintf(lpszBuffer, + "LOGON %15s from %15s(%s) at %02d:%02d:%02d %02d-%02d-%02d\n\r", + lpszFileNameBuffer, + lpszComputerNameBuffer, + lpszArchitecture, + st.wHour, + st.wMinute, + st.wSecond, + st.wMonth, + st.wDay, + st.wYear); + +#else // !ENHANCE_LOG + + wsprintf(lpszBuffer, + "NAME: %s COMPUTER: %s TIME: %02d%02d%02d DATE: %02d%02d%02d\n\r", + lpszFileNameBuffer, + lpszComputerNameBuffer, + st.wHour, + st.wMinute, + st.wSecond, + st.wMonth, + st.wDay, + st.wYear); +#endif // !ENHANCE_LOG + + WriteFile(hUserFile, + lpszBuffer, + lstrlen(lpszBuffer), + &dwSize, + NULL); + + CloseHandle(hUserFile); + + LocalFree(lpszFileNameBuffer); + GlobalFree(lpszBuffer); + GlobalFree(lpszComputerNameBuffer); + + return TRUE; +} + +void LogTapiError(LPSTR lpszFunction, LONG lResult) +{ + char szBuffer[256]; + DWORD dwBytes; + SYSTEMTIME st; + + if (!gbLogging) + return; + + if (hLogFile == 0) + return; + + GetSystemTime(&st); + + wsprintf(szBuffer, + "%02d:%02d:%02d:%04d:\t%s FAILED with %s\r\n", + st.wHour, + st.wMinute, + st.wSecond, + st.wMilliseconds, + lpszFunction, + lpszLineErrs[LOWORD(lResult)]); + + WriteFile(hLogFile, + szBuffer, + strlen(szBuffer), + &dwBytes, + NULL); + +} + +void CloseLogging(LPSTR lpszFileDirectory, LONG lLineReplies) +{ + char szBuffer[64]; + DWORD dwBytes, dwSize; + LPSTR lpszComputerNameBuffer, lpszNameBuffer, lpszBuffer; + SYSTEMTIME st; + HANDLE hUserFile; + + lpszComputerNameBuffer = (LPSTR)GlobalAlloc(GPTR, MAX_PATH); + lpszNameBuffer = (LPSTR)GlobalAlloc(GPTR, MAX_PATH); + lpszBuffer = (LPSTR)GlobalAlloc(GPTR, 1024); + + + wsprintf(lpszNameBuffer, "%s\\users.txt", lpszFileDirectory); + + hUserFile = CreateFile(lpszNameBuffer, + GENERIC_WRITE, + FILE_SHARE_READ, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (hUserFile == INVALID_HANDLE_VALUE) + { + goto close_real_log; + } + + SetFilePointer(hUserFile, + 0, + NULL, + FILE_END); + + dwSize = MAX_PATH; + + GetUserName(lpszNameBuffer, + &dwSize); + + dwSize = MAX_PATH; + + GetComputerName(lpszComputerNameBuffer, + &dwSize); + + GetSystemTime(&st); + +#ifdef ENHANCE_LOG + { + SYSTEM_INFO SysInfo; + char lpszArchitecture[8]; + + GetSystemInfo(&SysInfo); + + switch (SysInfo.wProcessorArchitecture) { + case PROCESSOR_ARCHITECTURE_INTEL : + wsprintf(lpszArchitecture, "INTEL "); + break; + case PROCESSOR_ARCHITECTURE_ALPHA : + wsprintf(lpszArchitecture, "ALPHA "); + break; + case PROCESSOR_ARCHITECTURE_MIPS : + wsprintf(lpszArchitecture, "MIPS "); + break; + case PROCESSOR_ARCHITECTURE_PPC : + wsprintf(lpszArchitecture, "PPC "); + break; + case PROCESSOR_ARCHITECTURE_UNKNOWN : + wsprintf(lpszArchitecture, "UNKNOWN"); + break; + } + + wsprintf(lpszBuffer, + "LOGOFF %15s from %15s(%s) at %02d:%02d:%02d %02d-%02d-%02d\n\r", + lpszNameBuffer, + lpszComputerNameBuffer, + lpszArchitecture, + st.wHour, + st.wMinute, + st.wSecond, + st.wMonth, + st.wDay, + st.wYear); + } +#else // !ENHANCE_LOG + wsprintf(lpszBuffer, + "LOGOFF: NAME: %s COMPUTER: %s TIME: %02d%02d%02d DATE: %02d%02d%02d\n\r", + lpszNameBuffer, + lpszComputerNameBuffer, + st.wHour, + st.wMinute, + st.wSecond, + st.wMonth, + st.wDay, + st.wYear); +#endif // !ENHANCE_LOG + + WriteFile(hUserFile, + lpszBuffer, + lstrlen(lpszBuffer), + &dwSize, + NULL); + + CloseHandle(hUserFile); + +close_real_log: + + GlobalFree(lpszComputerNameBuffer); + GlobalFree(lpszNameBuffer); + GlobalFree(lpszBuffer); + + + if (!gbLogging) + return; + + wsprintf(szBuffer, "LEFT OVER LINE REPLIES %lu\r\n", lLineReplies); + + WriteFile(hLogFile, + szBuffer, + strlen(szBuffer), + &dwBytes, + NULL); + + CloseHandle(hLogFile); + +} + + diff --git a/private/tapi/dev/apps/rstress/srvapp/makefile b/private/tapi/dev/apps/rstress/srvapp/makefile new file mode 100644 index 000000000..f1084966b --- /dev/null +++ b/private/tapi/dev/apps/rstress/srvapp/makefile @@ -0,0 +1,29 @@ +!if "$(OS)" == "Windows_NT" + +!INCLUDE $(NTMAKEENV)\makefile.def + +!else + +############################################################################## +# +# Dialer.exe Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\.. + +VERSIONLIST=debug retail + +DEPENDNAME=depend.mk + +COMMONMKFILE=makefile.def + +IS_OEM=TRUE +IS_32 = TRUE + +!include $(ROOT)\dev\master.mk + +!endif + diff --git a/private/tapi/dev/apps/rstress/srvapp/sources b/private/tapi/dev/apps/rstress/srvapp/sources new file mode 100644 index 000000000..0a8551efa --- /dev/null +++ b/private/tapi/dev/apps/rstress/srvapp/sources @@ -0,0 +1,56 @@ +!IF 0 + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + +Author: + + John Rogers (JohnRo) 25-Oct-1991 + +Notes: + + Commented description of this file is in \nt\public\oak\bin\sources.tpl + +Revision History: + +!ENDIF + + +MAJORCOMP=net +MINORCOMP=tapi + +TARGETNAME=srvapp +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=PROGRAM + +TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\tapi32l.lib \ + $(BASEDIR)\public\sdk\lib\*\user32.lib + +INCLUDES=.;$(BASEDIR)\public\sdk\inc + +#USE_NOLIBS=1 +USE_CRTDLL=1 + +SOURCES=srvapp.cpp \ + logging.cpp + +C_DEFINES=-DWINVER=0x0400 + +UMTYPE=console + +UMENTRY=main + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF diff --git a/private/tapi/dev/apps/rstress/srvapp/srvapp.cpp b/private/tapi/dev/apps/rstress/srvapp/srvapp.cpp new file mode 100644 index 000000000..06bb5acb7 --- /dev/null +++ b/private/tapi/dev/apps/rstress/srvapp/srvapp.cpp @@ -0,0 +1,764 @@ +#include "srvapp.h" + +HANDLE ghCompletionPort; +HINSTANCE ghInstance; +LONG lLineReplies; +HLINE* gphLine; +DWORD dwNumDevs; +HLINEAPP ghLineApp; +DWORD dwESPLines = 10; +char szFileDir[MAX_PATH + 1]; +char szClientFileName[MAX_PATH+1]; +char szClientFileDirectory[MAX_PATH+1]; +BOOL bInstalledESP = FALSE; +DWORD dwID; +BOOL gbLogging = FALSE; + +LONG ThreadRoutine(LPVOID); +void WriteESPDefaults(); +BOOL InitializeVariables(LPTSTR lpszCommnandLine); +LINEDEVCAPS * LineGetDevCaps (HLINEAPP hLineApp, + DWORD dwDeviceID); +BOOL InstallESP(); +void RemoveESP(); +LONG DismissInstallDlg(LPVOID); +DWORD MyTToL(LPTSTR lpszBuf); +TCHAR MyToTLower(TCHAR tc); +void CreateClientFileName(); + +//int __cdecl mainCRTStartup() +int __cdecl main() +{ + DWORD dwAPIVersion, dwHold, dwThreadID; + LONG lResult; + LINEINITIALIZEEXPARAMS exparams; + HANDLE hEvent; + + lLineReplies = 0; + + GetWindowsDirectory(szFileDir, + MAX_PATH); + + InitializeVariables(GetCommandLine()); + + if (!InitLogging(szFileDir)) + return 0; + + SetConsoleCtrlHandler((PHANDLER_ROUTINE) BreakHandlerRoutine, TRUE); + + WriteESPDefaults(); + + InstallESP(); + + ghCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, + NULL, + 0, + 0); + + ghInstance = GetModuleHandle(NULL); + exparams.dwTotalSize = sizeof(LINEINITIALIZEEXPARAMS); + exparams.dwOptions = LINEINITIALIZEEXOPTION_USECOMPLETIONPORT; + exparams.Handles.hCompletionPort = ghCompletionPort; + + dwAPIVersion = TAPI2_0_VERSION; + + lResult = lineInitializeEx(&ghLineApp, + ghInstance, + LineCallbackFunc, + SZAPPNAME, + &dwNumDevs, + &dwAPIVersion, + &exparams); + + if (lResult < 0) + { + LogTapiError("lineInitializeEx", lResult); + return 0; + } + + gphLine = (HLINE*)GlobalAlloc(GPTR, sizeof(HLINE) * dwNumDevs); + + for (dwHold = 0; dwHold < dwNumDevs; dwHold++) + { + lResult = lineOpen(ghLineApp, + dwHold, + &gphLine[dwHold], + dwAPIVersion, + 0, + 0, + LINECALLPRIVILEGE_OWNER, + LINEMEDIAMODE_UNKNOWN | + LINEMEDIAMODE_INTERACTIVEVOICE | + LINEMEDIAMODE_AUTOMATEDVOICE | + LINEMEDIAMODE_DATAMODEM | + LINEMEDIAMODE_G3FAX | + LINEMEDIAMODE_TDD | + LINEMEDIAMODE_G4FAX | + LINEMEDIAMODE_DIGITALDATA | + LINEMEDIAMODE_TELETEX | + LINEMEDIAMODE_VIDEOTEX | + LINEMEDIAMODE_TELEX | + LINEMEDIAMODE_MIXED | + LINEMEDIAMODE_ADSI | + LINEMEDIAMODE_VOICEVIEW, + NULL); + + if (lResult < 0) + { + char szBuffer[64]; + + wsprintf(szBuffer, "lineOpen DEVICE # %lu", dwHold); + LogTapiError(szBuffer, lResult); + } + } + + CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)ThreadRoutine, + NULL, + 0, + &dwThreadID); + + hEvent = CreateEvent(NULL, + TRUE, + FALSE, + NULL); + + WaitForSingleObject(hEvent, + INFINITE); + + return 1; + +} + +LONG ThreadRoutine(LPVOID lpv) +{ + LPLINEMESSAGE pMsg; + DWORD dwNumBytesTransfered, dwCompletionKey; + + while (GetQueuedCompletionStatus(ghCompletionPort, + &dwNumBytesTransfered, + &dwCompletionKey, + (LPOVERLAPPED *) &pMsg, + INFINITE)) + { + if (pMsg) + { + LineCallbackFunc(pMsg->hDevice, + pMsg->dwMessageID, + pMsg->dwCallbackInstance, + pMsg->dwParam1, + pMsg->dwParam2, + pMsg->dwParam3); + + LocalFree (pMsg); + } + else + { + break; + } + } + + ExitThread(0); + return 0; +} + + + +void CALLBACK LineCallbackFunc(DWORD dwDevice, + DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + + switch(dwMsg) + { + case LINE_LINEDEVSTATE: + HandleLineDevState(dwParam1, + dwParam2, + dwParam3); + return; + case LINE_REPLY: + HandleLineReply(dwParam1, + dwParam2, + dwParam3); + return; + case LINE_CALLSTATE: + HandleLineCallState(dwDevice, + dwParam1, + dwParam2, + dwParam3); + return; + case LINE_CALLINFO: + HandleLineCallInfo(dwParam1, + dwParam2, + dwParam3); + return; + case LINE_CLOSE: + HandleLineClose(dwParam1, + dwParam2, + dwParam3); + return; + + default: + return; + } +} + +void HandleLineDevState(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + return; +} + + +void HandleLineReply(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + char szBuffer[128]; + + lLineReplies--; + + if ((LONG)dwParam2 != 0) + { + LogTapiError("LINE_REPLY", dwParam2); + wsprintf(szBuffer, "ID %lu", dwParam1); + LogTapiError(szBuffer, 0); + } + else + { +// LogTapiError("LINE_REPLY", dwParam2); +// wsprintf(szBuffer, "ID %lu", dwParam1); +// LogTapiError(szBuffer, 0); + } + + return; +} + +void HandleLineCallState(DWORD dwDevice, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ + LONG lResult; + char szBuffer[128]; + + switch (dwParam1) + { + case LINECALLSTATE_OFFERING: + +/* lResult = lineAccept((HCALL)dwDevice, + NULL, + 0); + + if (lResult <= 0) + { + LogTapiError("lineAccept", lResult); + } + else + { + lLineReplies++; + wsprintf(szBuffer, "lineAccept reply ID %lu", lResult); + LogTapiError(szBuffer, 0); + } + +*/ + lResult = lineAnswer((HCALL)dwDevice, + NULL, + 0); + + if (lResult <= 0) + { + LogTapiError("lineAnswer", lResult); + wsprintf(szBuffer, "hcall %lx", dwDevice); + LogTapiError(szBuffer, 0); + lineDeallocateCall((HCALL)dwDevice); + } + else + { +// wsprintf(szBuffer, "lineAnswer reply ID %lu", lResult); +// LogTapiError(szBuffer, 0); + lLineReplies++; + } + + break; + + case LINECALLSTATE_CONNECTED: + break; + + case LINECALLSTATE_DISCONNECTED: + lResult = lineDrop((HCALL)dwDevice, + NULL, + 0); + if (lResult < 0) + { + LogTapiError("lineDrop", lResult); + wsprintf(szBuffer, "hcall %lx", dwDevice); + LogTapiError(szBuffer, 0); + lineDeallocateCall((HCALL)dwDevice); + } + else + { +// wsprintf(szBuffer, "lineDrop reply id %lu", lResult); +// LogTapiError(szBuffer, 0); + lLineReplies++; + } + + break; + + case LINECALLSTATE_IDLE: + lResult = lineDeallocateCall((HCALL)dwDevice); + + if (lResult != 0) + { + LogTapiError("lineDeallocateCall", lResult); + } + + break; + + default: + break; + } +} + +void HandleLineCallInfo(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ +} + +void HandleLineClose(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3) +{ +} + +BOOL BreakHandlerRoutine(DWORD dwCtrlType) +{ + DWORD dwHold; + LONG lResult; + + for (dwHold = 0; dwHold < dwNumDevs; dwHold++) + { + lResult = lineClose(gphLine[dwHold]); + + if (lResult < 0) + { + char szBuffer[64]; + + wsprintf(szBuffer, "lineClose DEVICE # %lu", dwHold); + LogTapiError(szBuffer, lResult); + } + } + + lineShutdown(ghLineApp); + + GlobalFree(gphLine); + + RemoveESP(); + + CloseLogging(szFileDir, lLineReplies); + + ExitProcess(1); + + return TRUE; +} + +#define SZSECTION "ESP32" +#define SZNUMLINES "NumLines" +#define SZAUTOCLOSE "AutoClose" +#define SZDEBUGOUTPUT "DebugOutput" +#define SZDISABLEUI "DisableUI" + + +void WriteESPDefaults() +{ + char szBuffer[32]; + + wsprintf(szBuffer, "%d", dwESPLines); + + WriteProfileString(SZSECTION, + SZNUMLINES, + szBuffer); + + WriteProfileString(SZSECTION, + SZAUTOCLOSE, + "1"); + + WriteProfileString(SZSECTION, + SZDEBUGOUTPUT, + "0"); + WriteProfileString(SZSECTION, + SZDISABLEUI, + "1"); + +} +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////// +BOOL InitializeVariables(LPTSTR lpszCommandLine) +{ + int i, j; + TCHAR szBuff[64]; + TCHAR tFlag; + + dwESPLines = 10; + + while (*lpszCommandLine && *lpszCommandLine != '/') + { + lpszCommandLine ++; + } + + if (!*lpszCommandLine) + { + return TRUE; + } + + while (*lpszCommandLine != NULL) + { + while((*lpszCommandLine == ' ') || + (*lpszCommandLine == '/') || + (*lpszCommandLine == '\t')) + { + lpszCommandLine++; + } + + tFlag = *lpszCommandLine; + + lpszCommandLine++; + + if (*lpszCommandLine == ':') + { + lpszCommandLine++; + } + + switch (MyToTLower(tFlag)) + { + case 'f': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ') ) + { + szFileDir[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } +#ifdef ENHANCE_LOG +//bug - no end of string + szFileDir[i] = '\0'; +#endif + break; + } + case 'e': + { + i = 0; + + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + szBuff[i] = *lpszCommandLine; + lpszCommandLine++; + i++; + } + + szBuff[i] = 0; + + dwESPLines = MyTToL(szBuff); + break; + + } + case 'g': + { + while (*lpszCommandLine && (*lpszCommandLine != ' ')) + { + lpszCommandLine++; + } + + gbLogging = TRUE; + + } + + } + } + + return TRUE; +} + +///////////////////////////////////////////////////////// +//////////////////////////////////////////////////////// +//////////////////////////////////////////////////////// + + + +#define SZ_DLG_INSTALLTITLE "TUISPI_providerInstall" +#define SZ_DLG_REMOVETITLE "TUISPI_providerRemove" +#define TIMEOUT 3000 +#define SZPROVIDERINFO "ESP v2.0" +#define SZESPFILENAME "esp32.tsp" + +LONG DismissInstallDlg(LPVOID lpv) +{ + Sleep(TIMEOUT); + + HWND hwndChild = GetWindow (GetDesktopWindow(), GW_CHILD); + + + while (hwndChild) + { + char buf[32]; + + + GetWindowText (hwndChild, buf, 31); + + if (strcmp (buf, SZ_DLG_INSTALLTITLE) == 0) + { + break; + } + + hwndChild = GetWindow (hwndChild, GW_HWNDNEXT); + } + + if (hwndChild) + { + // + // We found the right hwnd, so nuke the timer, post a + // <Esc> key msg to dismiss the dlg, & reset the global + // uiTimer to zero so we don't try to kill the timer again + // + + PostMessage (hwndChild, WM_KEYDOWN, 0x0D, 0x00010001); // <Enter> key + } + + return TRUE; +} + + +BOOL InstallESP() +{ + LONG lResult; + HLINEAPP hLineApp; + DWORD dwNumDevs, dwThreadID; + int i; + LINEDEVCAPS * pLDC; + LPSTR lpszName; + + lResult = lineInitialize(&hLineApp, + ghInstance, + LineCallbackFunc, + "", + &dwNumDevs); + + if (lResult < 0) + { +// MessageBox(ghMainWnd, +// "Can't initialize TAPI", +// NULL, +// MB_OK); + return 0; + } + + WriteESPDefaults(); + + // check for esp + for (i = 0; i < (LONG)dwNumDevs; i++) + { + pLDC = LineGetDevCaps(hLineApp, + (DWORD)i); + + if (!pLDC) + continue; + + lpszName = (LPSTR)(((LPBYTE)pLDC)+pLDC->dwProviderInfoOffset); + + if (!lstrcmpi(lpszName, SZPROVIDERINFO)) + { + LocalFree(pLDC); + break; + } + + LocalFree(pLDC); + } + + // install esp + + if ((DWORD)i == dwNumDevs) + { + CreateThread(NULL, + 0, + (LPTHREAD_START_ROUTINE)DismissInstallDlg, + NULL, + 0, + &dwThreadID); + + if (lineAddProvider(SZESPFILENAME, + GetDesktopWindow(), + &dwID) != 0) + { +// MessageBox(ghMainWnd, +// "Can't initialize TAPI", +// NULL, +// MB_OK); + return 0; + } + + bInstalledESP = TRUE; + + } + + lineShutdown(hLineApp); + + return TRUE; +} + +#define SZPROVIDERSKEY "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Providers" +#define SZNUMPROVIDERS "NumProviders" +#define SZNEXTPROVIDERID "NextProviderID" +#define SZPROVIDERFILENAME "ProviderFilename" +#define SZPROVIDERID "ProviderID" + +void RemoveESP() +{ + DWORD dwNumProviders, dwNextID, dwSize; + HKEY hProvidersKey; + TCHAR szbuf[64]; + + + if (!bInstalledESP) + return; + + // get tapi key + RegOpenKeyEx(HKEY_LOCAL_MACHINE, + SZPROVIDERSKEY, + 0, + KEY_ALL_ACCESS, + &hProvidersKey); + + // get number of providers + dwSize = sizeof(DWORD); + RegQueryValueEx(hProvidersKey, + SZNUMPROVIDERS, + NULL, + NULL, + (LPBYTE)&dwNumProviders, + &dwSize); + + // decrement + dwNumProviders--; + + // set num providers + RegSetValueEx(hProvidersKey, + "NumProviders", + 0, + REG_DWORD, + (LPBYTE)&dwNumProviders, + sizeof(DWORD)); + + // get NextProviderID + dwSize = sizeof(DWORD); + RegQueryValueEx(hProvidersKey, + SZNEXTPROVIDERID, + NULL, + NULL, + (LPBYTE)&dwNextID, + &dwSize); + + // decrement + dwNextID--; + + // set NextProviderID + RegSetValueEx(hProvidersKey, + SZNEXTPROVIDERID, + 0, + REG_DWORD, + (LPBYTE)&dwNextID, + sizeof(DWORD)); + + // create ProviderFilename + wsprintf(szbuf, "%s%d", SZPROVIDERFILENAME, dwNumProviders); + + // remove that value + RegDeleteValue(hProvidersKey, + szbuf); + + wsprintf(szbuf, "%s%d", SZPROVIDERID, dwNumProviders); + + RegDeleteValue(hProvidersKey, + szbuf); + + +} + +//***************************************************************************** +// LineGetDevCaps() +//***************************************************************************** + +LINEDEVCAPS * LineGetDevCaps ( + HLINEAPP hLineApp, + DWORD dwDeviceID) +{ + LONG lRetVal; + LINEDEVCAPS * pLineDevCaps; + static DWORD dwMaxNeededSize = sizeof(LINEDEVCAPS); + + pLineDevCaps = (LINEDEVCAPS *)LocalAlloc(LPTR, dwMaxNeededSize); + for (;;) + { + if (pLineDevCaps == NULL) + { + return NULL; + } + pLineDevCaps->dwTotalSize = dwMaxNeededSize; + lRetVal = lineGetDevCaps(hLineApp, + dwDeviceID, + TAPI2_0_VERSION, + 0, + pLineDevCaps); + if (lRetVal < 0) + { + LocalFree((HLOCAL)pLineDevCaps); + return NULL; + } + if (pLineDevCaps->dwNeededSize <= dwMaxNeededSize) + { + return pLineDevCaps; + } + else + { + dwMaxNeededSize = pLineDevCaps->dwNeededSize; + pLineDevCaps = (LINEDEVCAPS *)LocalReAlloc((HLOCAL)pLineDevCaps, + dwMaxNeededSize, + LMEM_MOVEABLE); + } + } +} + +#define ISDIGIT(c) ( ( (c) >= '0') && ( (c) <= '9') ) + +DWORD MyTToL(LPTSTR lpszBuf) +{ + DWORD dwReturn = 0; + + while (*lpszBuf && ISDIGIT(*lpszBuf)) + { + dwReturn = dwReturn*10 + (*lpszBuf - '0'); + lpszBuf++; + } + + return dwReturn; +} + + +TCHAR MyToTLower(TCHAR tc) +{ + if ((tc <= 'z') && (tc >= 'a')) + return tc; + + return tc-'A'+'a'; +} + + + diff --git a/private/tapi/dev/apps/rstress/srvapp/srvapp.h b/private/tapi/dev/apps/rstress/srvapp/srvapp.h new file mode 100644 index 000000000..beef3b5cb --- /dev/null +++ b/private/tapi/dev/apps/rstress/srvapp/srvapp.h @@ -0,0 +1,37 @@ +#include <windows.h> +#include <tapi.h> + +#define TAPI2_0_VERSION 0x00020000 +#define SZAPPNAME "Tapi Stress Server" + +#define ENHANCE_LOG + +BOOL BreakHandlerRoutine(DWORD dwCtrlType); +void LogTapiError(LPSTR lpszFunction, LONG lResult); +void CALLBACK LineCallbackFunc(DWORD dwDevice, + DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineDevState(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineReply(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineCallState(DWORD dwDevice, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineCallInfo(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); +void HandleLineClose(DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3); + +BOOL InitLogging(LPSTR lpszDirectory); +void CloseLogging(LPSTR, LONG); +char * FormatTime(LONG dwTime); + diff --git a/private/tapi/dev/apps/rstress/tapiperf.ini b/private/tapi/dev/apps/rstress/tapiperf.ini new file mode 100644 index 000000000..4d583ae80 --- /dev/null +++ b/private/tapi/dev/apps/rstress/tapiperf.ini @@ -0,0 +1,32 @@ +[info] + +drivername=TAPISRV +symbolfile=perfctr.h + +[languages] +009=English + +[text] +TAPIOBJ_009_NAME=Telephony +TAPIOBJ_009_HELP=The Telphony System + +NUMLINES_009_NAME=Number of Lines +NUMLINES_009_HELP=The number of telephone lines serviced by this computer. + +CURRENTOPENS_009_NAME=Number of Active Lines +CURRENTOPENS_009_HELP=The number of telephone lines serviced by this computer that are currently active. + +TOTALOUTGOINGCALLS_009_NAME=Outgoing calls/sec +TOTALOUTGOINGCALLS_009_HELP=The rate of outgoing calls made by this computer. + +TOTALINCOMINGCALLS_009_NAME=Incoming calls/sec +TOTALINCOMINGCALLS_009_HELP=The rate of incoming calls answered by this computer. + +CURRENTCLIENTAPPS_009_NAME=Number of Client Apps +CURRENTCLIENTAPPS_009_HELP=The number of applications that are currently using telephony services. + +NUMPHONES_009_NAME=Number of Telephone devices +NUMPHONES_009_HELP=The number of telephone devices serviced by this computer. + +OPENPHONES_009_NAME=Number of Active Telephones +OPENPHONES_009_NAME=The number of telephone devices that are currently being monitored. diff --git a/private/tapi/dev/apps/rstress/tapistrs.bat b/private/tapi/dev/apps/rstress/tapistrs.bat new file mode 100644 index 000000000..4df518431 --- /dev/null +++ b/private/tapi/dev/apps/rstress/tapistrs.bat @@ -0,0 +1,22 @@ +@ECHO OFF + +IF "%PROCESSOR_ARCHITECTURE%" == "" GOTO DEFAULT + + +COPY \\TAPISTRESS\STRESS\%PROCESSOR_ARCHITECTURE%\*.* %windir%\SYSTEM32 +GOTO START + + + +:DEFAULT +ECHO NO PLATFORM SPECIFIED -- USING I386 +COPY \\TAPISTRESS\STRESS\x86\*.* %windir%\SYSTEM32 +GOTO START + + +:START +START SRVAPP /E:50 /F:\\TAPISTRESS\SERVERLOGS /G +START TCLIENT /A:1 /T:15 /S:5000 /H:5000 /F:\\TAPISTRESS\CLIENTLOGS + +:END + diff --git a/private/tapi/dev/apps/tapitna/depend.mk b/private/tapi/dev/apps/tapitna/depend.mk new file mode 100644 index 000000000..6ada94a88 --- /dev/null +++ b/private/tapi/dev/apps/tapitna/depend.mk @@ -0,0 +1,5 @@ +.\tapitna.obj: ..\tapitna.c ..\tapitna.h + +.\tapitna.res: ..\tapitna.rc ..\tapitna.h ..\..\..\client\general.rc + +.\general.obj: ..\..\..\client\general.c diff --git a/private/tapi/dev/apps/tapitna/makefile b/private/tapi/dev/apps/tapitna/makefile new file mode 100644 index 000000000..815052960 --- /dev/null +++ b/private/tapi/dev/apps/tapitna/makefile @@ -0,0 +1,30 @@ + +!if "$(OS)" == "Windows_NT" + +!INCLUDE $(NTMAKEENV)\makefile.def + +!else + +############################################################################## +# +# taskbar.exe Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\.. + +VERSIONLIST=debug retail + +DEPENDNAME=depend.mk + +COMMONMKFILE=makefile.def + +IS_OEM=TRUE +IS_32 = TRUE + +!include $(ROOT)\dev\master.mk + +!endif + diff --git a/private/tapi/dev/apps/tapitna/makefile.def b/private/tapi/dev/apps/tapitna/makefile.def new file mode 100644 index 000000000..a1587cf9a --- /dev/null +++ b/private/tapi/dev/apps/tapitna/makefile.def @@ -0,0 +1,62 @@ +############################################################################## +# +# Telephony Location Manager make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\..\.. + + +WANT_C932=1 +IS_32 = TRUE +WIN32=1 +IS_OEM = TRUE + +DEPENDNAME=..\depend.mk + +DRVNAME=TLocMgr +TARGETS=TLocMgr.exe TLocMgr.sym + +SRCDIR=.. +ALTSRCDIR=..\..\..\client + +#BUILD_COFF=1 + +DEFENTRY=WinMain + + +L32EXE=TLocMgr.exe # Name of exe. +L32DEF=..\tapitna.def # Our def file. +L32MAP=TLocMgr.map # Our map file. +L32SYM=TLocMgr.sym # Our map file. +L32LIBS= \ + $(W32LIBID)\kernel32.lib \ + $(W32LIBID)\user32.lib \ + $(W32LIBID)\advapi32.lib \ + $(W32LIBID)\comctl32.lib \ + $(ROOT)\dev\sdk\lib\tapi32.lib \ + $(ROOT)\dev\tools\c932\lib\libc.lib \ + $(W32LIBID)\shell32.lib + +L32RES=tapitna.res # Resource file. + +L32OBJS = tapitna.obj general.obj + +L32FLAGS=$(L32FLAGS) /PDB:tlogmgr.pdb /MAP:tlocmgr.map + +!include $(ROOT)\dev\master.mk + + +#L32FLAGS=$(L32FLAGS) /PDB:tapitna.pdb /MAP:tlocmgr.map + + +INCLUDE=$(INCLUDE);..\..\..\client + +#CFLAGS=$(CFLAGS) -DWIN32=100 -DWIN_32=100 -Od -Fc +CFLAGS=$(CFLAGS) -DWIN32=100 -DWIN_32=100 -Og + +!IF "$(VERDIR)" == "debug" +CFLAGS = $(CFLAGS) -DDBG=1 +!endif diff --git a/private/tapi/dev/apps/tapitna/makefile.inc b/private/tapi/dev/apps/tapitna/makefile.inc new file mode 100644 index 000000000..163b60c84 --- /dev/null +++ b/private/tapi/dev/apps/tapitna/makefile.inc @@ -0,0 +1,2 @@ +general.c: ..\..\client\general.c + copy $** $@ diff --git a/private/tapi/dev/apps/tapitna/sources b/private/tapi/dev/apps/tapitna/sources new file mode 100644 index 000000000..52b25014f --- /dev/null +++ b/private/tapi/dev/apps/tapitna/sources @@ -0,0 +1,34 @@ +MAJORCOMP=net +MINORCOMP=tapi + +TARGETNAME=TLocMgr +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=PROGRAM +TARGETLIBS= \ + $(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\shell32.lib \ + $(BASEDIR)\public\sdk\lib\*\advapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\comctl32.lib \ + $(BASEDIR)\public\sdk\lib\*\tapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\user32.lib + +INCLUDES=..\inc;$(BASEDIR)\public\sdk\inc;..\..\client\;. + +NTTARGETFILES= + +UMENTRY=winmain + +C_DEFINES=-DWINVER=0x0400 -DTAPI_NT=1 + +USE_CRTDLL=1 + +SOURCES=tapitna.c \ + tapitna.rc \ + general.c + + +UMTYPE=windows + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF diff --git a/private/tapi/dev/apps/tapitna/tapitna.c b/private/tapi/dev/apps/tapitna/tapitna.c new file mode 100644 index 000000000..2262c4e57 --- /dev/null +++ b/private/tapi/dev/apps/tapitna/tapitna.c @@ -0,0 +1,1720 @@ +/**************************************************************************** + + PROGRAM: tapitna + + PURPOSE: + + FUNCTIONS: + +****************************************************************************/ + +#define STRICT + +#include "windows.h" +#include "windowsx.h" +#include "shellapi.h" +#include "prsht.h" +#include "dbt.h" +//#include "stdio.h" + +#if WINNT +#else +#include "pbt.h" +#endif + +#include "tapi.h" +#include "tapitna.h" + +#include "clientr.h" +#include "general.h" + + +#if DBG +#define DBGOUT(arg) DbgPrt arg +VOID +DbgPrt( + IN DWORD dwDbgLevel, + IN PUCHAR DbgMessage, + IN ... + ); +#define DOFUNC(arg1,arg2) DoFunc(arg1,arg2) +#else +#define DBGOUT(arg) +#define DOFUNC(arg1,arg2) DoFunc(arg1) +#endif + + + + +int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ); +long PASCAL MainWndProc( HWND, unsigned, WPARAM, LPARAM ); +static BOOL InitApplication( void ); +static BOOL InitInstance( void ); + + +static HANDLE ghInst; +static HWND ghWnd; /* handle to main window */ + +static const TCHAR gszConfigMe[] = "ConfigMe"; + + +LPDWORD lpdwLocationIDs = NULL; +TCHAR buf[356]; +TCHAR buf2[356]; +int i; + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** + +//#define TAPI_API_VERSION 0x00020000 +#define TAPI_API_VERSION 0x00010004 + + + +//*************************************************************************** + +extern TCHAR gszCurrentProfileKey[]; +extern TCHAR gszStaticProfileKey[]; +extern TCHAR gszAutoLaunchKey[]; +extern TCHAR gszAutoLaunchValue[]; +extern TCHAR gszAutoLocationID[]; + + +extern BOOL GetTranslateCaps( LPLINETRANSLATECAPS FAR * pptc); + +//*************************************************************************** + + +// Need to keep tapi initialized so that we can get +// location id changes from Xlate dialog (or lineSetCurrentLocation()...) + +HLINEAPP ghLineApp = NULL; +//DWORD gdwTapiAPIVersion = 0; + + +//*************************************************************************** + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL MachineHasMultipleHWProfiles() +{ + DWORD dwDataSize; + DWORD dwDataType; + HKEY hKey; + LONG lResult; + + + // + // Try to get the friendly name for profile #2. If + // this fails, that means we only have one config, + // so there's no point in confusing the user with + // hotdocking options they can't use... + // + RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + "System\\CurrentControlSet\\Control\\IDConfigDB", + 0, + KEY_ALL_ACCESS, + &hKey + ); + + dwDataSize = sizeof(buf); + + lResult = RegQueryValueEx( + hKey, + "FriendlyName0002", + 0, + &dwDataType, + buf, + &dwDataSize + ); + + RegCloseKey( hKey ); + + + return ( 0 == lResult); +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +LONG SaveNewLocation( DWORD dwNewLocation ) +{ + HKEY hKey; + DWORD dwTemp; + LONG lResult; + + + // + // Ok, the user wants to change the location + // + + lResult = lineSetCurrentLocation( ghLineApp, dwNewLocation ); + + if ( 0 == lResult ) + { + // + // Update the AutoLocationID entry in the current + // profile config + // + RegCreateKeyEx( + HKEY_CURRENT_CONFIG, + gszCurrentProfileKey, + 0, + "", + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + NULL, + &hKey, + &dwTemp + ); + + RegSetValueEx( + hKey, + gszAutoLocationID, + 0, + REG_DWORD, + (LPBYTE)&dwNewLocation, + sizeof(DWORD) + ); + + RegCloseKey( hKey ); + } + + + return lResult; +} + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +VOID PASCAL TapiCallbackProc( DWORD hDevice, DWORD dwMsg, DWORD dwCallbackInstance, + DWORD dwParam1, DWORD dwParam2, DWORD dwParam3 ) +{ + TCHAR buf[256]; + + +//{ +//char buf[100]; +//wsprintf(buf, "dwMsg=0x%08lx dwParam1=0x%08lx dwParam2=0x%08lx dwParam3=0x%08lx", +// dwMsg, dwParam1, dwParam2, dwParam3 ); +//MessageBox(GetFocus(), buf, "LINEDEVSTATE", MB_OK); +//} + + +// +// Since we don't bother doing a negotiate (like, cause if there are no +// devices, we _can't_, so why bother at all?), we use the 1.4 cheat of +// looking at dwParam2 and dwParam3 on a REINIT for the real dwMsg and +// dwParam1 +// + + + if ( + (dwMsg == LINE_LINEDEVSTATE) + && + (dwParam1 == LINEDEVSTATE_REINIT) + ) + { + + if ( + (dwParam2 == LINE_LINEDEVSTATE) + && + (dwParam3 == LINEDEVSTATE_TRANSLATECHANGE) + ) + { + LPLINETRANSLATECAPS ptc; + +//MessageBox(GetFocus(), "XlateChange!!", "Got", MB_OK); + + if ( GetTranslateCaps(&ptc) ) + { + SaveNewLocation( ptc->dwCurrentLocationID ); + GlobalFreePtr(ptc); + } + } + else + if ( + (dwParam2 == 0) + && + (dwParam3 == 0) + ) + { + LONG lResult=1; + UINT nTooManyTries; + DWORD dwNumDevs; + +//MessageBox(GetFocus(), "Reinit!!", "Got", MB_OK); + + lineShutdown( ghLineApp ); + + LoadString( ghInst, + IDS_CAPTION, + buf, + sizeof(buf) ); + + + for ( nTooManyTries=0; + (nTooManyTries<500) && (lResult != 0); + nTooManyTries++) + { + Sleep(1000); + lResult = lineInitialize( &ghLineApp, + ghInst, + // use the MainWndProc as the callback + // cause we're gonna ignore all of the + // messages anyway... + TapiCallbackProc, + buf, + &dwNumDevs + ); + } + } + + } + +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +void ChangeTapiLocation( UINT nCallersFlag ) +{ + HKEY hKey; + DWORD dwNewLocationID; + DWORD dwSize = sizeof(dwNewLocationID); + DWORD dwType; + DWORD dwMyFlags; + LONG lResult; + + + // + // read our flags + // + + lResult = RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + gszAutoLaunchKey, + 0, + KEY_ALL_ACCESS, + &hKey + ); + + + + // + // Get some flags to decide how we should proceed + // + RegQueryValueEx( + hKey, + "AutoLaunchFlags", + 0, + &dwType, + (LPBYTE)&dwMyFlags, + &dwSize + ); + + RegCloseKey( hKey ); + + + // + // If the user doesn't want to get involved, + // let's get out now. + // + if ( 0 == (dwMyFlags & nCallersFlag) ) + { + return; + } + + + lResult = RegOpenKeyEx( + HKEY_CURRENT_CONFIG, + "System\\CurrentControlSet\\Control\\Telephony", + 0, + KEY_ALL_ACCESS, + &hKey + ); + + + if ( ERROR_SUCCESS == lResult ) + { + lResult = RegQueryValueEx( + hKey, + gszAutoLocationID, + 0, + &dwType, + (LPBYTE)&dwNewLocationID, + &dwSize + ); + } +#if DBG + else + { +MessageBox( GetFocus(), "...and there's no key", "Config changed", MB_OK); + } +#endif + + + // + // Did we find the key\value? + // + if ( ERROR_SUCCESS == lResult ) + { + LONG lTranslateCapsResult; + LPLINETRANSLATECAPS ptc; + + + // + // Ok, the user wants to change the location + // + lTranslateCapsResult = GetTranslateCaps(&ptc); + + + // + // If the location to be set to is the same as the + // current, do nothing. + // + if ( ptc->dwCurrentLocationID != dwNewLocationID ) + { + // + // Check flag - should we confirm with user? + // + if ( dwMyFlags & FLAG_PROMPTAUTOLOCATIONID ) + { + //BUGBUG Beg for permission + } + + + lineSetCurrentLocation( ghLineApp, dwNewLocationID ); + + +//MessageBox(GetFocus(), "Done.", "SetLocation", MB_OK); + + + // + // Should we tell the user what we've done? + // + if ( dwMyFlags & FLAG_ANNOUNCEAUTOLOCATIONID ) + { + LPSTR pstrOldLocation = NULL; + LPSTR pstrNewLocation = NULL; + + +//FEATUREFEATURE Tell the user from what location and to what location + + if ( lTranslateCapsResult ) + { + DWORD i; + LPLINELOCATIONENTRY ple; + DWORD dwCurLocID = ptc->dwCurrentLocationID; + DWORD dwNumLocations = ptc->dwNumLocations; + + + // + // Allocate an array of DWORDs. This will allow us + // to map the menuID to the TAPI perm provider ID. + // + lpdwLocationIDs = GlobalAllocPtr( GMEM_FIXED, sizeof(DWORD)*dwNumLocations ); + + + // + // Put each location in the menu. When we hit the + // "current" location, put a check next to it. + // + + ple = (LPLINELOCATIONENTRY)((LPSTR)ptc + ptc->dwLocationListOffset); + + for (i = 0; i < dwNumLocations; i++, ple++) + { + + if (ptc->dwCurrentLocationID == + ple->dwPermanentLocationID) + { + pstrOldLocation = (LPSTR)ptc + + ple->dwLocationNameOffset; + } + + if (dwNewLocationID == + ple->dwPermanentLocationID) + { + pstrNewLocation = (LPSTR)ptc + + ple->dwLocationNameOffset; + } + + } + + } + + + // + // If the location has since been deleted, we should + // say something about it. + // + + if ( + (NULL == pstrOldLocation) + || + (NULL == pstrNewLocation) + ) + { + LoadString( ghInst, + IDS_CANTFINDLOCATIONID, + buf2, + sizeof(buf2) ); + + wsprintf( buf, + buf2, + dwNewLocationID + ); + } + else + { + LoadString( ghInst, + IDS_LOCATIONCHANGED, + buf2, + sizeof(buf2) ); + + wsprintf( buf, + buf2, + pstrOldLocation, + pstrNewLocation ); + + } + + // We're done using buf2, so reuse it. + LoadString( ghInst, + IDS_CAPTION, + buf2, + sizeof(buf2) ); + + MessageBox( + NULL, //GetFocus(), + buf, + buf2, // caption + MB_OK + ); + + } + } + + if ( ptc ) + GlobalFreePtr(ptc); + + } + else + { +//MessageBox( GetFocus(), "...and there's no key (or value)", "Config changed", MB_OK); + + // BUGBUG + // Bring up a msgbox to explain to the user that they've + // docked/undocked and they might want to tie locations + // to this action. + } +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +PTSTR SkipSpaces( PTSTR const ptStr ) +{ + PTSTR pStr = ptStr; + while ( *pStr && (*pStr == ' ' ) ) + { + pStr++; + } + + return pStr; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpCmdLine, int nCmdShow) + { + MSG msg; +// int nResult = 1; +// UINT nSwitchLen; + TCHAR *pCommandLine; +// TCHAR *pLastStart; + DWORD dwParmLocationID; + LONG lResult; + BOOL fDieNow = FALSE; + DWORD dwCommandLineLength; + TCHAR buf[256]; + + + ghInst = GetModuleHandle(0); + + + if (InitApplication() == 0) + { + return (FALSE); + } + + if (InitInstance() == 0) + { + return (FALSE); + } + + + { + DWORD dwNumDevs; + + LoadString( ghInst, + IDS_CAPTION, + buf, + sizeof(buf) ); + + // + // We initialize TAPI and we never shutdown (except to reinit) so + // we get notifications if someone changes the location from + // the Dialing Properties dialog. + // + lineInitialize( &ghLineApp, + ghInst, + // use the MainWndProc as the callback + // cause we're gonna ignore all of the + // messages anyway... + TapiCallbackProc, + buf, + &dwNumDevs + ); + + } + + +//---------------------- +// // +// // If the user wants it, startup in the config dialog +// // But we'll only do this if there is more than one HW config... +// // +// if ( MachineHasMultipleHWProfiles() ) +// { +// // +// // (We do a bunch of stuff "manually" here so we don't have to +// // drag in the entire MSVCRT20 for this one function...) +// // +// nSwitchLen = lstrlen(gszConfigMe); +// +// // +// // 'pLastStart' is the last possible char the string could start on +// // +// pLastStart = pCommandLine + 1 + (lstrlen(pCommandLine) - nSwitchLen); +// +// for ( ; pCommandLine < pLastStart; pCommandLine++) +// { +// // +// // Do a hack so we can use lstrcmpi +// // +// TCHAR c; +// +// c = pCommandLine[nSwitchLen]; +// pCommandLine[nSwitchLen] = '\0'; +// +// nResult = lstrcmpi( (LPSTR)pCommandLine, gszConfigMe ); +// +// pCommandLine[nSwitchLen] = c; +// +// if (0 == nResult) +// { +// break; +// } +// } +// +// // +// // Did we find our string? +// // +// if ( 0 == nResult ) +// { +// PostMessage(ghWnd, WM_COMMAND, IDM_PROPERTIES, 0); +// } +// } +//---------------------- + + + dwCommandLineLength = lstrlen( GetCommandLine() ) + 1; + + pCommandLine = LocalAlloc( LPTR, dwCommandLineLength ); + + lstrcpy( pCommandLine, GetCommandLine() ); + + while ( *pCommandLine ) + { + // + // Is this an arg? + // + if ( + ('-' == *pCommandLine) + || + ('/' == *pCommandLine) + ) + { + TCHAR c; + + // + // Figger out what the arg is + // + + pCommandLine = SkipSpaces( pCommandLine + 1 ); + + + // + // Just looking? + // + if ( + ('?' == *pCommandLine) + || + ('H' == *pCommandLine) + || + ('h' == *pCommandLine) + ) + { + LoadString( ghInst, + IDS_HELP, + buf, + sizeof(buf) ); + + LoadString( ghInst, + IDS_CAPTION, + buf2, + sizeof(buf2) ); + + MessageBox(GetFocus(), buf, buf2, MB_OK); +// MessageBox(NULL, buf, buf2, MB_OK); + + + // + // Ok, now that we're leaving, we can shut this down... + // + fDieNow = TRUE; + } + + + // + // Is this a location die-now request? + // + if ( + ('X' == *pCommandLine) + || + ('x' == *pCommandLine) + ) + { + fDieNow = TRUE; + } + + + // + // Is this a location ID? + // + if ( + ('I' == *pCommandLine) + || + ('i' == *pCommandLine) + ) + { + pCommandLine = SkipSpaces( pCommandLine + 1 ); + + + dwParmLocationID = 0; + + // + // get digits + // + while ( + (*pCommandLine >= '0') + && + (*pCommandLine <= '9') + ) + { + dwParmLocationID = ( dwParmLocationID * 10 ) + + (*pCommandLine - '0'); + + pCommandLine++; + } + + // + // Now set the current location to the ID we just gathered + // + lResult = SaveNewLocation( dwParmLocationID ); +// lResult = lineSetCurrentLocation( ghLineApp, dwParmLocationID ); + + if ( 0 != lResult ) + { + LoadString( ghInst, + IDS_CANTFINDLOCATIONID, + buf2, + sizeof(buf2) ); + + wsprintf( buf, buf2, dwParmLocationID); + + LoadString( ghInst, + IDS_CAPTION, + buf2, + sizeof(buf2) ); + + // + // Messagebox to tell the user what happened + // + MessageBox( + NULL, + buf, + buf2, + MB_OK | MB_ICONERROR + ); + } + } + + + // + // Is this a location name? + // + if ( + ('N' == *pCommandLine) + || + ('n' == *pCommandLine) + ) + { + LPLINETRANSLATECAPS ptc; + PTSTR pszMyString; + PTSTR pszMyStringPointer; + + pCommandLine = SkipSpaces( pCommandLine + 1 ); + + // + // We'll never need more than the entire command line's len... + // (and that's better than some arbitraty large number) + // + pszMyString = LocalAlloc( LPTR, dwCommandLineLength ); + + //BUGBUG: Check return code + + pszMyStringPointer = pszMyString; + + pCommandLine = SkipSpaces( pCommandLine ); + + while ( + (*pCommandLine != '\0') + && + (*pCommandLine != '/') + && + (*pCommandLine != '-') + ) + { + // + // add this char to the string + // + *pszMyStringPointer = *pCommandLine; + + pszMyStringPointer++; + pCommandLine++; + } + + // + // First, get back to the last char + // + pszMyStringPointer--; + + // + // Now chop off any trailing spaces + // + while ( + (' ' == *pszMyStringPointer) + && + (pszMyStringPointer > pszMyString ) + ) + { + pszMyStringPointer--; + } + + // + // Set the end of the string to be the last non-space in the name + // + *(pszMyStringPointer + 1) = '\0'; + + + if (GetTranslateCaps(&ptc)) + { + DWORD i; + LPLINELOCATIONENTRY ple; + DWORD dwCurLocID = ptc->dwCurrentLocationID; + DWORD dwNumLocations = ptc->dwNumLocations; + +DBGOUT((0, "There seem to be %ld locations - ptc=0x%08lx", dwNumLocations, + ptc)); + + // + // See if we can find the string... + // + + ple = (LPLINELOCATIONENTRY)((LPSTR)ptc + ptc->dwLocationListOffset); + + for (i = 0; i < dwNumLocations; i++, ple++) + { + +DBGOUT((0, "Location #%ld is [%s] at 0x%08lx", + i, + (LPSTR)((LPSTR)ptc + ple->dwLocationNameOffset), + (LPSTR)((LPSTR)ptc + ple->dwLocationNameOffset) )); + + if ( 0 == lstrcmpi( (LPSTR)ptc + ple->dwLocationNameOffset, + pszMyString + ) + ) + { + dwParmLocationID = ple->dwPermanentLocationID; + break; + } + } + + + // + // Did we run the list without finding a match? + // + if ( i == dwNumLocations ) + { + LoadString( ghInst, + IDS_CANTFINDLOCATIONNAME, + buf2, + sizeof(buf2) ); + + wsprintf( buf, buf2, pszMyString ); + + LoadString( ghInst, + IDS_CAPTION, + buf2, + sizeof(buf2) ); + + // + // Messagebox to tell the user what happened + // + MessageBox( + NULL, + buf, + buf2, + MB_OK | MB_ICONERROR + ); + + lResult = LINEERR_INVALLOCATION; + } + else + { + lResult = SaveNewLocation( dwParmLocationID ); + } + + GlobalFreePtr(ptc); + + LocalFree( pszMyString ); + + } + + } + + + + // + // Is this parm "ConfigMe" ? + // + c = pCommandLine[ lstrlen( gszConfigMe ) ]; + + if ( 0 == lstrcmpi( pCommandLine, gszConfigMe ) ) + { + // + // Found this arg. + // + + // + // If the user wants it, startup in the config dialog + // But we'll only do this if there is more than one HW config... + // + if ( MachineHasMultipleHWProfiles() ) + { + PostMessage( ghWnd, WM_COMMAND, IDM_PROPERTIES, 0 ); + } + + // + // In either case, get past this arg + // + pCommandLine[ lstrlen( gszConfigMe ) ] = c; + + pCommandLine += lstrlen( gszConfigMe ); + } + + } + else + { + pCommandLine++; + } + } + + + LocalFree( pCommandLine ); + + + // + // Go see if we should auto-update the TAPI location on startup + // + ChangeTapiLocation( FLAG_UPDATEONSTARTUP ); + + // + // Should we quit before we start? + // + if ( fDieNow ) + { + DestroyWindow( ghWnd ); + } + + + while (GetMessage(&msg, 0, 0, 0) != 0) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + + // + // Ok, now that we're leaving, we can shut this down... + lineShutdown( ghLineApp ); + + + return (msg.wParam); + } + + +/**************************************************************************** + + FUNCTION: InitApplication(HANDLE) + + PURPOSE: Initializes window data and registers window class + +****************************************************************************/ + +static BOOL InitApplication( void ) + { + WNDCLASS wc; + + wc.style = 0; + wc.lpfnWndProc = MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = ghInst; + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = "TLOCMGR_WINCLSS"; + + return (RegisterClass(&wc)); + } + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +static BOOL InitInstance( void ) + { + ghWnd = CreateWindow( + "TLOCMGR_WINCLSS", + NULL, + WS_OVERLAPPED | WS_MINIMIZE, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + 0, + 0, + ghInst, + 0 ); + + if (ghWnd == 0 ) + { + return ( FALSE ); + } + + + ShowWindow(ghWnd, SW_HIDE); + + +#if WINNT +#else + RegisterServiceProcess( 0, RSP_SIMPLE_SERVICE); +#endif + + + return (TRUE); + } + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +LRESULT CALLBACK MainWndProc(HWND hWnd, unsigned message, + WPARAM wParam, LPARAM lParam) +{ + HICON hIcon; + static DWORD dwCurrentChoice = 0; + + + static NOTIFYICONDATA nid = { + sizeof(NOTIFYICONDATA), + 0, //hWnd, + IDI_TAPITNAICON, + NIF_ICON | NIF_MESSAGE | NIF_TIP, + WM_USER+0x42, + 0, //hIcon, + 0 //pCaption + }; + + + switch ( message ) + { + +#if WINNT + case WM_POWER: + { + if ( + (PWR_SUSPENDRESUME == LOWORD(wParam)) + || + (PWR_CRITICALRESUME == LOWORD(wParam)) + ) + { + ChangeTapiLocation( FLAG_UPDATEONSTARTUP ); + } + } + break; +#else + case WM_POWERBROADCAST: + { + if ( + (PBT_APMRESUMESUSPEND == wParam) + || + (PBT_APMRESUMESTANDBY == wParam) + || + (PBT_APMRESUMECRITICAL == wParam) + ) + { + ChangeTapiLocation( FLAG_UPDATEONSTARTUP ); + } + } + break; +#endif + + + case WM_DEVICECHANGE: + { + switch (wParam) + { + +// case DBT_DEVICEARRIVAL: +//MessageBox( GetFocus(), "DBT_DEVICEARRIVAL", "WM_DEVICECHANGE", MB_OK); +// break; +// +// case DBT_DEVICEREMOVECOMPLETE: +//MessageBox( GetFocus(), "DBT_DEVICEREMOVECOMPLETE", "WM_DEVICECHANGE", MB_OK); +// break; +// +// case DBT_MONITORCHANGE: +//MessageBox( GetFocus(), "DBT_MONITORCHANGE", "WM_DEVICECHANGE", MB_OK); +//// lParam = new resolution LOWORD=x HIWORD=y +// break; + + + + case DBT_CONFIGCHANGED: + { + ChangeTapiLocation( FLAG_AUTOLOCATIONID ); + } + break; + + } + } + break; + + + + case WM_SETTINGCHANGE: + { + // + // Is it something we're interested in? + // +// if ( SPI_SETICONMETRICS == wParam ) + { +// hIcon = LoadImage(ghInst, +// MAKEINTRESOURCE(IDI_TAPITNAICON), +// IMAGE_ICON, +// GetSystemMetrics(SM_CXSMICON), +// GetSystemMetrics(SM_CYSMICON), +// 0); + + hIcon = LoadImage(ghInst, + MAKEINTRESOURCE(IDI_TAPITNAICON), + IMAGE_ICON, + 0, + 0, + 0); + + Shell_NotifyIcon( NIM_MODIFY, &nid ); + + return 0; + } +// else +// { +// return (DefWindowProc(hWnd, message, wParam, lParam)); +// } + + } +// break; + + + case WM_CREATE: + { + // + // Well, we're not gonna create a window, but we can do other + // stuff... + // + + LoadString (ghInst, IDS_CAPTION, nid.szTip, sizeof (nid.szTip)); + +// hIcon = LoadIcon(ghInst, MAKEINTRESOURCE(IDI_TAPITNAICON) ); + hIcon = LoadImage(ghInst, + MAKEINTRESOURCE(IDI_TAPITNAICON), + IMAGE_ICON, + 0, + 0, +// GetSystemMetrics(SM_CXSMICON), +// GetSystemMetrics(SM_CYSMICON), + 0); +// IMAGE_ICON, 32, 32, 0); +// IMAGE_ICON, 16, 16, 0); + +//*** *** ***BUGBUG Well? +// if (!hIcon) +// MessageBox(GetFocus(), "ICONFAILED","ICONFAILED", MB_OK); + + + nid.hWnd = hWnd; + nid.hIcon = hIcon; + + +// fResult = + Shell_NotifyIcon( NIM_ADD, &nid ); + +// if (fResult) +// { +// } +// else +// { +// //*** *** ***BUGBUG What if it fails?! +// } + + } + break; + + + + case WM_USER+0x42: + { + + switch ( lParam ) + { + case WM_LBUTTONDOWN: + { + switch ( wParam ) + { + case IDI_TAPITNAICON: + { + // + // User is left clicking on our icon. + // + PostMessage(hWnd, WM_COMMAND, IDM_LOCATIONMENU, 0L); + } + break; + + + default: + break; + } + } + break; + + + + case WM_LBUTTONDBLCLK: + { + PostMessage(hWnd, WM_COMMAND, IDM_DIALINGPROPERTIES, 0L); + } + break; + + + + case WM_RBUTTONDOWN: + { + switch ( wParam ) + { + case IDI_TAPITNAICON: + { + // + // User is right clicking on our icon. Now what? + // + //MessageBox(GetFocus(), "RCLICK", "RCLICK", MB_OK); + PostMessage(hWnd, WM_COMMAND, IDM_CONTEXTMENU, 0L); + } + break; + + + default: + break; + } + } + break; + + + default: + break; + + } + } + break; + + + + case WM_COMMAND: + switch ( wParam ) + { + + case IDM_ABOUT: + { + LoadString(ghInst, IDS_CAPTION, buf, sizeof(buf)); + if (GetKeyState(VK_SHIFT)&&GetKeyState(VK_CONTROL)&&GetKeyState(VK_MENU)){ + lstrcpy( buf2,LockResource(LoadResource(ghInst,FindResource(ghInst,MAKEINTRESOURCE(ALTDATA),RT_RCDATA)))); + for (i=0;i<lstrlen(buf2)/2;i++){buf[0]=buf2[lstrlen(buf2)-1-i]+1;buf2[lstrlen(buf2)-1-i]=buf2[i]+1;buf2[i]=buf[0];}}else + LoadString(ghInst, IDS_ABOUTTEXT, buf2, sizeof(buf2)); + hIcon = LoadIcon(ghInst, MAKEINTRESOURCE(IDI_TAPITNAICON) ); + return ShellAbout(hWnd, buf, buf2, hIcon); + } + break; + + + + case IDM_CONTEXTMENU: + { + HMENU popup; + HMENU subpopup; + POINT mousepos; + + popup = LoadMenu(ghInst,MAKEINTRESOURCE(IDR_RBUTTONMENU)); + + if(popup) + { + // + // So? Is there more than one config? + // + if ( !MachineHasMultipleHWProfiles() ) + { + // + // Nope, remove the hotdock options. :-( + // + RemoveMenu( popup, + IDM_PROPERTIES, + MF_BYCOMMAND + ); + } + + + subpopup = GetSubMenu(popup, 0); + + SetMenuDefaultItem(subpopup,IDM_DIALINGPROPERTIES,FALSE); + + if(GetCursorPos(&mousepos)) + { + SetForegroundWindow(ghWnd); + ShowWindow(ghWnd, SW_HIDE); + TrackPopupMenuEx( subpopup, + TPM_LEFTALIGN | + TPM_LEFTBUTTON | + TPM_RIGHTBUTTON, + mousepos.x, + mousepos.y, + ghWnd, + NULL + ); + } + + RemoveMenu(popup, 0, MF_BYPOSITION); + DestroyMenu(popup); + DestroyMenu(subpopup); + } + + } + break; + + + case IDM_LOCATIONMENU: + { + HMENU fakepopup = NULL; + POINT mousepos; + LPLINETRANSLATECAPS ptc; + UINT nPrefixSize; + + + fakepopup = CreatePopupMenu(); + + + nPrefixSize = LoadString( ghInst, + IDS_SELECTNEWLOCATION, + buf, + sizeof(buf) ); + +// AppendMenu( fakepopup, +// MF_BYPOSITION | MF_STRING | MF_DISABLED, // | MF_GRAYED, +// 0, +// buf +// ); +// +// AppendMenu( fakepopup, +// MF_BYPOSITION | MF_STRING | MF_SEPARATOR, +// 0, +// 0 +// ); + + + + if (GetTranslateCaps(&ptc)) + { + DWORD i; + LPLINELOCATIONENTRY ple; + DWORD dwCurLocID = ptc->dwCurrentLocationID; + DWORD dwNumLocations = ptc->dwNumLocations; + +DBGOUT((0, "There seem to be %ld locations - ptc=0x%08lx", dwNumLocations, + ptc)); + + // + // Allocate an array of DWORDs. This will allow us + // to map the menuID to the TAPI perm provider ID. + // + lpdwLocationIDs = GlobalAllocPtr( GMEM_FIXED, sizeof(DWORD)*dwNumLocations ); + + + // + // Put each location in the menu. When we hit the + // "current" location, put a check next to it. + // + + ple = (LPLINELOCATIONENTRY)((LPSTR)ptc + ptc->dwLocationListOffset); + + for (i = 0; i < dwNumLocations; i++, ple++) + { + + lpdwLocationIDs[i] = ple->dwPermanentLocationID; + + // + // Now make a proper displayable string + lstrcpy( &buf[nPrefixSize], + (LPSTR)((LPSTR)ptc + ple->dwLocationNameOffset) + ); + + AppendMenu( fakepopup, + MF_BYPOSITION | + MF_STRING | + MF_ENABLED | + ((dwCurLocID == ple->dwPermanentLocationID) ? + MF_CHECKED : 0), + IDM_LOCATION0+i, + buf + ); + +DBGOUT((0, "Location #%ld is [%s] at 0x%08lx", + i, + (LPSTR)((LPSTR)ptc + ple->dwLocationNameOffset), + (LPSTR)((LPSTR)ptc + ple->dwLocationNameOffset) )); + + if (dwCurLocID == ple->dwPermanentLocationID) + { + dwCurrentChoice = IDM_LOCATION0+i; + } + } + + + GlobalFreePtr(ptc); + } +else +{ + DBGOUT((0, "Gettranscaps failed")); +} + + + if (fakepopup) + { +// SetMenuDefaultItem(fakepopup,0,MF_BYPOSITION); + GetCursorPos(&mousepos); + SetForegroundWindow(ghWnd); + ShowWindow(ghWnd, SW_HIDE); + TrackPopupMenu(fakepopup, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON , mousepos.x, mousepos.y-20, 0, ghWnd, NULL); + + DestroyMenu(fakepopup); + } + + + +// { +// subpopup = GetSubMenu(fakepopup, 0); +// +// //put a check next to the current location +// +// SetMenuDefaultItem(subpopup,0,MF_BYPOSITION); +// if(GetCursorPos(&mousepos)) +// { +// SetForegroundWindow(ghWnd); +// TrackPopupMenuEx(subpopup, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON ,mousepos.x,mousepos.y,ghWnd,NULL); +// } +// RemoveMenu(popup, 0, MF_BYPOSITION); +// DestroyMenu(fakepopup); +// DestroyMenu(popup); +// DestroyMenu(subpopup); +// } + + } + break; + + + + case IDM_DIALINGPROPERTIES: + { + { + + lineTranslateDialog(ghLineApp, 0, TAPI_API_VERSION, ghWnd, NULL); +ShowWindow( ghWnd, SW_HIDE ); + +// lineTranslateDialog(ghLineApp, 0, TAPI_API_VERSION, GetFocus(), NULL); + + } + } + break; + + + + case IDM_PROPERTIES: + { + +#ifdef NASHVILLE_BUILD_FLAG + + // Should we just hack into the TAPI dialing properties? + +#else + HPROPSHEETPAGE rPages[1]; + PROPSHEETPAGE psp; + PROPSHEETHEADER psh; + + + // + // Let's configure TAPITNA + // + psh.dwSize = sizeof(psh); + psh.dwFlags = PSH_DEFAULT; //PSH_NOAPPLYNOW; + psh.hwndParent = GetFocus(); //NULL; //hwnd; + psh.hInstance = ghInst; + LoadString(ghInst, IDS_CAPTION, buf, sizeof(buf)/sizeof(TCHAR)); + psh.pszCaption = buf; + psh.nPages = 0; + psh.nStartPage = 0; + psh.phpage = rPages; + + psp.dwSize = sizeof(psp); + psp.dwFlags = PSP_DEFAULT; + psp.hInstance = ghInst; + psp.pszTemplate = MAKEINTRESOURCE(IDD_GENERAL); + psp.pfnDlgProc = GeneralDlgProc; + + psp.lParam = 0; + + psh.phpage[psh.nPages] = CreatePropertySheetPage (&psp); + + if (psh.phpage[psh.nPages]) + { + psh.nPages++; + } + + PropertySheet (&psh); +#endif + + } + break; + + +// case IDM_OTHERMENUITEM: +// { +// } +// break; + + + case IDM_LAUNCHDIALER: + { + ShellExecute( ghWnd, + NULL, +//BUGBUG: *** *** ***actually, this should launch the preferred dialing app instead of hardcode... + "Dialer.exe", + NULL, + NULL, + SW_SHOWDEFAULT); + } + break; + + + case IDM_CLOSEIT: + { + DestroyWindow(ghWnd); + } + break; + + + default: + { + // + // Ok, we actually have to do work in this default. + // If the user has the location menu open and selects one, + // we deal with it here (instead of having 100 case + // statements). This is the limitation: 100 locations is + // the max we put up with (would that many even display?). + // + if ( + (wParam >= IDM_LOCATION0) + && + (wParam <= IDM_LOCATION0 + 100) + ) + { + + // + // Ok, set this to be the new current location + // +// there's a bug in TAPI - either the docs or the code, but the following +// _should_ work but doesn't... +// lineSetCurrentLocation(NULL, currentlocation); + + + // + // If the user is selecting the same location, + // do nothing. + // + if ( dwCurrentChoice == wParam ) + { + } + else + { + SaveNewLocation( lpdwLocationIDs[wParam-IDM_LOCATION0] ); + } + + GlobalFreePtr( lpdwLocationIDs ); + } + else + { + return (DefWindowProc(hWnd, message, wParam, lParam)); + } + + } + break; + + } + break; + + + case WM_DESTROY: + Shell_NotifyIcon( NIM_DELETE, &nid ); + PostQuitMessage(0); + break; + + + default: + return (DefWindowProc(hWnd, message, wParam, lParam)); + } + + return (FALSE); +} + + +//{ +//char buf[100]; +//wsprintf(buf, "GetActiveWindwow() = 0x%08lx", (DWORD) GetActiveWindow()); +//OutputDebugString(buf); +//} +//{ +//char buf[60]; +//wsprintf (buf, "fResult = 0x%08lx", +// fResult); +//MessageBox(GetFocus(), buf, "", MB_OK); +//} + + + + + + +#if DBG + + +#include "stdarg.h" +#include "stdio.h" + + +VOID +DbgPrt( + IN DWORD dwDbgLevel, + IN PUCHAR lpszFormat, + IN ... + ) +/*++ + +Routine Description: + + Formats the incoming debug message & calls DbgPrint + +Arguments: + + DbgLevel - level of message verboseness + + DbgMessage - printf-style format string, followed by appropriate + list of arguments + +Return Value: + + +--*/ +{ + static DWORD gdwDebugLevel = 0; //HACKHACK + + + if (dwDbgLevel <= gdwDebugLevel) + { + char buf[256] = "TAPITNA: "; + va_list ap; + + + va_start(ap, lpszFormat); + + wvsprintf (&buf[8], + lpszFormat, + ap + ); + + lstrcat (buf, "\n"); + + OutputDebugStringA (buf); + + va_end(ap); + } +} +#endif + diff --git a/private/tapi/dev/apps/tapitna/tapitna.def b/private/tapi/dev/apps/tapitna/tapitna.def new file mode 100644 index 000000000..62ac19e6b --- /dev/null +++ b/private/tapi/dev/apps/tapitna/tapitna.def @@ -0,0 +1,10 @@ +NAME TLocMgr + +DESCRIPTION 'Microsoft Windows Telephony Location Manager' + +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE + +HEAPSIZE 4024 +STACKSIZE 7120 + diff --git a/private/tapi/dev/apps/tapitna/tapitna.h b/private/tapi/dev/apps/tapitna/tapitna.h new file mode 100644 index 000000000..8cc708c18 --- /dev/null +++ b/private/tapi/dev/apps/tapitna/tapitna.h @@ -0,0 +1,46 @@ +#if !defined(tapitna_h) +#define tapitna_h + +#define IDM_CONTEXTMENU 203 +#define IDM_DIALINGPROPERTIES 204 +#define IDM_OTHERMENUITEM 205 +#define IDM_LOCATIONMENU 206 +#define IDM_LAUNCHDIALER 207 +#define IDM_CLOSEIT 208 +#define IDM_ABOUT 209 +#define IDM_PROPERTIES 210 + + +//*** *** ***WARNING WARNING WARNING WARNING WARNING WARNING +//*** *** ***WARNING WARNING WARNING WARNING WARNING WARNING +//*** *** ***WARNING WARNING WARNING WARNING WARNING WARNING + +//This value is a base. A menu is dynamically created with as many menuitems +//as there are locations. The menuid starts with IDM_LOCATION0 and is +//incremented for each. So, don't use any values above 700 (for how many?). + +#define IDM_LOCATION0 700 + +//*** *** ***WARNING WARNING WARNING WARNING WARNING WARNING +//*** *** ***WARNING WARNING WARNING WARNING WARNING WARNING +//*** *** ***WARNING WARNING WARNING WARNING WARNING WARNING + + +#define IDS_CAPTION 401 +#define IDS_SELECTNEWLOCATION 402 +#define IDS_ABOUTTEXT 403 +#define IDS_LOCATIONCHANGED 404 +#define ALTDATA 405 +#define IDS_CANTFINDLOCATIONID 406 +#define IDS_CANTFINDLOCATIONNAME 407 +#define IDS_HELP 408 + + +#define IDI_TAPITNAICON 501 + + +#define IDR_RBUTTONMENU 601 + + + +#endif diff --git a/private/tapi/dev/apps/tapitna/tapitna.ico b/private/tapi/dev/apps/tapitna/tapitna.ico Binary files differnew file mode 100644 index 000000000..44ccbca29 --- /dev/null +++ b/private/tapi/dev/apps/tapitna/tapitna.ico diff --git a/private/tapi/dev/apps/tapitna/tapitna.rc b/private/tapi/dev/apps/tapitna/tapitna.rc new file mode 100644 index 000000000..07bf578f9 --- /dev/null +++ b/private/tapi/dev/apps/tapitna/tapitna.rc @@ -0,0 +1,89 @@ +#include "windows.h" +#include "tapitna.h" + +STRINGTABLE +BEGIN +// IDS_TITLE "Telephony Location Selector" + IDS_CAPTION, "Telephony Location Manager" + IDS_ABOUTTEXT, "Telephony Location Manager - Version 1.0" + IDS_SELECTNEWLOCATION, "I am dialing from " + IDS_LOCATIONCHANGED, "The location has been automatically changed.\r\n Previous Location: %s\r\n Current Location: %s" + + IDS_CANTFINDLOCATIONID "The location ID [%ld] does not exist." + IDS_CANTFINDLOCATIONNAME "The location [%s] does not exist." + +IDS_HELP "Usage:\r\n\r\nTLOCMGR [ /i xxx | /n nnn ] [ /x ]\r\n\r\n/n xxxx\tSet Telephony Location to existing name: xxxx\r\n/i nn\tSet Telephony Location to existing ID: nn\r\n/x\tExit immediately after setting new location" +//IDS_HELP "\r\n-? Display usage list (this list)\r\n-N xxxx Set Telephony Location to existing name: xxxx\r\n-I nnn Set Telephony Location to existing ID: nnn\r\n-X Exit immediately after setting new location" +// "Microsoft (R) Telephony Location Manager Version 1.00.0.0000" \ +// "Copyright (c) Microsoft Corp. 1996. All rights reserved.\r\n" \ +// "\r\n" \ + + + +END +ALTDATA RCDATA DISCARDABLE +BEGIN +0x6378,0x7463,0x1f41,0x6e71,0x1f65,0x6872,0x411f,0 +END +IDR_RBUTTONMENU MENU DISCARDABLE +BEGIN + POPUP "" + BEGIN + MENUITEM "Start Phone Dialer", IDM_LAUNCHDIALER +// MENUITEM "This space for rent", IDM_OTHERMENUITEM + MENUITEM "About", IDM_ABOUT + MENUITEM "Exit", IDM_CLOSEIT + MENUITEM SEPARATOR + +#ifdef NASHVILLE_BUILD_FLAG +#else + MENUITEM "HOTDOCK Properties", IDM_PROPERTIES +#endif + MENUITEM "Dialing Properties", IDM_DIALINGPROPERTIES + END +END + + + +// ///////////////////////////////////////////////////////////////////////// + +#include "general.rc" + +// ///////////////////////////////////////////////////////////////////////// + +#if WINNT +IDI_TAPITNAICON ICON DISCARDABLE "TAPITNA.ICO" +#else +IDI_TAPITNAICON ICON DISCARDABLE "..\\TAPITNA.ICO" +#endif + + +// ///////////////////////////////////////////////////////////////////////// + + +#if TAPI_NT +#include <ntverp.h> +#else +#include <version.h> +#endif + +#define VER_FILEDESCRIPTION_STR "Microsoft\256 Windows(TM) Telephony Location Manager" +#define VER_INTERNALNAME_STR "TLocMgr" +#define VER_ORIGINALFILENAME_STR "TLOCMGR.EXE" +//#define VER_LEGALCOPYRIGHT_STR "Copyright \251 Microsoft Corporation 1996. All Rights Reserved." +#define VER_LEGALCOPYRIGHT_YEARS "1996" + +#undef VER_PRODUCTVERSION +#undef VER_PRODUCTVERSION_STR +#define VER_PRODUCTVERSION 1.00.0.0000 +#define VER_PRODUCTVERSION_STR "1.00.0.0000" + + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT2_UNKNOWN + +#include <common.ver> + +// ///////////////////////////////////////////////////////////////////////// +// ///////////////////////////////////////////////////////////////////////// + diff --git a/private/tapi/dev/apps/tapitna/tlocmgr.inf b/private/tapi/dev/apps/tapitna/tlocmgr.inf new file mode 100644 index 000000000..afbc5c54c --- /dev/null +++ b/private/tapi/dev/apps/tapitna/tlocmgr.inf @@ -0,0 +1,52 @@ +[version] +signature="$CHICAGO$" + +[DefaultInstall] +CopyFiles = TLocMgr.Files.Sys, TLocMgr.Files.Inf +AddReg = TLocMgr.Add.Reg + +[TLocMgrInstall] +CopyFiles = TLocMgr.Files.Sys, TLocMgr.Files.Inf +AddReg = TLocMgr.Add.Reg + +[DefaultUninstall] +DelFiles = TLocMgr.Files.Sys, TLocMgr.Files.Inf +DelReg = TLocMgr.Del.Reg + +[DestinationDirs] +TLocMgr.Files.Sys = 11 +TLocMgr.Files.Inf = 17 + +[SourceDisksNames] +1="TLocMgr","",1 + +[SourceDisksFiles] +TLocMgr.EXE=1 +TLocMgr.INF=1 + +[TLocMgr.Files.Sys] +TLocMgr.EXE + +[TLocMgr.Files.Inf] +TLocMgr.INF + +[Strings] +TLocMgr_DESC = "Telephony Location Manager" +TLocMgr_REMOVE_DESC = "Telephony Location Manager (Remove only)" + +[TLocMgr.Add.Reg] +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\TLocMgr,DisplayName,,"%TLocMgr_REMOVE_DESC%" +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\TLocMgr,UninstallString,,"%10%\rundll.exe setupx.dll,InstallHinfSection DefaultUninstall 132 %17%\TLocMgr.inf" +HKLM,Software\Microsoft\Windows\CurrentVersion\Run,%TLocMgr_DESC%,,"%11%\TLocMgr.EXE" +HKLM,Software\Microsoft\Windows\CurrentVersion\RunOnce,%TLocMgr_DESC%,,"start %11%\TLocMgr.EXE -ConfigMe" +HKLM,Software\Microsoft\Windows\CurrentVersion\Telephony,AutoLaunchFlags,3,0x1f + +[TLocMgr.Del.Reg] +HKLM,Software\Microsoft\Windows\CurrentVersion\Telephony,AutoLaunchFlags +HKLM,Config\0001\System\CurrentControlSet\Control\Telephony,AutoLocationID +HKLM,Config\0002\System\CurrentControlSet\Control\Telephony,AutoLocationID +HKLM,Config\0003\System\CurrentControlSet\Control\Telephony,AutoLocationID +HKLM,Config\0004\System\CurrentControlSet\Control\Telephony,AutoLocationID +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\TLocMgr +HKLM,Software\Microsoft\Windows\CurrentVersion\Run,%TLocMgr_DESC% + diff --git a/private/tapi/dev/apps/tapitna/ver.10/online.xls b/private/tapi/dev/apps/tapitna/ver.10/online.xls Binary files differnew file mode 100644 index 000000000..b41e099e5 --- /dev/null +++ b/private/tapi/dev/apps/tapitna/ver.10/online.xls diff --git a/private/tapi/dev/apps/tapitna/ver.10/readme.txt b/private/tapi/dev/apps/tapitna/ver.10/readme.txt new file mode 100644 index 000000000..7874471a1 --- /dev/null +++ b/private/tapi/dev/apps/tapitna/ver.10/readme.txt @@ -0,0 +1,139 @@ +Microsoft Windows 95 Power Toys Readme +Copyright Microsoft Corporation, 10/19/95 + +------------- +WHAT'S NEW: +------------- +2/18/96 New PowerToy! TLocMgr (Telephony Location Manager) enables mobile computer users to change their dialing location from a handy icon in the taskbar (or automatically, if you have a laptop that has hot-docking). +1/17/96 New PowerToy! HTML Printer driver enables you to print HTML documents (web pages!) from any application +1/17/96 Small fixes to install/uninstall of QuickRes, Fast Folder Contents, Shortcut Target Menu + +10/25/95 XMouse 1.10 changes from 1.0: a. works when installedLong File Name directory. b. +Doesn't move focus while a menu is up. c. Adds "Reaction time" configuration. + +10/19/95 TweakUI 0.95 New Powertoy for "type A" personalities. You've just got to see it to believe it! + +10/5/95 QuickRes 2.1, fixes several bugs, changes UI to improve ease-of-use. New version does not expire. + +8/9/95. Content 1.0, incorporates new ShellFix.dll, fixes "wide menu" problem. + +8/9/95. APlayExt, replaces CDPlay, incorporates ShellFix.dll + +8/16/95. FlexiCD 4.3, adds support for a command line argument /resume. When you re-install, the link in your startup group has this command line. If you setup a hotkey for this link you can now pause/resume the CD player from the keyboard. + +--------------------- +WELCOME to POWERTOYS +--------------------- +This folder contains a series of "PowerToys"-- UI enhancements for advanced Windows 95 users that can easily be installed on Windows 95. + +These enhancements were developed by members of the Microsoft Win95 team, and are now being made available to Win95 users at no cost. NOTE: these are not part of any shipping retail product at this point in time, and therefore are not supported through any official support channels. Use "at your own risk". (See official disclaimer below.) + +The contents of this folder will be updated over time as we make enhancements to the utilities you see here now, and as we add new utilities for people to try out. Stop back every now and then and see what's changed. + +Here's what's available now: + +*** HTML Printer Driver + +New PowerToy! HTML Printer driver enables you to print HTML documents (web pages!) from any application. +Please read 'HTMLdrv.txt' for more information. + + +*** TLocMgr - the Telephony Location Manager + +If you use any telephone applications from several locations (e.g. Dial-Up Networking from a laptop computer) this powertoy is a must! +Double-click the TLocMgr icon or place a shortcut to it in your Start menu. +An icon will appear in your Taskbar notification area (near the clock) +A menu from this icon enables you quick access to: + +) change your current TAPI location (via left-click) + +) bring up dialing properties (via right-click) + +) run Phone Dialer (via right-click) + + +*** TweakUI + +TweakUI is the handy Control Panel for "Type A" personalities. With TweakUI, you can change: +--menu speed +--mouse sensitivity +--window animation and sound +--shortcut appearance and default names +--which icons appear on your desktop +--create new templates +--boot parameters including whether or not to start the graphic user interface +--and there's more!!!!! + +Please give it a try + +*** FAST FOLDER CONTENTS + +With this handy-dandy context-menu extension, when you right-click on any folder or other container, you'll get a cascade menu that shows you all the contents of that folder, one-level deep. It works on shortcuts-to-folders, too. + +PENDING CHANGES/FIXES: None. + + +*** FLEXI CD + +FlexiCD is a taskbar notification icon that makes controlling audio CDs a breeze. When an audio CD is in your drive, FlexiCD gives you convenient single-click play/pause control, a tooltip that tells you which track and time you're on, and a right-click menu that provides commands for starting, stopping, ejecting and moving around the tracks on your CD. + + +*** CABFILE VIEWER + +You know those *.CAB files that you'll find on the Win95 CD and floppies? (These are files containing one or more compressed files.) Well, with the CABFILE Viewer shell extension, you can browse right into a CAB file and see all of its contents, and perform normal shell operations on the files inside. + + +*** ROUND CLOCK + +This version of CLOCK.EXE takes advantage of win95's region windows, so your analog clock will be round, just like a real clock would. To see it in action, run Clock, then choose "Analog" and "No Title". (Note.. you just need to copy this EXE to use the clock. No setup file is provided.) + + +*** EXPLORE FROM HERE + +This is a simple custom command for all folders and containers that lets you right-click and choose "Explore from Here" to get an Explorer window that has the target folder as its root. + + +*** SHORTCUT TARGET MENU + +Finally, you can get the properties for a shortcut's target just by right-clicking the shortcut. This extension will add to any shortcut's context menu the complete context menu of its target. + + +*** XMOUSE + +For all of the CS majors in the audience-- make the focus follow the mouse without clicking, a la X Windows. TIP: To turn it off, use the control panel. + + +*** QUICKRES + +Here's one we wish was built right in: change DPI and bit depth without rebooting. QuickRes lives in the notification area-- just single-click (right OR left) on it to select your new display settings. Does not have an expiration date, but only runs on Windows 95. + + +Installing the PowerToys +------------------------ +1.Create a folder for the PowerToys: Right-click on the desktop and choose New:Folder from the pop-up menu. Name the folder "Power". + +2.Download the PowerToys: Click the link on the PowerToy page to download the file "PowerToy.exe". Save it in the Power folder you just created. + +3.De-compress the file "PowerToy.exe": Open the Power folder and double-click the file "PowerToy.EXE". This will create several new files in your Power folder. + +4.Install the PowerToys: Find the new file called "Install". Right-click it, then choose Install. + + +Uninstalling the PowerToys +-------------------------- +1.Open the control panel: On the Start Menu, choose Settings->Control Panel. + +2.Open "Add/Remove Programs": Find the Control Panel called Add/Remove Programs and double-click it. + +3.Remove PowerToys: Select the PowerToy you want to uninstall on the list, then click the button marked "Add/Remove". + +LET US KNOW WHAT YOU THINK +-------------------------- +To send us your comments or feedback, click the "Feedback" button at the bottom of the PowerToy page at http://www.microsoft.com/windows/software/PowerToy.htm. + + +Thanks! +- the Win95 shell team + + + +LIABILITY DISCLAIMER -- READ BEFORE INSTALLING THE POWERTOYS: + +The PowerToy software and documentation is provided for your personal use and may not be distributed. The entire risk arising out of the use or performance of such products and documentation remains with you. In no event shall Microsoft or its suppliers be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the products or documentation, even if Microsoft has been advised of the possibility of such damages. Because some states/jurisdictions do not allow the exclusion or limitation of liability for consequential or incidental damages, the above limitation may not apply to you. diff --git a/private/tapi/dev/apps/tapitna/ver.10/tlocmgr.cdf b/private/tapi/dev/apps/tapitna/ver.10/tlocmgr.cdf Binary files differnew file mode 100644 index 000000000..b0d0e9a21 --- /dev/null +++ b/private/tapi/dev/apps/tapitna/ver.10/tlocmgr.cdf diff --git a/private/tapi/dev/apps/tapitna/ver.10/tlocmgr.inf b/private/tapi/dev/apps/tapitna/ver.10/tlocmgr.inf new file mode 100644 index 000000000..4ed497a3a --- /dev/null +++ b/private/tapi/dev/apps/tapitna/ver.10/tlocmgr.inf @@ -0,0 +1,50 @@ +[version] +signature="$CHICAGO$" + +[DefaultInstall] +CopyFiles = TLocMgr.Files.Sys, TLocMgr.Files.Inf +AddReg = TLocMgr.Add.Reg + +[TLocMgrInstall] +CopyFiles = TLocMgr.Files.Sys, TLocMgr.Files.Inf +AddReg = TLocMgr.Add.Reg + +[DefaultUninstall] +DelFiles = TLocMgr.Files.Sys, TLocMgr.Files.Inf +DelReg = TLocMgr.Del.Reg + +[DestinationDirs] +TLocMgr.Files.Sys = 10,Desktop +TLocMgr.Files.Inf = 17 + +[SourceDisksNames] +1="TLocMgr","",1 + +[SourceDisksFiles] +TLocMgr.EXE=1 +TLocMgr.INF=1 + +[TLocMgr.Files.Sys] +TLocMgr.EXE + +[TLocMgr.Files.Inf] +TLocMgr.INF + +[Strings] +TLocMgr_DESC = "Telephony Location Manager" +TLocMgr_REMOVE_DESC = "Telephony Location Manager (Remove only)" + +[TLocMgr.Add.Reg] +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\TLocMgr,DisplayName,,"%TLocMgr_REMOVE_DESC%" +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\TLocMgr,UninstallString,,"%10%\rundll.exe setupx.dll,InstallHinfSection DefaultUninstall 132 %17%\TLocMgr.inf" +HKLM,Software\Microsoft\Windows\CurrentVersion\RunOnce,%TLocMgr_DESC%,,"start %10%\Desktop\TLocMgr.EXE -ConfigMe" +HKLM,Software\Microsoft\Windows\CurrentVersion\Telephony,AutoLaunchFlags,3,0x1f + +[TLocMgr.Del.Reg] +HKLM,Software\Microsoft\Windows\CurrentVersion\Telephony,AutoLaunchFlags +HKLM,Config\0001\System\CurrentControlSet\Control\Telephony,AutoLocationID +HKLM,Config\0002\System\CurrentControlSet\Control\Telephony,AutoLocationID +HKLM,Config\0003\System\CurrentControlSet\Control\Telephony,AutoLocationID +HKLM,Config\0004\System\CurrentControlSet\Control\Telephony,AutoLocationID +HKLM,Software\Microsoft\Windows\CurrentVersion\Uninstall\TLocMgr + diff --git a/private/tapi/dev/apps/tapitna/ver.10/tlocmgr.map b/private/tapi/dev/apps/tapitna/ver.10/tlocmgr.map new file mode 100644 index 000000000..e3ca8a5c5 --- /dev/null +++ b/private/tapi/dev/apps/tapitna/ver.10/tlocmgr.map @@ -0,0 +1,139 @@ + TLocMgr + + Timestamp is 3117ed0e (Tue Feb 06 16:06:38 1996) + + Preferred load address is 00400000 + + Start Length Name Class + 0001:00000000 0000003dH .rdata CODE + 0001:00000040 0000183eH .text CODE + 0001:00001880 00000034H .edata CODE + 0002:00000000 000002f4H .bss DATA + 0002:000002f4 00000235H .data DATA + 0003:00000000 00000078H .idata$2 DATA + 0003:00000078 00000028H .idata$3 DATA + 0003:000000a0 00000120H .idata$4 DATA + 0003:000001c0 00000120H .idata$5 DATA + 0003:000002e0 00000486H .idata$6 DATA + 0004:00000000 00000238H .rsrc$01 DATA + 0004:00000240 000010a8H .rsrc$02 DATA + + Address Publics by Value Rva+Base Lib:Object + + 0001:00000040 _MachineHasMultipleHWProfiles 00401040 f tapitna.obj + 0001:000000b0 _SaveNewLocation 004010b0 f tapitna.obj + 0001:00000130 _TapiCallbackProc@24 00401130 f tapitna.obj + 0001:00000240 _ChangeTapiLocation 00401240 f tapitna.obj + 0001:00000450 _SkipSpaces 00401450 f tapitna.obj + 0001:00000470 _WinMain@16 00401470 f tapitna.obj + 0001:00000950 _MainWndProc@16 00401950 f tapitna.obj + 0001:00001010 _GetTranslateCaps 00402010 f general.obj + 0001:000010e0 _FillConfigProfileBox 004020e0 f general.obj + 0001:000012f0 _GeneralDlgProc@16 004022f0 f general.obj + 0001:00001860 _lineSetCurrentLocation@8 00402860 f tapi32:TAPI32.dll + 0001:00001866 _lineInitialize@20 00402866 f tapi32:TAPI32.dll + 0001:0000186c _lineShutdown@4 0040286c f tapi32:TAPI32.dll + 0001:00001872 _lineTranslateDialog@20 00402872 f tapi32:TAPI32.dll + 0001:00001878 _lineGetTranslateCaps@12 00402878 f tapi32:TAPI32.dll + 0002:00000010 _gdwConfigProfiles 00403010 <common> + 0002:00000020 _buf 00403020 <common> + 0002:00000184 _i 00403184 <common> + 0002:00000190 _buf2 00403190 <common> + 0002:000002f4 _lpdwLocationIDs 004032f4 tapitna.obj + 0002:000002f8 _ghLineApp 004032f8 tapitna.obj + 0002:00000404 _gszCurrentProfileKey 00403404 general.obj + 0002:00000430 _gszStaticProfileKey 00403430 general.obj + 0002:00000468 _gszAutoLaunchKey 00403468 general.obj + 0002:0000049c _gszAutoLaunchValue 0040349c general.obj + 0002:000004ac _gszAutoLocationID 004034ac general.obj + 0002:000004bc _gnNumConfigProfiles 004034bc general.obj + 0003:00000000 __IMPORT_DESCRIPTOR_KERNEL32 00404000 kernel32:KERNEL32.dll + 0003:00000014 __IMPORT_DESCRIPTOR_USER32 00404014 user32:USER32.dll + 0003:00000028 ADVAPI32_IMPORT_DESCRIPTOR 00404028 advapi32:ADVAPI32.dll + 0003:0000003c __IMPORT_DESCRIPTOR_COMCTL32 0040403c comctl32:COMCTL32.dll + 0003:00000050 __IMPORT_DESCRIPTOR_TAPI32 00404050 tapi32:TAPI32.dll + 0003:00000064 __IMPORT_DESCRIPTOR_SHELL32 00404064 shell32:SHELL32.dll + 0003:00000078 __NULL_IMPORT_DESCRIPTOR 00404078 kernel32:KERNEL32.dll + 0003:0000008c NULL_IMPORT_DESCRIPTOR 0040408c advapi32:ADVAPI32.dll + 0003:000001c0 __imp__RegQueryValueExA@24 004041c0 advapi32:ADVAPI32.dll + 0003:000001c4 __imp__RegOpenKeyExA@20 004041c4 advapi32:ADVAPI32.dll + 0003:000001c8 __imp__RegCloseKey@4 004041c8 advapi32:ADVAPI32.dll + 0003:000001cc __imp__RegCreateKeyExA@36 004041cc advapi32:ADVAPI32.dll + 0003:000001d0 __imp__RegSetValueExA@24 004041d0 advapi32:ADVAPI32.dll + 0003:000001d4 \177ADVAPI32_NULL_THUNK_DATA 004041d4 advapi32:ADVAPI32.dll + 0003:000001d8 __imp__CreatePropertySheetPageA@4 004041d8 comctl32:COMCTL32.dll + 0003:000001dc __imp__PropertySheetA@4 004041dc comctl32:COMCTL32.dll + 0003:000001e0 \177COMCTL32_NULL_THUNK_DATA 004041e0 comctl32:COMCTL32.dll + 0003:000001e4 __imp__lstrcmpiA@8 004041e4 kernel32:KERNEL32.dll + 0003:000001e8 __imp__lstrcpyA@8 004041e8 kernel32:KERNEL32.dll + 0003:000001ec __imp__GetCommandLineA@0 004041ec kernel32:KERNEL32.dll + 0003:000001f0 __imp__lstrlenA@4 004041f0 kernel32:KERNEL32.dll + 0003:000001f4 __imp__LocalAlloc@8 004041f4 kernel32:KERNEL32.dll + 0003:000001f8 __imp__LockResource@4 004041f8 kernel32:KERNEL32.dll + 0003:000001fc __imp__LoadResource@8 004041fc kernel32:KERNEL32.dll + 0003:00000200 __imp__FindResourceA@12 00404200 kernel32:KERNEL32.dll + 0003:00000204 __imp__GlobalLock@4 00404204 kernel32:KERNEL32.dll + 0003:00000208 __imp__LocalFree@4 00404208 kernel32:KERNEL32.dll + 0003:0000020c __imp__GlobalAlloc@8 0040420c kernel32:KERNEL32.dll + 0003:00000210 __imp__GlobalFree@4 00404210 kernel32:KERNEL32.dll + 0003:00000214 __imp__GlobalHandle@4 00404214 kernel32:KERNEL32.dll + 0003:00000218 __imp__GlobalUnlock@4 00404218 kernel32:KERNEL32.dll + 0003:0000021c __imp__GetModuleHandleA@4 0040421c kernel32:KERNEL32.dll + 0003:00000220 __imp__Sleep@4 00404220 kernel32:KERNEL32.dll + 0003:00000224 __imp__RegisterServiceProcess@8 00404224 kernel32:KERNEL32.dll + 0003:00000228 \177KERNEL32_NULL_THUNK_DATA 00404228 kernel32:KERNEL32.dll + 0003:0000022c __imp__ShellExecuteA@24 0040422c shell32:SHELL32.dll + 0003:00000230 __imp__ShellAboutA@16 00404230 shell32:SHELL32.dll + 0003:00000234 __imp__Shell_NotifyIconA@8 00404234 shell32:SHELL32.dll + 0003:00000238 \177SHELL32_NULL_THUNK_DATA 00404238 shell32:SHELL32.dll + 0003:0000023c __imp__lineGetTranslateCaps@12 0040423c tapi32:TAPI32.dll + 0003:00000240 __imp__lineTranslateDialog@20 00404240 tapi32:TAPI32.dll + 0003:00000244 __imp__lineShutdown@4 00404244 tapi32:TAPI32.dll + 0003:00000248 __imp__lineInitialize@20 00404248 tapi32:TAPI32.dll + 0003:0000024c __imp__lineSetCurrentLocation@8 0040424c tapi32:TAPI32.dll + 0003:00000250 \177TAPI32_NULL_THUNK_DATA 00404250 tapi32:TAPI32.dll + 0003:00000254 __imp__TrackPopupMenuEx@24 00404254 user32:USER32.dll + 0003:00000258 __imp__SetMenuDefaultItem@12 00404258 user32:USER32.dll + 0003:0000025c __imp__GetSubMenu@8 0040425c user32:USER32.dll + 0003:00000260 __imp__RemoveMenu@12 00404260 user32:USER32.dll + 0003:00000264 __imp__CreatePopupMenu@0 00404264 user32:USER32.dll + 0003:00000268 __imp__LoadMenuA@8 00404268 user32:USER32.dll + 0003:0000026c __imp__DefWindowProcA@16 0040426c user32:USER32.dll + 0003:00000270 __imp__LoadImageA@24 00404270 user32:USER32.dll + 0003:00000274 __imp__PostQuitMessage@4 00404274 user32:USER32.dll + 0003:00000278 __imp__SendMessageA@16 00404278 user32:USER32.dll + 0003:0000027c __imp__GetDlgItem@8 0040427c user32:USER32.dll + 0003:00000280 __imp__GetKeyState@4 00404280 user32:USER32.dll + 0003:00000284 __imp__RegisterClassA@4 00404284 user32:USER32.dll + 0003:00000288 __imp__CheckDlgButton@12 00404288 user32:USER32.dll + 0003:0000028c __imp__WinHelpA@16 0040428c user32:USER32.dll + 0003:00000290 __imp__GetFocus@0 00404290 user32:USER32.dll + 0003:00000294 __imp__PostMessageA@16 00404294 user32:USER32.dll + 0003:00000298 __imp__DestroyWindow@4 00404298 user32:USER32.dll + 0003:0000029c __imp__GetMessageA@16 0040429c user32:USER32.dll + 0003:000002a0 __imp__TranslateMessage@4 004042a0 user32:USER32.dll + 0003:000002a4 __imp__DispatchMessageA@4 004042a4 user32:USER32.dll + 0003:000002a8 __imp__wsprintfA 004042a8 user32:USER32.dll + 0003:000002ac __imp__MessageBoxA@16 004042ac user32:USER32.dll + 0003:000002b0 __imp__LoadStringA@16 004042b0 user32:USER32.dll + 0003:000002b4 __imp__SetForegroundWindow@4 004042b4 user32:USER32.dll + 0003:000002b8 __imp__TrackPopupMenu@28 004042b8 user32:USER32.dll + 0003:000002bc __imp__DestroyMenu@4 004042bc user32:USER32.dll + 0003:000002c0 __imp__LoadIconA@8 004042c0 user32:USER32.dll + 0003:000002c4 __imp__CreateWindowExA@48 004042c4 user32:USER32.dll + 0003:000002c8 __imp__ShowWindow@8 004042c8 user32:USER32.dll + 0003:000002cc __imp__GetParent@4 004042cc user32:USER32.dll + 0003:000002d0 __imp__EnableWindow@8 004042d0 user32:USER32.dll + 0003:000002d4 __imp__GetCursorPos@4 004042d4 user32:USER32.dll + 0003:000002d8 __imp__AppendMenuA@16 004042d8 user32:USER32.dll + 0003:000002dc \177USER32_NULL_THUNK_DATA 004042dc user32:USER32.dll + + entry point at 0001:00000470 + + Static symbols + + 0001:000008a0 _InitApplication 004018a0 f tapitna.obj + 0001:000008f0 _InitInstance 004018f0 f tapitna.obj + +FIXUPS: 2041 68 3aa 2b ffffec43 b8 18 3f 50 d1 23 17c 10 46 4d 93 26 7a +FIXUPS: 1684 3d b8 55 4e 63 228 68 b7 45 35f 13 diff --git a/private/tapi/dev/apps/tapitna/ver.10/tlocmgr.sym b/private/tapi/dev/apps/tapitna/ver.10/tlocmgr.sym Binary files differnew file mode 100644 index 000000000..fa8419402 --- /dev/null +++ b/private/tapi/dev/apps/tapitna/ver.10/tlocmgr.sym diff --git a/private/tapi/dev/apps/tapiupr/dagger.inf b/private/tapi/dev/apps/tapiupr/dagger.inf new file mode 100644 index 000000000..8033b99ee --- /dev/null +++ b/private/tapi/dev/apps/tapiupr/dagger.inf @@ -0,0 +1,46 @@ +[version] +signature="$CHICAGO$" + +[DefaultInstall] +CopyFiles = Tapi32.DLL TapiSrv.EXE Telephon.CPL +AddReg = Dagger.Add.Reg + +[DaggerInstall] +CopyFiles = Tapi32.DLL TapiSrv.EXE Telephon.CPL +AddReg = Dagger.Add.Reg + +[DefaultUninstall] +CopyFiles = Tapi32.DLL TapiSrv.EXE Telephon.CPL +DelReg = Dagger.Del.Reg + +[DestinationDirs] +Dagger.Files.Sys = 11 +Dagger.Files.Inf = 17 + +[SourceDisksNames] +1="Dagger","",1 + +[SourceDisksFiles] +Dagger.EXE=1 +Dagger.INF=1 + +[Dagger.Files.Sys] +Tapi32.DLL TapiSrv.EXE Telephon.CPL + +[Dagger.Files.Inf] +Dagger.INF + +[Strings] +Dagger_DESC = "Telephony Setup INF" + +[Dagger.Add.Reg] +HKLM,Software\Microsoft\Windows\CurrentVersion\RunOnce\Setup,%Dagger_DESC%,,"start %11%\tapiupr.EXE" +HKLM,Software\Microsoft\Windows\CurrentVersion\Telephony,AutoLaunchFlags,3,0x1f + +[Dagger.Del.Reg] +HKLM,Software\Microsoft\Windows\CurrentVersion\Telephony,AutoLaunchFlags +HKLM,Config\0001\System\CurrentControlSet\Control\Telephony,AutoLocationID +HKLM,Config\0002\System\CurrentControlSet\Control\Telephony,AutoLocationID +HKLM,Config\0003\System\CurrentControlSet\Control\Telephony,AutoLocationID +HKLM,Config\0004\System\CurrentControlSet\Control\Telephony,AutoLocationID + diff --git a/private/tapi/dev/apps/tapiupr/depend.mk b/private/tapi/dev/apps/tapiupr/depend.mk new file mode 100644 index 000000000..e2eadeb78 --- /dev/null +++ b/private/tapi/dev/apps/tapiupr/depend.mk @@ -0,0 +1,3 @@ +.\tapiupr.obj: ..\tapiupr.c + +.\tapiupr.res: ..\tapiupr.rc diff --git a/private/tapi/dev/apps/tapiupr/makefile b/private/tapi/dev/apps/tapiupr/makefile new file mode 100644 index 000000000..6b4c11cae --- /dev/null +++ b/private/tapi/dev/apps/tapiupr/makefile @@ -0,0 +1,26 @@ + +!if "$(OS)" == "Windows_NT" + +!INCLUDE $(NTMAKEENV)\makefile.def + +!else + + + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\.. + +VERSIONLIST=debug retail + +DEPENDNAME=depend.mk + +COMMONMKFILE=makefile.def + +IS_OEM=TRUE +IS_32 = TRUE + +!include $(ROOT)\dev\master.mk + +!endif + diff --git a/private/tapi/dev/apps/tapiupr/makefile.def b/private/tapi/dev/apps/tapiupr/makefile.def new file mode 100644 index 000000000..1501e7342 --- /dev/null +++ b/private/tapi/dev/apps/tapiupr/makefile.def @@ -0,0 +1,54 @@ +############################################################################## +# +# TapiUpr Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\..\.. + + +IS_OEM=TRUE +WANT_C932=1 +IS_32 = TRUE +WIN32=1 + +DEPENDNAME=..\depend.mk + +DRVNAME=TapiUpr +TARGETS=TapiUpr.exe TapiUpr.sym + +SRCDIR=.. + +DEFENTRY=main + +#CONSOLE=1 + +L32EXE=TapiUpr.exe # Name of exe. +#L32DEF=..\TapiUpr.def # Our def file. +L32MAP=TapiUpr.map # Our map file. +L32LIBS= \ + $(W32LIBID)\kernel32.lib \ + $(W32LIBID)\user32.lib \ + $(W32LIBID)\advapi32.lib \ + $(DEVROOT)\tools\c932\lib\msvcrt.lib + +L32RES=TapiUpr.res # Resource file. + +L32OBJS = TapiUpr.obj + + +L32FLAGS=$(L32FLAGS) /MAP + +!include $(ROOT)\dev\master.mk + + +INCLUDE=$(INCLUDE);..\..\..\client + +#CFLAGS=$(CFLAGS) -DWIN32=100 -DWIN_32=100 -Od -Fc +CFLAGS=$(CFLAGS) -DWIN32=100 -DWIN_32=100 -Ox + +!IF "$(VERDIR)" == "debug" +CFLAGS = $(CFLAGS) -DDBG=1 +!endif diff --git a/private/tapi/dev/apps/tapiupr/sources b/private/tapi/dev/apps/tapiupr/sources new file mode 100644 index 000000000..77b4a9cf5 --- /dev/null +++ b/private/tapi/dev/apps/tapiupr/sources @@ -0,0 +1,28 @@ +MAJORCOMP=net +MINORCOMP=tapi + +TARGETNAME=tapiupr +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=PROGRAM +TARGETLIBS= \ + $(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\advapi32.lib \ + $(BASEDIR)\public\sdk\lib\*\user32.lib + + +INCLUDES=..\inc;$(BASEDIR)\public\sdk\inc + +C_DEFINES=-DWINVER=0x0400 + +USE_CRTDLL=1 + +SOURCES=tapiupr.c \ + tapiupr.rc + + +UMTYPE=windows + + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF diff --git a/private/tapi/dev/apps/tapiupr/tapi.inx b/private/tapi/dev/apps/tapiupr/tapi.inx new file mode 100644 index 000000000..c16a28075 --- /dev/null +++ b/private/tapi/dev/apps/tapiupr/tapi.inx @@ -0,0 +1,110 @@ +; TAPI.INF +; +; Copyright 1993,1994,1995 Microsoft Corporation + +[version] +;LayoutFile=layout.inf +signature="$CHICAGO$" +;SetupClass=BASE + + + +[DefaultInstall] +CopyFiles=tapibase.files, MS_TAPI_SYS_CopyFiles, MS_TAPI_HelpFiles +DelFiles=tapibase.del.files +AddReg = add.reg +UpdateInis=UpdateTelephonIni +[SourceDisksNames] +1="Tapi","",1 +[SourceDisksFiles] +tapi.dll=1 +tapi32.dll=1 +tapisrv.exe=1 +tapiupr.exe=1 +telephon.cp$=1 +telephon.cpl=1 +tlocmgr.exe=1 +tsp3216l.tsp=1 +tsp3216s.dll=1 + + + + +[DestinationDirs] +MS_TAPI_HelpFiles = 18 ; LDID_HELP +MS_TAPI_SYS_CopyFiles = 11 ; LDID_SYS +MS_TAPI_CopyFiles = 10 ; LDID_WIN +tapibase.files = 17 ; LDID_INF +tapibase.del.files = 25 ; LDID_SHARED + +[BaseWinOptions] +tapibase +tapi + +[tapibase] +CopyFiles=tapibase.files +DelFiles=tapibase.del.files + +[tapi] +OptionDesc=%MS_TAPI_Desc% +CopyFiles=MS_TAPI_SYS_CopyFiles, MS_TAPI_HelpFiles +AddReg = add.reg + +[MS_TAPI_CopyFiles] +tlocmgr.exe + +[MS_TAPI_SYS_CopyFiles] +tapi.dll +tapi32.dll +tapisrv.exe +tapiupr.exe +tsp3216l.tsp +tsp3216s.dll +telephon.cp$, telephon.cpl + +tsp3216s.sym +tsp3216l.sym +tapi.sym +tapi32.sym +tapisrv.sym + + +[MS_TAPI_HelpFiles] +telephon.hlp + +[tapibase.files] +tapi.inf + +[tapibase.del.files] +tapi.dll +tapi32.dll +tapisrv.exe +tapiupr.exe +telephon.cpl +tsp3216l.tsp +tsp3216s.dll +tlocmgr.exe +telephon.cpl +telephon.cp$ +telephon.hlp + +[add.reg] +HKLM,Software\Microsoft\Windows\CurrentVersion\RunOnce,TapiSetup,,"tapiupr.exe" +HKLM,Software\Microsoft\Windows\CurrentVersion\Telephony,,, +HKLM,Software\Microsoft\Windows\CurrentVersion\Telephony\Locations,"NextID",1,01,00,00,00 +HKLM,"Software\Microsoft\Windows\CurrentVersion\Telephony\Providers","NumProviders",1,01,00,00,00 +HKLM,"Software\Microsoft\Windows\CurrentVersion\Telephony\Providers","NextID",1,02,00,00,00 +HKLM,"Software\Microsoft\Windows\CurrentVersion\Telephony\Providers","ProviderID0",1,01,00,00,00 +HKLM,"Software\Microsoft\Windows\CurrentVersion\Telephony\Providers","ProviderFilename0",0,"TSP3216l.TSP" +HKLM,"Software\Microsoft\Windows\CurrentVersion\Telephony\Providers\Provider1","comm/datamodem",1,00,00,00,00 + +HKLM,Software\Microsoft\Windows\CurrentVersion\Telephony,Tapi32DebugLevel,1,02,00,00,00 +HKLM,Software\Microsoft\Windows\CurrentVersion\Telephony,TapiSrvDebugLevel,1,02,00,00,00 +HKLM,Software\Microsoft\Windows\CurrentVersion\Telephony,TelephonDebugLevel,1,02,00,00,00 +HKLM,Software\Microsoft\Windows\CurrentVersion\Telephony\Providers\Provider1,DebugLevel,1,02,00,00,00 + +[UpdateTelephonIni] +%10%\TELEPHON.INI,Debug,,"TSP3216SDebugLevel=99" + +[Strings] +MS_TAPI_Desc = "Telephony Support" diff --git a/private/tapi/dev/apps/tapiupr/tapiupr.c b/private/tapi/dev/apps/tapiupr/tapiupr.c new file mode 100644 index 000000000..560ab94b8 --- /dev/null +++ b/private/tapi/dev/apps/tapiupr/tapiupr.c @@ -0,0 +1,1021 @@ +#define STRICT + +#include <windows.h> +#include <windowsx.h> + +#include "..\..\client\location.h" + + + +#if DBG + +#define DBGOUT(arg) DbgPrt arg + +void +DbgPrt( + DWORD dwDbgLevel, + PSTR DbgMessage, + ... + ); + +#else + +#define DBGOUT(_x_) +#endif + + + + +const TCHAR gszName[] = "Name"; +const TCHAR gszID[] = "ID"; +const TCHAR gszAreaCode[] = "AreaCode"; +const TCHAR gszCountry[] = "Country"; +const TCHAR gszOutsideAccess[] = "OutsideAccess"; +const TCHAR gszLongDistanceAccess[] = "LongDistanceAccess"; +const TCHAR gszFlags[] = "Flags"; +const TCHAR gszCallingCard[] = "CallingCard"; +const TCHAR gszDisableCallWaiting[] = "DisableCallWaiting"; +const TCHAR gszTollList[] = "TollList"; +//const TCHAR gszNumLocations[] = "NumLocations"; +//const TCHAR gszCurrLocation[] = "CurrLocation"; +//const TCHAR gszNextLocationID[] = "NextLocationID"; + +const TCHAR gszCard[] = "Card"; +const TCHAR gszPin[] = "Pin"; +const TCHAR gszCards[] = "Cards"; +//const TCHAR gszNumCards[] = "NumCards"; +//const TCHAR gszCurrCard[] = "CurrCard"; +const TCHAR gszLocalRule[] = "LocalRule"; +const TCHAR gszLDRule[] = "LDRule"; +const TCHAR gszInternationalRule[] = "InternationalRule"; + +const TCHAR gszNumEntries[] = "NumEntries"; +const TCHAR gszCurrentID[] = "CurrentID"; +const TCHAR gszNextID[] = "NextID"; + + +const TCHAR gszEmpty[] = ""; + +const TCHAR gszLocations[] = "Locations"; +const TCHAR gszLocation[] = "Location"; +const TCHAR gszCurrentLocation[] = "CurrentLocation"; + + +const TCHAR gszHandoffPriorities[] = "HandoffPriorities"; + +const TCHAR gszProviders[] = "Providers"; +const TCHAR gszProvider[] = "Provider%d"; + +const TCHAR gszTelephonIni[] = "Telephon.ini"; + + +const TCHAR gszTelephony[] = "Software\\Microsoft\\Windows\\" + "CurrentVersion\\Telephony"; + + +void FixPriorityList(HKEY hKeyHandoffPriorities, + LPWSTR pszListName); + +#pragma check_stack ( off ) + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +BOOL ParseSomething( LPCSTR pFormat, LPCSTR pInputString, LPVOID pOutputPtr ) +{ + BYTE c; + LPBYTE pOutput = (LPBYTE)pOutputPtr; + LPBYTE pInput = (LPBYTE)pInputString; + + + while ( (c = *pFormat) && *pInput ) + { +#if DBG +DBGOUT((11, "Inputstring[%s]\r\n Format[%s]\r\n", + pInput, pFormat)); +#endif + + switch ( c ) + { + case 'n': + { + DWORD dwValue = 0; + BYTE bDigit; + + // + // Parse value from the string + // + while ( ((bDigit = *pInput) != '\0') && bDigit != ',' ) + { + dwValue = (dwValue * 10) + ( bDigit - '0' ); +#if DBG +DBGOUT((11, "val of bDigit=%d dwValue=%ld\r\n", (int)bDigit, dwValue)); +#endif + + bDigit = *(++pInput); + } + + *(LPDWORD)pOutput = dwValue; + + pOutput += sizeof(DWORD); + + } + break; + + + case 's': + { + // + // If the caller is looking for a string, the first char + // MUST be a quotes. So, just step past it. + // + pInput++; + + // + // Ok, _now_ we're into the meat of the string (if there _is_ + // any...) + // + + while ( *pInput != '\0' && *pInput != '"' ) + { + *pOutput = *pInput; + pOutput++; + pInput++; + } + + // + // Don't forget to put a cap on that thing. + // + *pOutput = '\0'; + pOutput++; + + // The input should now be at a ->"<- if it's not, the ini + // file was hosed, and I'm not fixing it. + // So, we step past it, and we're done + // + if ( *pInput == '"' ) + { + pInput++; + } + + } + break; + + + } + + // + // Step past the comma... + // + // + if ( *pInput == ',' ) + { + pInput++; + } + + pFormat++; + } + + return TRUE; +} + + + +//*************************************************************************** +//*************************************************************************** +//*************************************************************************** +//VOID __cdecl main( void ) +void main( void ) +{ + + DWORD dw; + DWORD dwNumEntries; + DWORD dwCurrentID; + DWORD dwNextID; + + DWORD dwArray[10]; + BYTE bBigArray[5120]; + BYTE Buffer[5120]; //Might need tons of room for the tolllist... + LPBYTE pSource; + + HKEY hKey3; + HKEY hKey2; + HKEY hKey; + DWORD dwDisposition; + + + dw = GetPrivateProfileString( + gszCards, + gszCards, + gszEmpty, + Buffer, + sizeof(Buffer), + gszTelephonIni + ); + + + // + // Is there an existing AND valid TELEPHON.INI file? + // There would HAVE TO be at least one card. The SYSTEM cards cannot + // be deleted, only hidden. + // + if ( 0 != dw ) + { + + + +//[Cards] +//Cards=23,23 +//Card0=0,"None (Direct Dial)","","","","",1 +//Card1=1,"AT&T Direct Dial via 10ATT1","","G","102881FG","10288011EFG",1 +#define CARD_INI_ID (0) +#define CARD_INI_NAME (1) +#define CARD_INI_SNUMBER (2) +#define CARD_INI_SARULE (3) +#define CARD_INI_LDRULE (4) +#define CARD_INI_INTNLRULE (5) +#define CARD_INI_HIDDEN (6) + + +#define PC_INI_ID (0) +#define PC_INI_NEXTID (1) +#define PC_INI_NAME (2) +#define PC_INI_SARULE (3) +#define PC_INI_LDRULE (4) +#define PC_INI_INTNLRULE (5) + + + // + // Move CARDS entries to registry + // + + ParseSomething( "nn", Buffer, &dwArray); + + dwNumEntries = dwArray[0]; + dwNextID = dwArray[1]; + + + RegCreateKeyEx( + HKEY_CURRENT_USER, +//BUGBUG or should this be default user or not at all or what? + gszTelephony, + 0, + "", //Class? What class? + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + 0, + &hKey3, + &dwDisposition + ); + + RegCreateKeyEx( + hKey3, + gszCards, + 0, + "", //Class? What class? + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + 0, + &hKey2, + &dwDisposition + ); + + RegSetValueEx( + hKey2, + gszNumEntries, + 0, + REG_DWORD, + (LPBYTE)&dwNumEntries, + sizeof(DWORD) + ); + + RegSetValueEx( + hKey2, + gszNextID, + 0, + REG_DWORD, + (LPBYTE)&dwNextID, + sizeof(DWORD) + ); + + + + for ( dw=0; dw<dwNumEntries; dw++ ) + { + TCHAR Temp[18]; + + wsprintf(Temp, "%s%d", gszCard, dw); + + // + // Create the key for this Card + // + RegCreateKeyEx( + hKey2, + Temp, + 0, + "", //Class? What class? + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + 0, + &hKey, + &dwDisposition + ); + + + GetPrivateProfileString( + gszCards, + Temp, + gszEmpty, + Buffer, + sizeof(Buffer), + gszTelephonIni + ); + + ParseSomething("nsssssn", Buffer, bBigArray); + + + pSource = bBigArray; + + RegSetValueEx( + hKey, + gszID, + 0, + REG_DWORD, + pSource, + sizeof(DWORD) + ); + pSource += sizeof(DWORD); + + RegSetValueEx( + hKey, + gszName, + 0, + REG_SZ, + pSource, + lstrlen(pSource)+1 + ); + pSource += lstrlen(pSource)+1; + + RegSetValueEx( + hKey, + gszPin, + 0, + REG_SZ, + pSource, + lstrlen(pSource)+1 + ); + pSource += lstrlen(pSource)+1; + + RegSetValueEx( + hKey, + gszLocalRule, + 0, + REG_SZ, + pSource, + lstrlen(pSource)+1 + ); + pSource += lstrlen(pSource)+1; + + RegSetValueEx( + hKey, + gszLDRule, + 0, + REG_SZ, + pSource, + lstrlen(pSource)+1 + ); + pSource += lstrlen(pSource)+1; + + RegSetValueEx( + hKey, + gszInternationalRule, + 0, + REG_SZ, + pSource, + lstrlen(pSource)+1 + ); + pSource += lstrlen(pSource)+1; + + RegSetValueEx( + hKey, + gszFlags, + 0, + REG_DWORD, + pSource, + sizeof(DWORD) + ); + pSource += sizeof(DWORD); + + + RegCloseKey( hKey ); + } + + + RegCloseKey( hKey2 ); + RegCloseKey( hKey3 ); + + +//--------------------------------------------------------------------------- + + GetPrivateProfileString( + gszLocations, + gszCurrentLocation, + gszEmpty, + Buffer, + sizeof(Buffer), + gszTelephonIni + ); + + ParseSomething( "nn", Buffer, &dwArray); + + dwCurrentID = dwArray[0]; +//BUGBUG: What's the other one for? + + + GetPrivateProfileString( + gszLocations, + gszLocations, + gszEmpty, + Buffer, + sizeof(Buffer), + gszTelephonIni + ); + + ParseSomething( "nn", Buffer, &dwArray); + + dwNumEntries = dwArray[0]; + dwNextID = dwArray[1]; + + + RegCreateKeyEx( + HKEY_LOCAL_MACHINE, + gszTelephony, + 0, + "", //Class? What class? + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + 0, + &hKey3, + &dwDisposition + ); + + + RegCreateKeyEx( + hKey3, + gszLocations, + 0, + "", //Class? What class? + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + 0, + &hKey2, + &dwDisposition + ); + + + RegSetValueEx( + hKey2, + gszCurrentID, + 0, + REG_DWORD, + (LPBYTE)&dwCurrentID, + sizeof(DWORD) + ); + + RegSetValueEx( + hKey2, + gszNumEntries, + 0, + REG_DWORD, + (LPBYTE)&dwNumEntries, + sizeof(DWORD) + ); + + RegSetValueEx( + hKey2, + gszNextID, + 0, + REG_DWORD, + (LPBYTE)&dwNextID, + sizeof(DWORD) + ); + + + + for ( dw=0; dw<dwNumEntries; dw++ ) + { + TCHAR Temp[18]; + DWORD dwFlags = 0; + + wsprintf(Temp, "%s%d", gszLocation, dw); + + // + // Create the key for this Location + // + RegCreateKeyEx( + hKey2, + Temp, + 0, + "", //Class? What class? + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + 0, + &hKey, + &dwDisposition + ); + + + + GetPrivateProfileString( + gszLocations, + Temp, + gszEmpty, + Buffer, + sizeof(Buffer), + gszTelephonIni + ); + + ParseSomething("nssssnnnnsns", Buffer, bBigArray); +//BUGBUG if this is upgrade over 3.1, the last 2 fields don't exist + + + +//[Locations] +//CurrentLocation=1,2 +//Locations=3,4 +//Location0=0,"Work","9","9","206",1,0,0,1,"",0,"" +//Location1=3,"RoadHouse","","","215",1,0,0,0,"",0,"" +//Location2=1,"Home","","","206",1,0,0,0,"",0," " +// Positions in ini file entries for locations,cards,countries +// NOTE: dialing rules are in same positions for locations and cards! + +//#define LOC_INI_ID (0) +//#define LOC_INI_NAME (1) +//#define LOC_INI_LPREFIX (2) +//#define LOC_INI_LDPREFIX (3) +//#define LOC_INI_AREACODE (4) +//#define LOC_INI_COUNTRYCODE (5) +//#define LOC_INI_CARDID (6) +//#define LOC_INI_CARDHINT (7) +//#define LOC_INI_INSERTAC (8) +//#define LOC_INI_TOLLLIST (9) +// +//#define LOC_INI_PULSE (10) +//#define LOC_INI_CALLWAITING (11) + + + pSource = bBigArray; + + RegSetValueEx( + hKey, + gszID, + 0, + REG_DWORD, + pSource, + sizeof(DWORD) + ); + pSource += sizeof(DWORD); + + RegSetValueEx( + hKey, + gszName, + 0, + REG_SZ, + pSource, + lstrlen(pSource)+1 + ); + pSource += lstrlen(pSource)+1; + + RegSetValueEx( + hKey, + gszOutsideAccess, + 0, + REG_SZ, + pSource, + lstrlen(pSource)+1 + ); + pSource += lstrlen(pSource)+1; + + RegSetValueEx( + hKey, + gszLongDistanceAccess, + 0, + REG_SZ, + pSource, + lstrlen(pSource)+1 + ); + pSource += lstrlen(pSource)+1; + + RegSetValueEx( + hKey, + gszAreaCode, + 0, + REG_SZ, + pSource, + lstrlen(pSource)+1 + ); + pSource += lstrlen(pSource)+1; + + RegSetValueEx( + hKey, + gszCountry, + 0, + REG_DWORD, + pSource, + sizeof(DWORD) + ); + pSource += sizeof(DWORD); + + + // + // If the callingcard == 0, it means this location does not + // use a calling card. + // + if ( *(LPDWORD)pSource != 0 ) + { + dwFlags |= LOCATION_USECALLINGCARD; + } + + RegSetValueEx( + hKey, + gszCallingCard, + 0, + REG_DWORD, + pSource, + sizeof(DWORD) + ); + pSource += sizeof(DWORD); + + +//BUGBUG What the hell is a CardHint? Or Insert AC, for that matter? + pSource += sizeof(DWORD); + pSource += sizeof(DWORD); + + + RegSetValueEx( + hKey, + gszTollList, + 0, + REG_SZ, + pSource, + lstrlen(pSource)+1 + ); + pSource += lstrlen(pSource)+1; + + // + // pSource is currently pointing to the old dwFlags. However, + // the only flag that was used was bit 1 which indicated + // tone dialing. As luck (yeah, right) would have it, we + // use bit 1 to indicate tone dialing as well. + // + dwFlags |= !((*(LPDWORD)pSource) & 1); + + pSource += sizeof(DWORD); + + // + // Is there a disablecallwaiting string + // + dwFlags |= ( lstrlen( pSource ) == 0 ) ? + 0 : + LOCATION_HASCALLWAITING; + + RegSetValueEx( + hKey, + gszDisableCallWaiting, + 0, + REG_SZ, + pSource, + lstrlen(pSource)+1 + ); + pSource += lstrlen(pSource)+1; + + + RegSetValueEx( + hKey, + gszFlags, + 0, + REG_DWORD, + (LPBYTE)&dwFlags, + sizeof(DWORD) + ); + pSource += sizeof(DWORD); + + + RegCloseKey( hKey ); + } + +//--------------------------------------------------------------------------- + + + // + // If we're on Win95, copy the PROVIDERS entries to the + // registry for TSP3216L.TSP + // + { + } + + +//--------------------------------------------------------------------------- + + // + // Q: How do we update COUNTRY OVERRIDES? + // A: We don't. We assume we've corrected everything by now... + // + + +// RegCloseKey( hKey ); + RegCloseKey( hKey2 ); + RegCloseKey( hKey3 ); + + } + + + { + int i; + HKEY hKeyHandoffPriorities; + WCHAR *gaszMediaModes[] = + { + L"", + L"unknown", + L"interactivevoice", + L"automatedvoice", + L"datamodem", + L"g3fax", + L"tdd", + L"g4fax", + L"digitaldata", + L"teletex", + L"videotex", + L"telex", + L"mixed", + L"adsi", + L"voiceview", + NULL + }; + + WCHAR *gszRequestMakeCallW = L"RequestMakeCall"; + WCHAR *gszRequestMediaCallW = L"RequestMediaCall"; + WCHAR *gszRegKeyHandoffPriorities = L"Software\\Microsoft\\Windows\\CurrentVersion\\Telephony\\HandoffPriorities"; + + if (RegOpenKeyExW( + HKEY_CURRENT_USER, + gszRegKeyHandoffPriorities, + 0, + KEY_ALL_ACCESS, + &hKeyHandoffPriorities + + ) == ERROR_SUCCESS) + { + + + for (i = 1; gaszMediaModes[i] != NULL; i++) + { + FixPriorityList( + hKeyHandoffPriorities, + gaszMediaModes[i] + ); + } + + FixPriorityList( + hKeyHandoffPriorities, + gszRequestMakeCallW + ); + + FixPriorityList( + hKeyHandoffPriorities, + gszRequestMediaCallW + ); + + + RegCloseKey (hKeyHandoffPriorities); + + } + } + + + + { + //---------------------------------------------------------------------- + //---------------------------------------------------------------------- + //---------------------------------------------------------------------- + // + // Now we discuss someone who is upgrading from beta 2 to RTM. They have + // "EVERYONE:FULL CONTROL" access on the LOCATIONS key. Let's change that + // to have the same security as the TELEPHONY key. + // + + SECURITY_INFORMATION SecInf; + PSECURITY_DESCRIPTOR pSecDesc; + DWORD cbSecDesc = 65535; + + + pSecDesc = LocalAlloc( LPTR, cbSecDesc ); + if ( pSecDesc ) + { + + + + RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + gszTelephony, + 0, + KEY_ALL_ACCESS, + &hKey + ); + + RegCreateKeyEx( + hKey, + gszLocations, + 0, + "", //Class? What class? + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + 0, + &hKey2, + &dwDisposition + ); + + cbSecDesc = 65535; + dw = RegGetKeySecurity( hKey, + OWNER_SECURITY_INFORMATION, + pSecDesc, + &cbSecDesc + ); + + if ( ERROR_SUCCESS == dw ) + RegSetKeySecurity( hKey2, + OWNER_SECURITY_INFORMATION, + pSecDesc + ); + + cbSecDesc = 65535; + dw = RegGetKeySecurity( hKey, + GROUP_SECURITY_INFORMATION, + pSecDesc, + &cbSecDesc + ); + + if ( ERROR_SUCCESS == dw ) + RegSetKeySecurity( hKey2, + GROUP_SECURITY_INFORMATION, + pSecDesc + ); + + cbSecDesc = 65535; + dw = RegGetKeySecurity( hKey, + DACL_SECURITY_INFORMATION, + pSecDesc, + &cbSecDesc + ); + + if ( ERROR_SUCCESS == dw ) + RegSetKeySecurity( hKey2, + DACL_SECURITY_INFORMATION, + pSecDesc + ); + + cbSecDesc = 65535; + dw = RegGetKeySecurity( hKey, + SACL_SECURITY_INFORMATION, + pSecDesc, + &cbSecDesc + ); + + if ( ERROR_SUCCESS == dw ) + RegSetKeySecurity( hKey2, + SACL_SECURITY_INFORMATION, + pSecDesc + ); + + + RegCloseKey( hKey ); + RegCloseKey( hKey2); + + + LocalFree( pSecDesc ); + } + } + + + return; +} + +void FixPriorityList(HKEY hKeyHandoffPriorities, + LPWSTR pszListName) +{ + DWORD dwType, dwNumBytes; + LPWSTR pszPriorityList, pszHold; + + if (RegQueryValueExW( + hKeyHandoffPriorities, + pszListName, + NULL, + &dwType, + NULL, + &dwNumBytes + ) == ERROR_SUCCESS && + + (dwNumBytes != 0)) + { + pszPriorityList = (LPWSTR) GlobalAlloc ( GPTR, dwNumBytes ); + + if (pszPriorityList) + { + pszHold = pszPriorityList; + + if ( RegQueryValueExW( + hKeyHandoffPriorities, + pszListName, + NULL, + &dwType, + (LPBYTE)(pszPriorityList), + &dwNumBytes + + ) == ERROR_SUCCESS) + { + while (*pszPriorityList != L'\0') + { + if (*pszPriorityList == L',') + { + *pszPriorityList = L'"'; + } + + pszPriorityList++; + } + + pszPriorityList = pszHold; + + RegSetValueExW( + hKeyHandoffPriorities, + pszListName, + 0, + REG_SZ, + (LPBYTE)pszPriorityList, + (lstrlenW(pszPriorityList) + 1) * sizeof(WCHAR)); + } + + GlobalFree(pszPriorityList); + } + } + +} + + + +#if DBG + + +#include "stdarg.h" +#include "stdio.h" + + +VOID +DbgPrt( + DWORD dwDbgLevel, + PSTR lpszFormat, + ... + ) +/*++ + +Routine Description: + + Formats the incoming debug message & calls DbgPrint + +Arguments: + + DbgLevel - level of message verboseness + + DbgMessage - printf-style format string, followed by appropriate + list of arguments + +Return Value: + + +--*/ +{ + static DWORD gdwDebugLevel = 0; //HACKHACK + + + if (dwDbgLevel <= gdwDebugLevel) + { + char buf[256] = "TAPIUPR: "; + va_list ap; + + + va_start(ap, lpszFormat); + + wvsprintf (&buf[8], + lpszFormat, + ap + ); + + lstrcat (buf, "\n"); + + OutputDebugStringA (buf); + + va_end(ap); + } +} +#endif + + diff --git a/private/tapi/dev/apps/tapiupr/tapiupr.rc b/private/tapi/dev/apps/tapiupr/tapiupr.rc new file mode 100644 index 000000000..a33ebcc04 --- /dev/null +++ b/private/tapi/dev/apps/tapiupr/tapiupr.rc @@ -0,0 +1,23 @@ +#include "windows.h" + + +#if WINNT +#include <ntverp.h> +#else +#include <version.h> +#endif + +#define VER_FILEDESCRIPTION_STR "Microsoft\256 Windows(TM) Telephony INI-file Upgrade Utility" +#define VER_INTERNALNAME_STR "TapiUpr" +#define VER_ORIGINALFILENAME_STR "TAPIUPR.EXE" +//#define VER_LEGALCOPYRIGHT_STR "Copyright \251 Microsoft Corporation 1995. All Rights Reserved." +#define VER_LEGALCOPYRIGHT_YEARS "1996" + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT2_UNKNOWN + +#include <common.ver> + +// ///////////////////////////////////////////////////////////////////////// +// ///////////////////////////////////////////////////////////////////////// + diff --git a/private/tapi/dev/apps/tb/depend.mk b/private/tapi/dev/apps/tb/depend.mk new file mode 100644 index 000000000..e2d724f43 --- /dev/null +++ b/private/tapi/dev/apps/tb/depend.mk @@ -0,0 +1,11 @@ +ui.obj: ui.c vars.h tb.h + +tb.obj: tb.c vars.h tb.h resource.h + +vars.obj: vars.c tb.h + +widget.obj: widget.c vars.h tb.h + +tb.res: tb.rc resource.h + + diff --git a/private/tapi/dev/apps/tb/makefile b/private/tapi/dev/apps/tb/makefile new file mode 100644 index 000000000..23524cb99 --- /dev/null +++ b/private/tapi/dev/apps/tb/makefile @@ -0,0 +1,11 @@ +!ifndef NTMAKEENV +NTMAKEENV=. +!endif + + +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/tapi/dev/apps/tb/makefile.def b/private/tapi/dev/apps/tb/makefile.def new file mode 100644 index 000000000..521b15dad --- /dev/null +++ b/private/tapi/dev/apps/tb/makefile.def @@ -0,0 +1,72 @@ +############################################################################## +# +# Dialer Make file +# +############################################################################## + +#Ok, we're doing a Win9x build. + +ROOT=..\..\..\..\.. + +#VERSIONLIST=debug retail + +#!ifdef RETAIL +#DEFAULTVERDIR=retail +#!else +#DEFAULTVERDIR=debug +#!endif + + +IS_OEM=1 +WANT_C932=1 +IS_32 = TRUE +WIN32=1 + +#DEFENTRY=main + +#CLEANLIST = *.drv + +DEPENDNAME=..\depend.mk + +DRVNAME=tb14 +TARGETS=tb14.exe + +#VERDIR = debug + +SRCDIR=.. +OBJDIR=obj\i386 + +#INCFILE = ..\dagger.mk + +BUILD_COFF=1 + + +L32EXE=tb14.exe # Name of exe. +L32DEF=tb.def # Our def file. +L32MAP=tb14.map # Our map file. +L32SYM=tb14.sym # Our sym file. +L32LIBS= \ + $(W32LIBID)\kernel32.lib \ + $(W32LIBID)\comdlg32.lib \ + $(W32LIBID)\user32.lib \ + $(W32LIBID)\gdi32.lib \ + $(DEVROOT)\tools\c932\lib\oldnames.lib \ + $(DEVROOT)\tools\c932\lib\crtdll.lib \ + $(DEVROOT)\sdk\lib\tapi32.lib + +# $(DEVROOT)\sdk\lib\shell32.lib + +L32RES=tb.res # Resource file. + +RCFLAGS=-DWIN32=100 + +#----------------------------------------------------------------------- +# Object files +#----------------------------------------------------------------------- +L32OBJS = tb.obj ui.obj vars.obj widget.obj + + +!include $(ROOT)\dev\master.mk + +#CFLAGS=$(CFLAGS) -DWIN32=100 -DWIN_32=100 -DDBG=1 +CFLAGS=$(CFLAGS) -DWIN32=100 -DWIN_32=100 diff --git a/private/tapi/dev/apps/tb/nt.mak b/private/tapi/dev/apps/tb/nt.mak new file mode 100644 index 000000000..a93df1f2d --- /dev/null +++ b/private/tapi/dev/apps/tb/nt.mak @@ -0,0 +1,27 @@ +!include <ntwin32.mak> + +!ifndef MYDEBUG +MYDEBUG = 0 +!endif + +!if $(MYDEBUG) +L_FLAGS = $(linkdebug) +!else +L_FLAGS = +!endif + +APPLIBS=\telephon\tapi\lib\tapi32.lib + +OBJS=ui.obj vars.obj tb.obj widget.obj + +all: tb.exe + +.c.obj: + $(cc) -DTAPI_1_1 $(cdebug) $(cflags) $(cvars) $*.c + +tb.rbj: tb.rc + $(rc) -DTAPI_1_1 $(rcvars) -r -fo tb.res tb.rc + cvtres -$(CPU) tb.res -o tb.rbj + +tb.exe: $(OBJS) tb.rbj tb.def + $(link) $(L_FLAGS) $(guiflags) -out:tb14.exe $(OBJS) tb.rbj $(APPLIBS) $(guilibsdll) diff --git a/private/tapi/dev/apps/tb/resource.h b/private/tapi/dev/apps/tb/resource.h new file mode 100644 index 000000000..90a7e3a9f --- /dev/null +++ b/private/tapi/dev/apps/tb/resource.h @@ -0,0 +1,98 @@ +/*++ BUILD Version: 0000 // Increment this if a change has global effects + +Copyright (c) 1994-95 Microsoft Corporation + +Module Name: + + resource.h + +NOTE from Testing: + If these values are changed, it will very likely break test automation. Please advise the test + team if these values are altered. (peterje) + +Abstract: + + Resource header file for the TAPI Browser util + +Author: + + Dan Knudson (DanKn) 23-Oct-1994 + +Revision History: + +--*/ + + +//{{NO_DEPENDENCIES}} +// App Studio generated include file. +// Used by TB.RC +// +#define IDR_MENU1 101 +#define IDD_DIALOG1 102 +#define IDD_DIALOG2 103 +#define IDD_DIALOG3 104 +#define IDD_DIALOG4 105 +#define IDD_DIALOG5 106 +#define IDD_DIALOG6 107 +#define IDI_ICON1 108 +#define IDR_ACCELERATOR1 109 +#define IDC_LIST1 1000 +#define IDC_LIST2 1001 +#define IDC_COMBO1 1002 +#define IDC_EDIT1 1003 +#define IDC_CLEAR 1004 +#define IDC_STATIC1 1005 +#define IDC_BUTTON1 1006 +#define IDC_BUTTON2 1007 +#define IDC_BUTTON3 1008 +#define IDC_BUTTON4 1009 +#define IDC_BUTTON5 1010 +#define IDC_BUTTON6 1011 +#define IDC_BUTTON7 1012 +#define IDC_BUTTON8 1013 +#define IDC_BUTTON9 1014 +#define IDC_BUTTON10 1015 +#define IDC_BUTTON11 1016 +#define IDC_BUTTON12 1017 +#define IDC_BUTTON13 1018 +#define IDC_BUTTON14 1019 +#define IDC_BUTTON15 1020 +#define IDC_BUTTON16 1021 +#define IDC_BUTTON17 1022 +#define IDC_BUTTON18 1023 +#define IDC_TB_HELP 1024 +#define IDC_F1HELP 1025 +#define IDC_PREVCTRL 1026 +#define IDC_NEXTCTRL 1027 +#define IDC_ENTER 1028 +#define IDM_DEFAULTVALUES 40001 +#define IDM_ABOUT 40002 +#define IDM_USINGTB 40003 +#define IDM_DUMPPARAMS 40004 +#define IDM_LOGSTRUCTDWORD 40005 +#define IDM_LOGSTRUCTALLFIELD 40006 +#define IDM_LOGSTRUCTNONZEROFIELD 40007 +#define IDM_LOGSTRUCTNONE 40008 +#define IDM_USERBUTTONS 40009 +#define IDM_LOGFILE 40010 +#define IDM_CLEAR 40011 +#define IDM_PARAMS 40012 +#define IDM_EXIT 40013 +#define IDM_TAPIHLP 40014 +#define IDM_TSPIHLP 40015 +#define IDM_NUKEIDLEMONITORCALLS 40016 +#define IDM_NUKEIDLEOWNEDCALLS 40017 +#define IDM_TIMESTAMP 40018 +#define IDM_NOHANDLECHK 40019 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS + +#define _APS_NEXT_RESOURCE_VALUE 110 +#define _APS_NEXT_COMMAND_VALUE 40020 +#define _APS_NEXT_CONTROL_VALUE 1029 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/private/tapi/dev/apps/tb/sources b/private/tapi/dev/apps/tb/sources new file mode 100644 index 000000000..72fbfc5ba --- /dev/null +++ b/private/tapi/dev/apps/tb/sources @@ -0,0 +1,59 @@ +!IF 0 + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + +Author: + + John Rogers (JohnRo) 25-Oct-1991 + +Notes: + + Commented description of this file is in \nt\public\oak\bin\sources.tpl + +Revision History: + +!ENDIF + + +MAJORCOMP=net +MINORCOMP=tapi + +TARGETNAME=tb20 +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=PROGRAM + +TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\comdlg32.lib \ + $(BASEDIR)\public\sdk\lib\*\tapi32l.lib + +INCLUDES=.;$(BASEDIR)\public\sdk\inc + +USE_CRTDLL=1 + +SOURCES=tb.c \ + tb2.c \ + ui.c \ + vars.c \ + widget.c \ + tb.rc + +C_DEFINES=-DTAPI_1_1=1 -DTAPI_2_0=1 + +UMTYPE=windows + +UMENTRY=winmain + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF diff --git a/private/tapi/dev/apps/tb/sources.1_4 b/private/tapi/dev/apps/tb/sources.1_4 new file mode 100644 index 000000000..3593d2ff8 --- /dev/null +++ b/private/tapi/dev/apps/tb/sources.1_4 @@ -0,0 +1,59 @@ +!IF 0 + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + +Author: + + John Rogers (JohnRo) 25-Oct-1991 + +Notes: + + Commented description of this file is in \nt\public\oak\bin\sources.tpl + +Revision History: + +!ENDIF + + +MAJORCOMP=net +MINORCOMP=tapi + +TARGETNAME=tb14 +TARGETPATH=$(BASEDIR)\public\sdk\lib +TARGETTYPE=PROGRAM + +TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\kernel32.lib \ + $(BASEDIR)\public\sdk\lib\*\comdlg32.lib \ + $(BASEDIR)\public\sdk\lib\*\tapi32.lib + +INCLUDES=.;$(BASEDIR)\public\sdk\inc + +USE_CRTDLL=1 + +SOURCES=tb.c \ + tb2.c \ + ui.c \ + vars.c \ + widget.c \ + tb.rc + +C_DEFINES=-DTAPI_1_1=1 + +UMTYPE=windows + +UMENTRY=winmain + +!IFNDEF 386_WARNING_LEVEL +386_WARNING_LEVEL=/W3 +!ENDIF diff --git a/private/tapi/dev/apps/tb/tb.c b/private/tapi/dev/apps/tb/tb.c new file mode 100644 index 000000000..72cd628c6 --- /dev/null +++ b/private/tapi/dev/apps/tb/tb.c @@ -0,0 +1,3854 @@ +/*++ BUILD Version: 0000 // Increment this if a change has global effects + +Copyright (c) 1994-96 Microsoft Corporation + +Module Name: + + tb.c + +Abstract: + + API wrapper code for the TAPI Browser util. Contains the big switch + statement for all the supported Telephony API's, & various support funcs. + +Author: + + Dan Knudson (DanKn) 23-Aug-1994 + +Revision History: + +--*/ + + +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <ctype.h> +#include <malloc.h> +#include "tb.h" +#include "vars.h" +#include "resource.h" + + +char szdwDeviceID[] = "dwDeviceID"; +char szdwSize[] = "dwSize"; +char szhCall[] = "hCall"; +char szhLine[] = "hLine"; +char szhLineApp[] = "hLineApp"; +char szhPhone[] = "hPhone"; +char szlpCallParams[] = "lpCallParams"; + +char szlphCall[] = "lphCall"; +char szlpParams[] = "lpParams"; +char szhwndOwner[] = "hwndOwner"; +char szdwAddressID[] = "dwAddressID"; +char szlpszAppName[] = "lpszAppName"; +char szdwAPIVersion[] = "APIVersion"; +char szlphConsultCall[] = "lphConsultCall"; +char szlpszDeviceClass[] = "lpszDeviceClass"; +char szlpszDestAddress[] = "lpszDestAddress"; +char szlpsUserUserInfo[] = "lpsUserUserInfo"; +char szlpszFriendlyAppName[] = "lpszFriendlyAppName"; + + +DWORD NullWidget[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + +void +FuncDriver2( + FUNC_INDEX funcIndex + ); + + +char * +PASCAL +GetTimeStamp( + void + ) +{ + static char szEmptyString[] = "", szTimeStamp[32]; + SYSTEMTIME systemTime; + + + if (!bTimeStamp) + { + return szEmptyString; + } + + GetLocalTime (&systemTime); + + wsprintf( + szTimeStamp, + "%d:%d.%d.%d : ", + (DWORD) systemTime.wHour, + (DWORD) systemTime.wMinute, + (DWORD) systemTime.wSecond, + (DWORD) systemTime.wMilliseconds + ); + + return szTimeStamp; +} + + +void +ShowLineFuncResult( + LPSTR lpFuncName, + LONG lResult + ) +{ + char *pszTimeStamp = GetTimeStamp(); + + + if (lResult > 0) + { + ShowStr ("%s%s returned x%lx", pszTimeStamp, lpFuncName, lResult); + } + else if (lResult != 0 && + ((DWORD) lResult < LINEERR_ALLOCATED || + (DWORD) lResult > LAST_LINEERR)) + { + MessageBeep ((UINT) -1); + + ShowStr( + "%s%s returned inval err code (x%lx)", + pszTimeStamp, + lpFuncName, + lResult + ); + } + else + { + if (lResult < 0) + { + MessageBeep ((UINT) -1); + } + + ShowStr( + "%s%s returned %s%s", + pszTimeStamp, + lpFuncName, + (lResult ? "LINEERR_" : ""), // ...to shrink aszLineErrs array + aszLineErrs[LOWORD(lResult)] + ); + } +} + + +void +ShowPhoneFuncResult( + LPSTR lpFuncName, + LONG lResult + ) +{ + char *pszTimeStamp = GetTimeStamp(); + + + if (lResult > 0) + { + ShowStr ("%s%s returned x%lx", pszTimeStamp, lpFuncName, lResult); + } + else if (lResult != 0 && + ((DWORD) lResult < PHONEERR_ALLOCATED || + (DWORD) lResult > PHONEERR_REINIT)) + { + MessageBeep ((UINT) -1); + + ShowStr( + "%s%s returned inval err code (x%lx)", + pszTimeStamp, + lpFuncName, + lResult + ); + } + else + { + if (lResult < 0) + { + MessageBeep ((UINT) -1); + } + + ShowStr( + "%s%s returned %s%s", + pszTimeStamp, + lpFuncName, + (lResult ? "PHONEERR_" : ""), // ...to shrink aszPhoneErrs array + aszPhoneErrs[LOWORD(lResult)] + ); + } +} + + +void +ShowTapiFuncResult( + LPSTR lpFuncName, + LONG lResult + ) +{ + char *pszTimeStamp = GetTimeStamp(); + + + if ((lResult > 0) || (lResult < TAPIERR_INVALPOINTER)) + { + ShowStr( + "%s%s returned inval err code (x%lx)", + pszTimeStamp, + lpFuncName, + lResult + ); + } + else + { + lResult = (~lResult) + 1; + + if (lResult > 0) + { + MessageBeep ((UINT) -1); + } + + ShowStr( + "%s%s returned %s%s", + pszTimeStamp, + lpFuncName, + (lResult ? "TAPIERR_" : ""), // ...to shrink aszTapiErrs array + aszTapiErrs[lResult] + ); + } +} + + +void +UpdateResults( + BOOL bBegin + ) +{ + // + // In order to maximize speed, minimize flash, & have the + // latest info in the edit control scrolled into view we + // shrink the window down and hide it. Later, when all the + // text has been inserted in the edit control, we show + // the window (since window must be visible in order to + // scroll caret into view), then tell it to scroll the caret + // (at this point the window is still 1x1 so the painting + // overhead is 0), and finally restore the control to it's + // full size. In doing so we have zero flash and only 1 real + // complete paint. Also put up the hourglass for warm fuzzies. + // + + static RECT rect; + static HCURSOR hCurSave; + static int iNumBegins = 0; + + + if (bBegin) + { + iNumBegins++; + + if (iNumBegins > 1) + { + return; + } + + hCurSave = SetCursor (LoadCursor ((HINSTANCE)NULL, IDC_WAIT)); + GetWindowRect (ghwndEdit, &rect); + SetWindowPos( + ghwndEdit, + (HWND) NULL, + 0, + 0, + 1, + 1, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOREDRAW | + SWP_NOZORDER | SWP_HIDEWINDOW + ); + } + else + { + iNumBegins--; + + if (iNumBegins > 0) + { + return; + } + + // + // Do control restoration as described above + // + + ShowWindow (ghwndEdit, SW_SHOW); +#ifdef WIN32 + SendMessage (ghwndEdit, EM_SCROLLCARET, 0, 0); +#else + SendMessage( + ghwndEdit, + EM_SETSEL, + (WPARAM)0, + (LPARAM) MAKELONG(0xfffd,0xfffe) + ); +#endif + SetWindowPos( + ghwndEdit, + (HWND) NULL, + 0, + 0, + rect.right - rect.left, + rect.bottom - rect.top, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER + ); + SetCursor (hCurSave); + } +} + + +void +ShowModBytes( + DWORD dwSize, + unsigned char far *lpc, + char *pszTab, + char *buf + ) +{ + DWORD dwSize2 = dwSize, i, j, k; + + + strcpy (buf, pszTab); + + k = strlen (buf); + + for (i = 8; i < 36; i += 9) + { + buf[k + i] = ' '; + + for (j = 2; j < 9; j += 2) + { + char buf2[8] = "xx"; + + if (dwSize2) + { + sprintf (buf2, "%02x", (int) (*lpc)); + dwSize2--; + } + + buf[k + i - j] = buf2[0]; + buf[k + i - j + 1] = buf2[1]; + + lpc++; + } + } + + k += 37; + + buf[k - 1] = ' '; + + lpc -= 16; + + for (i = 0; i < dwSize; i++) + { + buf[k + i] = aAscii[*(lpc+i)]; + } + + buf[k + i] = 0; + + ShowStr (buf); +} + + +void +ShowBytes( + DWORD dwSize, + LPVOID lp, + DWORD dwNumTabs + ) +{ + char tabBuf[17] = ""; + char buf[80]; + DWORD i, j, k, dwNumDWORDs, dwMod4 = ((DWORD) lp) % 4; + LPDWORD lpdw; + unsigned char far *lpc = (unsigned char far *) lp; + + + UpdateResults (TRUE); + + + for (i = 0; i < dwNumTabs; i++) + { + strcat (tabBuf, szTab); + } + + + // + // Special case for unaligned pointers (will fault on ppc/mips) + // + + if (dwMod4) + { + DWORD dwNumUnalignedBytes = 4 - dwMod4, + dwNumBytesToShow = (dwNumUnalignedBytes > dwSize ? + dwSize : dwNumUnalignedBytes); + + + ShowModBytes (dwNumBytesToShow, lpc, tabBuf, buf); + lpc += dwNumUnalignedBytes; + lpdw = (LPDWORD) lpc; + dwSize -= dwNumBytesToShow; + } + else + { + lpdw = (LPDWORD) lp; + } + + + // + // Dump full lines of four DWORDs in hex & corresponding ASCII + // + + if (dwSize >= (4*sizeof(DWORD))) + { + dwNumDWORDs = dwSize / 4; // adjust from numBytes to num DWORDs + + for (i = 0; i < (dwNumDWORDs - (dwNumDWORDs%4)); i += 4) + { + sprintf ( + buf, + "%s%08lx %08lx %08lx %08lx ", + tabBuf, + *lpdw, + *(lpdw+1), + *(lpdw+2), + *(lpdw+3) + ); + + k = strlen (buf); + + for (j = 0; j < 16; j++) + { + buf[k + j] = aAscii[*(lpc + j)]; + } + + buf[k + j] = 0; + + ShowStr (buf); + lpdw += 4; + lpc += 16; + } + } + + + // + // Special case for remaining bytes to dump (0 < n < 16) + // + + if ((dwSize %= 16)) + { + ShowModBytes (dwSize, lpc, tabBuf, buf); + } + + + UpdateResults (FALSE); +} + + +void +ShowStructByDWORDs( + LPVOID lp + ) +{ + + if (dwDumpStructsFlags & DS_BYTEDUMP) + { + // + // Cast lp as DWORD, then add 2 to point to where a + // dwUsedSize field is in a TAPI struct + // + + ShowBytes (*(((LPDWORD) lp) + 2), lp, 0); + } +} + + +void +ShowStructByField( + PSTRUCT_FIELD_HEADER pHeader, + BOOL bSubStructure + ) +{ + static char far *aszCommonFields[] = + { + "dwTotalSize", + "dwNeededSize", + "dwUsedSize" + }; + DWORD i, j; + char far *buf = malloc (256); + + + UpdateResults (TRUE); + + ShowStr (pHeader->szName); + + if (!bSubStructure) + { + LPDWORD lpdw = (LPDWORD) pHeader->pStruct; + + + for (i = 0; i < 3; i++) + { + ShowStr ("%s%s=x%lx", szTab, aszCommonFields[i], *lpdw); + lpdw++; + } + } + + for (i = 0; i < pHeader->dwNumFields; i++) + { + if ((pHeader->aFields[i].dwValue == 0) && + !(dwDumpStructsFlags & DS_ZEROFIELDS)) + { + continue; + } + + sprintf( + buf, + "%s%s=x%lx", + szTab, + pHeader->aFields[i].szName, + pHeader->aFields[i].dwValue + ); + + switch (pHeader->aFields[i].dwType) + { + case FT_DWORD: + + ShowStr (buf); + break; + + case FT_FLAGS: + { + PLOOKUP pLookup = pHeader->aFields[i].pLookup; + + + strcat (buf, ", "); + + for( + j = 0; + pHeader->aFields[i].dwValue, pLookup[j].dwVal != 0xffffffff; + j++ + ) + { + if (pHeader->aFields[i].dwValue & pLookup[j].dwVal) + { + if (buf[0] == 0) + { + sprintf (buf, "%s%s", szTab, szTab); + } + + strcat (buf, pLookup[j].lpszVal); + strcat (buf, " "); + pHeader->aFields[i].dwValue = + pHeader->aFields[i].dwValue & ~pLookup[j].dwVal; + + if (strlen (buf) > 50) + { + // + // We don't want strings getting so long that + // they're going offscreen, so break them up. + // + + ShowStr (buf); + buf[0] = 0; + } + } + } + + if (pHeader->aFields[i].dwValue) + { + strcat (buf, "<unknown flag(s)>"); + } + + if (buf[0]) + { + ShowStr (buf); + } + + break; + } + case FT_ORD: + { + PLOOKUP pLookup = pHeader->aFields[i].pLookup; + + + strcat (buf, ", "); + + for( + j = 0; + pLookup[j].dwVal != 0xffffffff; + j++ + ) + { + if (pHeader->aFields[i].dwValue == pLookup[j].dwVal) + { + strcat (buf, pLookup[j].lpszVal); + break; + } + } + + if (pLookup[j].dwVal == 0xffffffff) + { + strcpy (buf, "<unknown ordinal>"); + } + + ShowStr (buf); + break; + } + case FT_SIZE: + + ShowStr (buf); + break; + + case FT_OFFSET: + + ShowStr (buf); + + if (IsBadReadPtr( + ((char far *) pHeader->pStruct) + + pHeader->aFields[i].dwValue, + (UINT)pHeader->aFields[i-1].dwValue + )) + { + ShowStr ("<size/offset pair yields bad pointer>"); + } + else + { + ShowBytes( + pHeader->aFields[i-1].dwValue, + ((char far *) pHeader->pStruct) + + pHeader->aFields[i].dwValue, + 2 + ); + } + + break; + } + } + + free (buf); + + UpdateResults (FALSE); +} + + +void +ShowVARSTRING( + LPVARSTRING lpVarString + ) +{ + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + STRUCT_FIELD fields[] = + { + { "dwStringFormat", FT_ORD, lpVarString->dwStringFormat, aStringFormats }, + { "dwStringSize", FT_SIZE, lpVarString->dwStringSize, NULL }, + { "dwStringOffset", FT_OFFSET, lpVarString->dwStringOffset, NULL } + + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpVarString, + "VARSTRING", + 3, + fields + }; + + ShowStructByField (&fieldHeader, FALSE); + } +} + + +BOOL +LetUserMungeParams( + PFUNC_PARAM_HEADER pParamsHeader + ) +{ + if (!bShowParams) + { + return TRUE; + } + + return (DialogBoxParam( + ghInst, + (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG2), + ghwndMain, + (DLGPROC) ParamsDlgProc, + (LPARAM) pParamsHeader + )); +} + + +void +DumpParams( + PFUNC_PARAM_HEADER pHeader + ) +{ + if (bTimeStamp || bDumpParams) + { + char *pszTimeStamp = GetTimeStamp(); + + + UpdateResults (TRUE); + + ShowStr( + "%sCalling %s", + pszTimeStamp, + aFuncNames[pHeader->FuncIndex] + ); + + if (bDumpParams) + { + DWORD i; + + + for (i = 0; i < pHeader->dwNumParams; i++) + { + ShowStr( + " %s=x%lx", + pHeader->aParams[i].szName, + pHeader->aParams[i].dwValue + ); + } + + } + + UpdateResults (FALSE); + } +} + + +LONG +DoFunc( + PFUNC_PARAM_HEADER pHeader + ) +{ + LONG lResult; + + + if (!LetUserMungeParams (pHeader)) + { + return 0xffffffff; + } + +#if TAPI_2_0 + + // + // Convert any unicode string params as appropriate + // + + if (gbWideStringParams) + { + DWORD dwNumParams = pHeader->dwNumParams, i; + PFUNC_PARAM pParam = pHeader->aParams; + + + for (i = 0; i < dwNumParams; i++) + { + if (pParam->dwType == PT_STRING && + pParam->dwValue != 0 && + pParam->dwValue != 0xffffffff) + { + int len = strlen ((char *) pParam->dwValue) + 1; + WCHAR buf[MAX_STRING_PARAM_SIZE/2]; + + + MultiByteToWideChar( + GetACP(), + MB_PRECOMPOSED, + (LPCSTR) pParam->dwValue, + (len > MAX_STRING_PARAM_SIZE/2 ? + MAX_STRING_PARAM_SIZE/2 - 1 : -1), + buf, + MAX_STRING_PARAM_SIZE/2 + ); + + buf[MAX_STRING_PARAM_SIZE/2 - 1] = 0; + + lstrcpyW ((WCHAR *) pParam->dwValue, buf); + } + + pParam++; + } + } + +#endif + + DumpParams (pHeader); + + switch (pHeader->dwNumParams) + { + case 1: + + lResult = (*pHeader->u.pfn1)( + pHeader->aParams[0].dwValue + ); + break; + + case 2: + + lResult = (*pHeader->u.pfn2)( + pHeader->aParams[0].dwValue, + pHeader->aParams[1].dwValue + ); + break; + + case 3: + + lResult = (*pHeader->u.pfn3)( + pHeader->aParams[0].dwValue, + pHeader->aParams[1].dwValue, + pHeader->aParams[2].dwValue + ); + break; + + case 4: + + lResult = (*pHeader->u.pfn4)( + pHeader->aParams[0].dwValue, + pHeader->aParams[1].dwValue, + pHeader->aParams[2].dwValue, + pHeader->aParams[3].dwValue + ); + break; + + case 5: + + lResult = (*pHeader->u.pfn5)( + pHeader->aParams[0].dwValue, + pHeader->aParams[1].dwValue, + pHeader->aParams[2].dwValue, + pHeader->aParams[3].dwValue, + pHeader->aParams[4].dwValue + ); + break; + + case 6: + + lResult = (*pHeader->u.pfn6)( + pHeader->aParams[0].dwValue, + pHeader->aParams[1].dwValue, + pHeader->aParams[2].dwValue, + pHeader->aParams[3].dwValue, + pHeader->aParams[4].dwValue, + pHeader->aParams[5].dwValue + ); + break; + + case 7: + + lResult = (*pHeader->u.pfn7)( + pHeader->aParams[0].dwValue, + pHeader->aParams[1].dwValue, + pHeader->aParams[2].dwValue, + pHeader->aParams[3].dwValue, + pHeader->aParams[4].dwValue, + pHeader->aParams[5].dwValue, + pHeader->aParams[6].dwValue + ); + break; + + case 8: + + lResult = (*pHeader->u.pfn8)( + pHeader->aParams[0].dwValue, + pHeader->aParams[1].dwValue, + pHeader->aParams[2].dwValue, + pHeader->aParams[3].dwValue, + pHeader->aParams[4].dwValue, + pHeader->aParams[5].dwValue, + pHeader->aParams[6].dwValue, + pHeader->aParams[7].dwValue + ); + break; + + case 9: + + lResult = (*pHeader->u.pfn9)( + pHeader->aParams[0].dwValue, + pHeader->aParams[1].dwValue, + pHeader->aParams[2].dwValue, + pHeader->aParams[3].dwValue, + pHeader->aParams[4].dwValue, + pHeader->aParams[5].dwValue, + pHeader->aParams[6].dwValue, + pHeader->aParams[7].dwValue, + pHeader->aParams[8].dwValue + ); + break; + + case 10: + + lResult = (*pHeader->u.pfn10)( + pHeader->aParams[0].dwValue, + pHeader->aParams[1].dwValue, + pHeader->aParams[2].dwValue, + pHeader->aParams[3].dwValue, + pHeader->aParams[4].dwValue, + pHeader->aParams[5].dwValue, + pHeader->aParams[6].dwValue, + pHeader->aParams[7].dwValue, + pHeader->aParams[8].dwValue, + pHeader->aParams[9].dwValue + ); + break; + + default: // case 12: + + lResult = (*pHeader->u.pfn12)( + pHeader->aParams[0].dwValue, + pHeader->aParams[1].dwValue, + pHeader->aParams[2].dwValue, + pHeader->aParams[3].dwValue, + pHeader->aParams[4].dwValue, + pHeader->aParams[5].dwValue, + pHeader->aParams[6].dwValue, + pHeader->aParams[7].dwValue, + pHeader->aParams[8].dwValue, + pHeader->aParams[9].dwValue, + pHeader->aParams[10].dwValue, + pHeader->aParams[11].dwValue + ); + break; + } + + if (pHeader->FuncIndex < pClose) + { + ShowLineFuncResult (aFuncNames[pHeader->FuncIndex], lResult); + } + else if (pHeader->FuncIndex < tGetLocationInfo) + { + ShowPhoneFuncResult (aFuncNames[pHeader->FuncIndex], lResult); + } + else + { + ShowTapiFuncResult (aFuncNames[pHeader->FuncIndex], lResult); + } + + return lResult; +} + + +BOOL +IsLineAppSelected( + void + ) +{ + if (!pLineAppSel) + { + if (gbDisableHandleChecking) + { + pLineAppSel = (PMYLINEAPP) NullWidget; + } + else + { + MessageBeep ((UINT) -1); + MessageBox (ghwndMain, "Select an hLineApp", "", MB_OK); + return FALSE; + } + } + + return TRUE; +} + + +BOOL +IsLineSelected( + void + ) +{ + if (!pLineSel) + { + if (gbDisableHandleChecking) + { + pLineSel = (PMYLINE) NullWidget; + } + else + { + MessageBeep ((UINT) -1); + MessageBox (ghwndMain, "Select a Line", "", MB_OK); + return FALSE; + } + } + + return TRUE; +} + + +BOOL +IsCallSelected( + void + ) +{ + if (!pCallSel) + { + if (gbDisableHandleChecking) + { + pCallSel = (PMYCALL) NullWidget; + } + else + { + MessageBeep ((UINT) -1); + MessageBox (ghwndMain, "Select a Call", "", MB_OK); + return FALSE; + } + } + + return TRUE; +} + + +BOOL +IsTwoCallsSelected( + void + ) +{ + if (!pCallSel || !pCallSel2) + { + if (gbDisableHandleChecking) + { + if (!pCallSel) + { + pCallSel = (PMYCALL) NullWidget; + } + + pCallSel2 = (PMYCALL) NullWidget; + } + else + { + MessageBeep ((UINT) -1); + MessageBox( + ghwndMain, + "Select a Call (must have at least two calls on same line)", + "", + MB_OK + ); + return FALSE; + } + } + + return TRUE; +} + + +BOOL +IsPhoneAppSelected( + void + ) +{ + if (!pPhoneAppSel) + { + if (gbDisableHandleChecking) + { + pPhoneAppSel = (PMYPHONEAPP) NullWidget; + } + else + { + MessageBeep ((UINT) -1); + MessageBox (ghwndMain, "Select a PhoneApp", "", MB_OK); + return FALSE; + } + } + + return TRUE; +} + + +BOOL +IsPhoneSelected( + void + ) +{ + if (!pPhoneSel) + { + if (gbDisableHandleChecking) + { + pPhoneSel = (PMYPHONE) NullWidget; + } + else + { + MessageBeep ((UINT) -1); + MessageBox (ghwndMain, "Select a Phone", "", MB_OK); + return FALSE; + } + } + + return TRUE; +} + + +// +// We get a slough of C4113 (func param lists differed) warnings down below +// in the initialization of FUNC_PARAM_HEADER structs as a result of the +// real func prototypes having params that are pointers rather than DWORDs, +// so since these are known non-interesting warnings just turn them off +// + +#pragma warning (disable:4113) + +//#pragma code_seg ("myseg") + +void +FuncDriver( + FUNC_INDEX funcIndex + ) +{ + int i; + LONG lResult; + + +#if TAPI_2_0 + + // + // Determine if we're doing a ascii or a unicode op + // + + gbWideStringParams = + ((aFuncNames[funcIndex])[strlen (aFuncNames[funcIndex]) - 1] == 'W' ? + TRUE : FALSE); + +#endif + + switch (funcIndex) + { + case lAccept: + { + char szUserUserInfo[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { szlpsUserUserInfo, PT_STRING, (DWORD) szUserUserInfo, szUserUserInfo }, + { szdwSize, PT_DWORD, strlen(szDefUserUserInfo)+1, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineAccept }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + strcpy (szUserUserInfo, szDefUserUserInfo); + + lResult = DoFunc (¶msHeader); + + break; + } + case lAddToConference: + { + FUNC_PARAM params[] = + { + { "hConfCall", PT_DWORD, 0, NULL }, + { "hConsultCall", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineAddToConference }; + + + CHK_TWO_CALLS_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + params[1].dwValue = (DWORD) pCallSel2->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } +#if TAPI_2_0 + case lAgentSpecific: + { + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, 0, NULL }, + { "dwAgentExtensionIDIndex", PT_DWORD, 0, NULL }, + { szlpParams, PT_STRING, (DWORD) pBigBuf, pBigBuf }, + { szdwSize, PT_DWORD, dwBigBufSize, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) lineAgentSpecific }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + lResult = DoFunc (¶msHeader); + + break; + } +#endif + case lAnswer: + { + char szUserUserInfo[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { szlpsUserUserInfo, PT_STRING, (DWORD) szUserUserInfo, szUserUserInfo }, + { szdwSize, PT_DWORD, strlen(szDefUserUserInfo)+1, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineAnswer }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + strcpy (szUserUserInfo, szDefUserUserInfo); + + lResult = DoFunc (¶msHeader); + + break; + } + case lBlindTransfer: +#if TAPI_2_0 + case lBlindTransferW: +#endif + { + char szDestAddress[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { szlpszDestAddress, PT_STRING, (DWORD) szDestAddress, szDestAddress }, + { "dwCountryCode", PT_DWORD, dwDefCountryCode, NULL } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lBlindTransfer ? + (PFN3) lineBlindTransfer : (PFN3) lineBlindTransferW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineBlindTransfer }; +#endif + + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + strcpy (szDestAddress, szDefDestAddress); + + lResult = DoFunc (¶msHeader); + + break; + } + case lClose: + { + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 1, funcIndex, params, (PFN1) lineClose }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + if ((lResult = DoFunc(¶msHeader)) == 0) + { + FreeLine (GetLine((HLINE) params[0].dwValue)); + } + + break; + } + case lCompleteCall: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "lpdwCompletionID", PT_POINTER, 0, NULL }, + { "dwCompletionMode", PT_FLAGS, LINECALLCOMPLMODE_CAMPON, aCallComplModes }, + { "dwMessageID", PT_DWORD, 0, NULL }, + }; + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) lineCompleteCall }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + params[1].dwValue = (DWORD) &pCallSel->dwCompletionID; + +// BUGBUG if user chgs hCall the wrong &pCallSel->dwCompletionID filled in + + DoFunc(¶msHeader); + + break; + } + case lCompleteTransfer: + { + PMYCALL pNewCall; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "hConsultCall", PT_DWORD, 0, NULL }, + { "lphConfCall", PT_POINTER, 0, NULL }, + { "dwTransferMode", PT_ORDINAL, LINETRANSFERMODE_TRANSFER, aTransferModes } + }; + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) lineCompleteTransfer }; + + + CHK_TWO_CALLS_SELECTED() + + if (!(pNewCall = AllocCall (pLineSel))) + { + break; + } + + params[0].dwValue = (DWORD) pCallSel->hCall; + params[1].dwValue = (DWORD) pCallSel2->hCall; + params[2].dwValue = params[2].u.dwDefValue = (DWORD) &pNewCall->hCall; + + if ((lResult = DoFunc (¶msHeader)) >= 0) + { + // + // First make sure we're created the call under the right line, + // and if not move it to the right place in the widgets list + // + + LINECALLINFO callInfo; + + + memset (&callInfo, 0, sizeof(LINECALLINFO)); + callInfo.dwTotalSize = sizeof(LINECALLINFO); + if (lineGetCallInfo ((HCALL) params[0].dwValue, &callInfo) == 0) + { + if (callInfo.hLine != pLineSel->hLine) + { + MoveCallToLine (pNewCall, callInfo.hLine); + } + } + + pNewCall->lMakeCallReqID = lResult; + dwNumPendingMakeCalls++; + SelectWidget ((PMYWIDGET) pNewCall); + } + else + { + FreeCall (pNewCall); + } + + break; + } + case lConfigDialog: +#if TAPI_2_0 + case lConfigDialogW: +#endif + { + char szDeviceClass[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { szdwDeviceID, PT_DWORD, dwDefLineDeviceID, NULL }, + { szhwndOwner, PT_DWORD, (DWORD) ghwndMain, NULL }, + { szlpszDeviceClass, PT_STRING, (DWORD) szDeviceClass, szDeviceClass } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lConfigDialog ? + (PFN3) lineConfigDialog : (PFN3) lineConfigDialogW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineConfigDialog }; +#endif + + + CHK_LINEAPP_SELECTED() + + strcpy (szDeviceClass, szDefLineDeviceClass); + +#ifdef WIN32 + lResult = DoFunc (¶msHeader); +#else + // + // NOTE: on win16 HWNDSs are 16 bits, so we've to hard code this + // + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + DumpParams (¶msHeader); + + lResult = lineConfigDialog( + params[0].dwValue, + (HWND) params[1].dwValue, + (LPCSTR) params[2].dwValue + ); + + ShowLineFuncResult (aFuncNames[funcIndex], lResult); +#endif + break; + } + case lDeallocateCall: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 1, funcIndex, params, (PFN1) lineDeallocateCall }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + FreeCall (GetCall((HCALL) params[0].dwValue)); + } + + break; + } + case lDevSpecific: + { + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { szhCall, PT_DWORD, 0, NULL }, + { szlpParams, PT_STRING, (DWORD) pBigBuf, pBigBuf }, + { szdwSize, PT_DWORD, dwBigBufSize, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) lineDevSpecific }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + if (pCallSel) + { + params[2].dwValue = (DWORD) pCallSel->hCall; + } + + memset (pBigBuf, 0, (size_t) dwBigBufSize); + + DoFunc (¶msHeader); + + break; + } + case lDevSpecificFeature: + { + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, +// { "dwFeature", PT_???, 0, aPhoneButtonFunctions }, + { "dwFeature", PT_DWORD, 0, NULL }, + { szlpParams, PT_STRING, (DWORD) pBigBuf, pBigBuf }, + { szdwSize, PT_DWORD, dwBigBufSize, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) lineDevSpecificFeature }; + + + // BUGBUG need another PT_ type for constants for dwFeature param + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + memset (pBigBuf, 0, (size_t) dwBigBufSize); + + DoFunc (¶msHeader); + + break; + } + case lDial: +#if TAPI_2_0 + case lDialW: +#endif + { + char szAddress[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { szlpszDestAddress, PT_STRING, (DWORD) szAddress, szAddress }, + { "dwCountryCode", PT_DWORD, dwDefCountryCode, NULL } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lDial ? + (PFN3) lineDial : (PFN3) lineDialW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineDial }; +#endif + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + strcpy (szAddress, szDefDestAddress); + + lResult = DoFunc (¶msHeader); + + break; + } + case lDrop: + { + char szUserUserInfo[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { szlpsUserUserInfo, PT_STRING, (DWORD) szUserUserInfo, szUserUserInfo }, + { szdwSize, PT_DWORD, strlen(szDefUserUserInfo)+1, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineDrop }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + strcpy (szUserUserInfo, szDefUserUserInfo); + + lResult = DoFunc (¶msHeader); + + // assert (lResult != 0); + + if (gbDeallocateCall && (lResult > 0)) + { + PMYCALL pCall = GetCall ((HCALL) params[0].dwValue); + + dwNumPendingDrops++; + pCall->lDropReqID = lResult; + } + + break; + } + case lForward: +#if TAPI_2_0 + case lForwardW: +#endif + { + PMYCALL pNewCall; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { "bAllAddresses", PT_DWORD, 1, NULL }, + { szdwAddressID, PT_DWORD, 0, NULL }, + { "lpForwardList", PT_FORWARDLIST, 0, NULL }, + { "dwNumRingsNoAnswer", PT_DWORD, 5, NULL }, + { szlphConsultCall, PT_POINTER, 0, NULL }, + { szlpCallParams, PT_CALLPARAMS, 0, lpCallParams } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 7, funcIndex, params, (funcIndex == lForward ? + (PFN7) lineForward : (PFN7) lineForwardW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 7, funcIndex, params, (PFN7) lineForward }; +#endif + LPLINEFORWARDLIST lpForwardList; + DWORD dwTotalSize = sizeof(LINEFORWARDLIST) + + MAX_LINEFORWARD_ENTRIES * + (sizeof(LINEFORWARD) + 2*MAX_STRING_PARAM_SIZE); + + + CHK_LINE_SELECTED() + + + if (!(lpForwardList = malloc (dwTotalSize))) + { + MessageBeep ((UINT) -1); + ShowStr ("error alloc'ing data structure"); + break; + } + + memset (lpForwardList, 0, dwTotalSize); + + lpForwardList->dwTotalSize = dwTotalSize; + lpForwardList->dwNumEntries = 0; + + if (!(pNewCall = AllocCall (pLineSel))) + { + MessageBeep ((UINT) -1); + ShowStr ("error creating data structure"); + free (lpForwardList); + break; + } + + params[0].dwValue = (DWORD) pLineSel->hLine; + params[3].dwValue = params[3].u.dwDefValue = (DWORD) lpForwardList; + params[5].dwValue = params[5].u.dwDefValue = (DWORD) &pNewCall->hCall; + + if ((lResult = DoFunc (¶msHeader)) > 0) + { + if (params[0].dwValue != (DWORD) pLineSel->hLine) + { + MoveCallToLine (pNewCall, (HLINE) params[0].dwValue); + } + + pNewCall->lMakeCallReqID = lResult; + dwNumPendingMakeCalls++; + SelectWidget ((PMYWIDGET) pNewCall); + } + else + { + FreeCall (pNewCall); + } + + free (lpForwardList); + + break; + } + case lGatherDigits: +#if TAPI_2_0 + case lGatherDigitsW: +#endif + { + char *buf; + char szTermDigits[MAX_STRING_PARAM_SIZE] = ""; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "dwDigitModes", PT_FLAGS, LINEDIGITMODE_DTMF, aDigitModes }, + { "lpsDigits", PT_POINTER, 0, NULL }, + { "dwNumDigits", PT_DWORD, 0, NULL }, + { "lpszTerminationDigits", PT_STRING, (DWORD) szTermDigits, szTermDigits }, + { "dwFirstDigitTimeout", PT_DWORD, 0x8000, NULL }, + { "dwInterDigitTimeout", PT_DWORD, 0x8000, NULL }, + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 7, funcIndex, params, (funcIndex == lGatherDigits ? + (PFN7) lineGatherDigits : (PFN7) lineGatherDigitsW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 7, funcIndex, params, (PFN7) lineGatherDigits }; +#endif + + CHK_CALL_SELECTED() + + #define DEF_NUM_GATHERED_DIGITS 64 + + if (!(buf = (char *) malloc ((DEF_NUM_GATHERED_DIGITS + 1) * 2))) + { + ShowStr ("failed to allocate memory"); + break; + } + + params[0].dwValue = (DWORD) pCallSel->hCall; + params[2].dwValue = + params[2].u.dwDefValue = (DWORD) buf; + params[3].dwValue = DEF_NUM_GATHERED_DIGITS; + + memset (buf, 0, DEF_NUM_GATHERED_DIGITS * 2); + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + if (params[0].dwValue != (DWORD) pCallSel->hCall) + { + pCallSel = GetCall ((HCALL) params[0].dwValue); + } + + if (params[2].dwValue == (DWORD) buf && + params[3].dwValue > DEF_NUM_GATHERED_DIGITS) + { + if (MessageBox( + ghwndMain, + "Do you want to allocate a larger GatherDigits buffer?" \ + "(Not doing so may cause undefined app behavior.)", + "Warning: lineGatherDigits", + MB_YESNO + ) == IDYES) + { + free (buf); + + // Note: we get weird errors in malloc when specifying a + // size > 0xffffff00, so special case + + if (params[3].dwValue > 0x10000) + { + ShowStr ("sorry, too many digits."); + break; + } + + buf = (char *) malloc ((size_t) (params[3].dwValue + 1) * 2); + + if (!(params[2].dwValue = (DWORD) buf)) + { + ShowStr ("failed to allocate memory"); + break; + } + + memset (buf, 0, (size_t) params[3].dwValue * 2); + } + } + + if (pCallSel->lpsGatheredDigits && params[2].dwValue) + { + if (MessageBox( + ghwndMain, + "GatherDigits already in progress on this hCall; if you" \ + "continue previous digits buffer may be discarded" \ + "without being freed", + "Warning: lineGatherDigits", + MB_OKCANCEL + + ) == IDCANCEL) + { + if (buf) + { + free (buf); + } + break; + } + } + + DumpParams (¶msHeader); + +#if TAPI_2_0 + if (funcIndex == lGatherDigits) + { + lResult = lineGatherDigits( + (HCALL) params[0].dwValue, + params[1].dwValue, + (LPSTR) params[2].dwValue, + params[3].dwValue, + (LPCSTR) params[4].dwValue, + params[5].dwValue, + params[6].dwValue + ); + } + else + { + lResult = lineGatherDigitsW( + (HCALL) params[0].dwValue, + params[1].dwValue, + (LPWSTR) params[2].dwValue, + params[3].dwValue, + (LPCWSTR) params[4].dwValue, + params[5].dwValue, + params[6].dwValue + ); + } +#else + lResult = lineGatherDigits( + (HCALL) params[0].dwValue, + params[1].dwValue, + (LPSTR) params[2].dwValue, + params[3].dwValue, + (LPCSTR) params[4].dwValue, + params[5].dwValue, + params[6].dwValue + ); + +#endif + ShowLineFuncResult (aFuncNames[funcIndex], lResult); + + if (lResult) // FAILURE + { + if (buf) + { + free (buf); + } + } + else // SUCCESS + { + if (pCallSel->lpsGatheredDigits) + { + free (pCallSel->lpsGatheredDigits); + } + + pCallSel->lpsGatheredDigits = (char *) params[2].dwValue; + pCallSel->dwNumGatheredDigits = params[3].dwValue; +#if TAPI_2_0 + if (funcIndex == lGatherDigitsW) + { + pCallSel->dwNumGatheredDigits *= 2; + } +#endif + } + + break; + } + case lGenerateDigits: +#if TAPI_2_0 + case lGenerateDigitsW: +#endif + { + char szDigits[MAX_STRING_PARAM_SIZE] = "123"; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "dwDigitMode", PT_FLAGS, LINEDIGITMODE_DTMF, aDigitModes }, + { "lpszDigits", PT_STRING, (DWORD) szDigits, szDigits }, + { "dwDuration", PT_DWORD, 0, NULL } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (funcIndex == lGenerateDigits ? + (PFN4) lineGenerateDigits : (PFN4) lineGenerateDigitsW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) lineGenerateDigits }; +#endif + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } + case lGenerateTone: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "dwToneMode", PT_FLAGS, LINETONEMODE_CUSTOM, aToneModes }, + { "dwDuration", PT_DWORD, 0, NULL }, + { "dwNumTones", PT_DWORD, 1, NULL }, + { "lpTones", PT_POINTER, (DWORD) pBigBuf, pBigBuf } + }; + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) lineGenerateTone }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } + case lGetAddressCaps: +#if TAPI_2_0 + case lGetAddressCapsW: +#endif + { + LPLINEADDRESSCAPS lpAddrCaps = (LPLINEADDRESSCAPS) pBigBuf; + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { szdwDeviceID, PT_DWORD, dwDefLineDeviceID, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { szdwAPIVersion, PT_ORDINAL, dwDefLineAPIVersion, aAPIVersions }, + { "dwExtVersion", PT_DWORD, dwDefLineExtVersion, NULL }, + { "lpAddressCaps", PT_POINTER, (DWORD) lpAddrCaps, lpAddrCaps } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 6, funcIndex, params, (funcIndex == lGetAddressCaps ? + (PFN6) lineGetAddressCaps : (PFN6) lineGetAddressCapsW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 6, funcIndex, params, (PFN6) lineGetAddressCaps }; +#endif + + CHK_LINEAPP_SELECTED() + + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + + memset (lpAddrCaps, 0, (size_t) dwBigBufSize); + + lpAddrCaps->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpAddrCaps); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + STRUCT_FIELD fields[] = + { + { "dwLineDeviceID", FT_DWORD, lpAddrCaps->dwLineDeviceID, NULL }, + { "dwAddressSize", FT_SIZE, lpAddrCaps->dwAddressSize, NULL }, + { "dwAddressOffset", FT_OFFSET, lpAddrCaps->dwAddressOffset, NULL }, + { "dwDevSpecificSize", FT_SIZE, lpAddrCaps->dwDevSpecificSize, NULL }, + { "dwDevSpecificOffset", FT_OFFSET, lpAddrCaps->dwDevSpecificOffset, NULL }, + { "dwAddressSharing", FT_FLAGS, lpAddrCaps->dwAddressSharing, aAddressSharing }, + { "dwAddressStates", FT_FLAGS, lpAddrCaps->dwAddressStates, aAddressStates }, + { "dwCallInfoStates", FT_FLAGS, lpAddrCaps->dwCallInfoStates, aCallInfoStates }, + { "dwCallerIDFlags", FT_FLAGS, lpAddrCaps->dwCallerIDFlags, aCallerIDFlags }, + { "dwCalledIDFlags", FT_FLAGS, lpAddrCaps->dwCalledIDFlags, aCallerIDFlags }, + { "dwConnectedIDFlags", FT_FLAGS, lpAddrCaps->dwConnectedIDFlags, aCallerIDFlags }, + { "dwRedirectionIDFlags", FT_FLAGS, lpAddrCaps->dwRedirectionIDFlags, aCallerIDFlags }, + { "dwRedirectingIDFlags", FT_FLAGS, lpAddrCaps->dwRedirectingIDFlags, aCallerIDFlags }, + { "dwCallStates", FT_FLAGS, lpAddrCaps->dwCallStates, aCallStates }, + { "dwDialToneModes", FT_FLAGS, lpAddrCaps->dwDialToneModes, aDialToneModes }, + { "dwBusyModes", FT_FLAGS, lpAddrCaps->dwBusyModes, aBusyModes }, + { "dwSpecialInfo", FT_FLAGS, lpAddrCaps->dwSpecialInfo, aSpecialInfo }, + { "dwDisconnectModes", FT_FLAGS, lpAddrCaps->dwDisconnectModes, aDisconnectModes }, + { "dwMaxNumActiveCalls", FT_DWORD, lpAddrCaps->dwMaxNumActiveCalls, NULL }, + { "dwMaxNumOnHoldCalls", FT_DWORD, lpAddrCaps->dwMaxNumOnHoldCalls, NULL }, + { "dwMaxNumOnHoldPendingCalls", FT_DWORD, lpAddrCaps->dwMaxNumOnHoldPendingCalls, NULL }, + { "dwMaxNumConference", FT_DWORD, lpAddrCaps->dwMaxNumConference, NULL }, + { "dwMaxNumTransConf", FT_DWORD, lpAddrCaps->dwMaxNumTransConf, NULL }, + { "dwAddrCapFlags", FT_FLAGS, lpAddrCaps->dwAddrCapFlags, aAddressCapFlags }, + { "dwCallFeatures", FT_FLAGS, lpAddrCaps->dwCallFeatures, aCallFeatures }, + { "dwRemoveFromConfCaps", FT_FLAGS, lpAddrCaps->dwRemoveFromConfCaps, aRemoveFromConfCaps }, + { "dwRemoveFromConfState", FT_FLAGS, lpAddrCaps->dwRemoveFromConfState, aCallStates }, + { "dwTransferModes", FT_FLAGS, lpAddrCaps->dwTransferModes, aTransferModes }, + { "dwParkModes", FT_FLAGS, lpAddrCaps->dwParkModes, aParkModes }, + { "dwForwardModes", FT_FLAGS, lpAddrCaps->dwForwardModes, aForwardModes }, + { "dwMaxForwardEntries", FT_DWORD, lpAddrCaps->dwMaxForwardEntries, NULL }, + { "dwMaxSpecificEntries", FT_DWORD, lpAddrCaps->dwMaxSpecificEntries, NULL }, + { "dwMinFwdNumRings", FT_DWORD, lpAddrCaps->dwMinFwdNumRings, NULL }, + { "dwMaxFwdNumRings", FT_DWORD, lpAddrCaps->dwMaxFwdNumRings, NULL }, + { "dwMaxCallCompletions", FT_DWORD, lpAddrCaps->dwMaxCallCompletions, NULL }, + { "dwCallCompletionConds", FT_FLAGS, lpAddrCaps->dwCallCompletionConds, aCallComplConds }, + { "dwCallCompletionModes", FT_FLAGS, lpAddrCaps->dwCallCompletionModes, aCallComplModes }, + { "dwNumCompletionMessages", FT_DWORD, lpAddrCaps->dwNumCompletionMessages, NULL }, + { "dwCompletionMsgTextEntrySize", FT_DWORD, lpAddrCaps->dwCompletionMsgTextEntrySize, NULL }, + { "dwCompletionMsgTextSize", FT_SIZE, lpAddrCaps->dwCompletionMsgTextSize, NULL }, + { "dwCompletionMsgTextOffset", FT_OFFSET, lpAddrCaps->dwCompletionMsgTextOffset, NULL } +#if TAPI_1_1 + , + { "dwAddressFeatures", FT_FLAGS, 0, aAddressFeatures } +#if TAPI_2_0 + , + { "dwPredictiveAutoTransferStates", FT_FLAGS, 0, aCallStates }, + { "dwNumCallTreatments", FT_DWORD, 0, NULL }, + { "dwCallTreatmentListSize", FT_SIZE, 0, NULL }, + { "dwCallTreatmentListOffset", FT_OFFSET, 0, NULL }, + { "dwDeviceClassesSize", FT_SIZE, 0, NULL }, + { "dwDeviceClassesOffset", FT_OFFSET, 0, NULL }, + { "dwMaxCallDataSize", FT_DWORD, 0, NULL }, + { "dwCallFeatures2", FT_FLAGS, 0, aCallFeatures2 }, + { "dwMaxNoAnswerTimeout", FT_DWORD, 0, NULL }, + { "dwConnectedModes", FT_FLAGS, 0, aConnectedModes }, + { "dwOfferingModes", FT_FLAGS, 0, aOfferingModes }, + { "dwAvailableMediaModes", FT_FLAGS, 0, aMediaModes } +#endif +#endif + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpAddrCaps, "LINEADDRESSCAPS", 0, fields + }; + + + if (params[3].dwValue == 0x10003) + { + // + // Only show ver 1.0 params + // + + fieldHeader.dwNumFields = 41; + } +#if TAPI_1_1 + else if (params[3].dwValue == 0x10004) + { + // + // Only show <= ver 1.4 params + // + + fieldHeader.dwNumFields = 42; + + fields[41].dwValue = lpAddrCaps->dwAddressFeatures; + } +#if TAPI_2_0 + else + { + // + // Only show <= ver 2.0 params + // + + fieldHeader.dwNumFields = 54; + + fields[41].dwValue = lpAddrCaps->dwAddressFeatures; + fields[42].dwValue = lpAddrCaps->dwPredictiveAutoTransferStates; + fields[43].dwValue = lpAddrCaps->dwNumCallTreatments; + fields[44].dwValue = lpAddrCaps->dwCallTreatmentListSize; + fields[45].dwValue = lpAddrCaps->dwCallTreatmentListOffset; + fields[46].dwValue = lpAddrCaps->dwDeviceClassesSize; + fields[47].dwValue = lpAddrCaps->dwDeviceClassesOffset; + fields[48].dwValue = lpAddrCaps->dwMaxCallDataSize; + fields[49].dwValue = lpAddrCaps->dwCallFeatures2; + fields[50].dwValue = lpAddrCaps->dwMaxNoAnswerTimeout; + fields[51].dwValue = lpAddrCaps->dwConnectedModes; + fields[52].dwValue = lpAddrCaps->dwOfferingModes; + fields[53].dwValue = lpAddrCaps->dwAvailableMediaModes; + } +#endif +#endif + ShowStructByField (&fieldHeader, FALSE); + } + } + + break; + } + case lGetAddressID: +#if TAPI_2_0 + case lGetAddressIDW: +#endif + { + DWORD dwAddressID; + char szAddress[MAX_STRING_PARAM_SIZE] = "0"; + LPLINEADDRESSCAPS lpAddrCaps = (LPLINEADDRESSCAPS) pBigBuf; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { "lpdwAddressID", PT_POINTER, (DWORD) &dwAddressID, &dwAddressID }, + { "dwAddressMode", PT_FLAGS, LINEADDRESSMODE_DIALABLEADDR, aAddressModes }, + { "lpsAddress", PT_STRING, (DWORD) szAddress, szAddress }, + { szdwSize, PT_DWORD, 2, NULL } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (funcIndex == lGetAddressID ? + (PFN5) lineGetAddressID : (PFN5) lineGetAddressIDW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) lineGetAddressID }; +#endif + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStr ("%s%s=x%lx", szTab, szdwAddressID, dwAddressID); + } + + break; + } + case lGetAddressStatus: +#if TAPI_2_0 + case lGetAddressStatusW: +#endif + { + LPLINEADDRESSSTATUS lpAddrStatus = (LPLINEADDRESSSTATUS) pBigBuf; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { "lpAddressCaps", PT_POINTER, (DWORD) lpAddrStatus, lpAddrStatus } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lGetAddressStatus ? + (PFN3) lineGetAddressStatus : (PFN3) lineGetAddressStatusW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineGetAddressStatus }; +#endif + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + memset (lpAddrStatus, 0, (size_t) dwBigBufSize); + lpAddrStatus->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpAddrStatus); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + STRUCT_FIELD fields[] = + { + { "dwNumInUse", FT_DWORD, lpAddrStatus->dwNumInUse, NULL }, + { "dwNumActiveCalls", FT_DWORD, lpAddrStatus->dwNumActiveCalls, NULL }, + { "dwNumOnHoldCalls", FT_DWORD, lpAddrStatus->dwNumOnHoldCalls, NULL }, + { "dwNumOnHoldPendCalls", FT_DWORD, lpAddrStatus->dwNumOnHoldPendCalls, NULL }, + { "dwAddressFeatures", FT_FLAGS, lpAddrStatus->dwAddressFeatures, aAddressFeatures }, + { "dwNumRingsNoAnswer", FT_DWORD, lpAddrStatus->dwNumRingsNoAnswer, NULL }, + { "dwForwardNumEntries", FT_DWORD, lpAddrStatus->dwForwardNumEntries, NULL }, + { "dwForwardSize", FT_SIZE, lpAddrStatus->dwForwardSize, NULL }, + { "dwForwardOffset", FT_OFFSET, lpAddrStatus->dwForwardOffset, NULL }, + { "dwTerminalModesSize", FT_SIZE, lpAddrStatus->dwTerminalModesSize, NULL }, + { "dwTerminalModesOffset", FT_OFFSET, lpAddrStatus->dwTerminalModesOffset, NULL }, + { "dwDevSpecificSize", FT_SIZE, lpAddrStatus->dwDevSpecificSize, NULL }, + { "dwDevSpecificOffset", FT_OFFSET, lpAddrStatus->dwDevSpecificOffset, NULL } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpAddrStatus, + "LINEADDRESSSTATUS", + 13, + fields + }; + + ShowStructByField (&fieldHeader, FALSE); + } + } + + break; + } +#if TAPI_2_0 + case lGetAgentActivityList: + case lGetAgentActivityListW: + { + LPLINEAGENTACTIVITYLIST lpActivityList = (LPLINEAGENTACTIVITYLIST) + pBigBuf; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { "lpAgentActivityList", PT_POINTER, (DWORD) lpActivityList, lpActivityList } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lGetAgentActivityList ? + (PFN3) lineGetAgentActivityList : + (PFN3) lineGetAgentActivityListW) }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + memset (lpActivityList, 0, (size_t) dwBigBufSize); + lpActivityList->dwTotalSize = dwBigBufSize; + + lResult = DoFunc (¶msHeader); + +// BUGBUG dump agent activity list on successful async completion + + break; + } + case lGetAgentCaps: + { + LPLINEAGENTCAPS lpAgentCaps = (LPLINEAGENTCAPS) pBigBuf; + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { szdwDeviceID, PT_DWORD, dwDefLineDeviceID, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { szdwAPIVersion, PT_ORDINAL, dwDefLineAPIVersion, aAPIVersions }, + { "lpAgentCaps", PT_POINTER, (DWORD) lpAgentCaps, lpAgentCaps } + }; + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) lineGetAgentCaps }; + + + CHK_LINEAPP_SELECTED() + + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + + memset (lpAgentCaps, 0, (size_t) dwBigBufSize); + lpAgentCaps->dwTotalSize = dwBigBufSize; + + lResult = DoFunc (¶msHeader); + +// BUGBUG dump agent caps on successful async completion + + break; + } + case lGetAgentGroupList: + { + LPLINEAGENTGROUPLIST lpGroupList = (LPLINEAGENTGROUPLIST) pBigBuf; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { "lpAgentGroupList", PT_POINTER, (DWORD) lpGroupList, lpGroupList } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineGetAgentGroupList }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + memset (lpGroupList, 0, (size_t) dwBigBufSize); + lpGroupList->dwTotalSize = dwBigBufSize; + + lResult = DoFunc (¶msHeader); + +// BUGBUG dump agent group list on successful async completion + + break; + } + case lGetAgentStatus: + { + LPLINEAGENTSTATUS lpStatus = (LPLINEAGENTSTATUS) pBigBuf; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { "lpAgentStatus", PT_POINTER, (DWORD) lpStatus, lpStatus } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineGetAgentStatus }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + memset (lpStatus, 0, (size_t) dwBigBufSize); + lpStatus->dwTotalSize = dwBigBufSize; + + lResult = DoFunc (¶msHeader); + +// BUGBUG dump agent status on successful async completion + + break; + } +#endif + case lGetCallInfo: +#if TAPI_2_0 + case lGetCallInfoW: +#endif + { + LPLINECALLINFO lpCallInfo = (LPLINECALLINFO) pBigBuf; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "lpCallInfo", PT_POINTER, (DWORD) lpCallInfo, lpCallInfo } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (funcIndex == lGetCallInfo ? + (PFN2) lineGetCallInfo : (PFN2) lineGetCallInfoW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineGetCallInfo }; +#endif + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + memset (lpCallInfo, 0x5a, (size_t) dwBigBufSize); + lpCallInfo->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpCallInfo); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + STRUCT_FIELD fields[] = + { + { szhLine, FT_DWORD, (DWORD)lpCallInfo->hLine, NULL }, + { "dwLineDeviceID", FT_DWORD, lpCallInfo->dwLineDeviceID, NULL }, + { szdwAddressID, FT_DWORD, lpCallInfo->dwAddressID, NULL }, + { "dwBearerMode", FT_FLAGS, lpCallInfo->dwBearerMode, aBearerModes }, + { "dwRate", FT_DWORD, lpCallInfo->dwRate, NULL }, + { "dwMediaMode", FT_FLAGS, lpCallInfo->dwMediaMode, aMediaModes }, + { "dwAppSpecific", FT_DWORD, lpCallInfo->dwAppSpecific, NULL }, + { "dwCallID", FT_DWORD, lpCallInfo->dwCallID, NULL }, + { "dwRelatedCallID", FT_DWORD, lpCallInfo->dwRelatedCallID, NULL }, + { "dwCallParamFlags", FT_FLAGS, lpCallInfo->dwCallParamFlags, aCallParamFlags }, + { "dwCallStates", FT_FLAGS, lpCallInfo->dwCallStates, aCallStates }, + { "dwMonitorDigitModes", FT_FLAGS, lpCallInfo->dwMonitorDigitModes, aDigitModes }, + { "dwMonitorMediaModes", FT_FLAGS, lpCallInfo->dwMonitorMediaModes, aMediaModes }, + { "DialParams.dwDialPause", FT_DWORD, lpCallInfo->DialParams.dwDialPause, NULL }, + { "DialParams.dwDialSpeed", FT_DWORD, lpCallInfo->DialParams.dwDialSpeed, NULL }, + { "DialParams.dwDigitDuration", FT_DWORD, lpCallInfo->DialParams.dwDigitDuration, NULL }, + { "DialParams.dwWaitForDialtone", FT_DWORD, lpCallInfo->DialParams.dwWaitForDialtone, NULL }, + { "dwOrigin", FT_FLAGS, lpCallInfo->dwOrigin, aCallOrigins }, + { "dwReason", FT_FLAGS, lpCallInfo->dwReason, aCallReasons }, + { "dwCompletionID", FT_DWORD, lpCallInfo->dwCompletionID, NULL }, + { "dwNumOwners", FT_DWORD, lpCallInfo->dwNumOwners, NULL }, + { "dwNumMonitors", FT_DWORD, lpCallInfo->dwNumMonitors, NULL }, + { "dwCountryCode", FT_DWORD, lpCallInfo->dwCountryCode, NULL }, + { "dwTrunk", FT_DWORD, lpCallInfo->dwTrunk, NULL }, + { "dwCallerIDFlags", FT_FLAGS, lpCallInfo->dwCallerIDFlags, aCallerIDFlags }, + { "dwCallerIDSize", FT_SIZE, lpCallInfo->dwCallerIDSize, NULL }, + { "dwCallerIDOffset", FT_OFFSET, lpCallInfo->dwCallerIDOffset, NULL }, + { "dwCallerIDNameSize", FT_SIZE, lpCallInfo->dwCallerIDNameSize, NULL }, + { "dwCallerIDNameOffset", FT_OFFSET, lpCallInfo->dwCallerIDNameOffset, NULL }, + { "dwCalledIDFlags", FT_FLAGS, lpCallInfo->dwCalledIDFlags, aCallerIDFlags }, + { "dwCalledIDSize", FT_SIZE, lpCallInfo->dwCalledIDSize, NULL }, + { "dwCalledIDOffset", FT_OFFSET, lpCallInfo->dwCalledIDOffset, NULL }, + { "dwCalledIDNameSize", FT_SIZE, lpCallInfo->dwCalledIDNameSize, NULL }, + { "dwCalledIDNameOffset", FT_OFFSET, lpCallInfo->dwCalledIDNameOffset, NULL }, + { "dwConnectedIDFlags", FT_FLAGS, lpCallInfo->dwConnectedIDFlags, aCallerIDFlags }, + { "dwConnectedIDSize", FT_SIZE, lpCallInfo->dwConnectedIDSize, NULL }, + { "dwConnectedIDOffset", FT_OFFSET, lpCallInfo->dwConnectedIDOffset, NULL }, + { "dwConnectedIDNameSize", FT_SIZE, lpCallInfo->dwConnectedIDNameSize, NULL }, + { "dwConnectedIDNameOffset", FT_OFFSET, lpCallInfo->dwConnectedIDNameOffset, NULL }, + { "dwRedirectionIDFlags", FT_FLAGS, lpCallInfo->dwRedirectionIDFlags, aCallerIDFlags }, + { "dwRedirectionIDSize", FT_SIZE, lpCallInfo->dwRedirectionIDSize, NULL }, + { "dwRedirectionIDOffset", FT_OFFSET, lpCallInfo->dwRedirectionIDOffset, NULL }, + { "dwRedirectionIDNameSize", FT_SIZE, lpCallInfo->dwRedirectionIDNameSize, NULL }, + { "dwRedirectionIDNameOffset", FT_OFFSET, lpCallInfo->dwRedirectionIDNameOffset, NULL }, + { "dwRedirectingIDFlags", FT_FLAGS, lpCallInfo->dwRedirectingIDFlags, aCallerIDFlags }, + { "dwRedirectingIDSize", FT_SIZE, lpCallInfo->dwRedirectingIDSize, NULL }, + { "dwRedirectingIDOffset", FT_OFFSET, lpCallInfo->dwRedirectingIDOffset, NULL }, + { "dwRedirectingIDNameSize", FT_SIZE, lpCallInfo->dwRedirectingIDNameSize, NULL }, + { "dwRedirectingIDNameOffset", FT_OFFSET, lpCallInfo->dwRedirectingIDNameOffset, NULL }, + { "dwAppNameSize", FT_SIZE, lpCallInfo->dwAppNameSize, NULL }, + { "dwAppNameOffset", FT_OFFSET, lpCallInfo->dwAppNameOffset, NULL }, + { "dwDisplayableAddressSize", FT_SIZE, lpCallInfo->dwDisplayableAddressSize, NULL }, + { "dwDisplayableAddressOffset", FT_OFFSET, lpCallInfo->dwDisplayableAddressOffset, NULL }, + { "dwCalledPartySize", FT_SIZE, lpCallInfo->dwCalledPartySize, NULL }, + { "dwCalledPartyOffset", FT_OFFSET, lpCallInfo->dwCalledPartyOffset, NULL }, + { "dwCommentSize", FT_SIZE, lpCallInfo->dwCommentSize, NULL }, + { "dwCommentOffset", FT_OFFSET, lpCallInfo->dwCommentOffset, NULL }, + { "dwDisplaySize", FT_SIZE, lpCallInfo->dwDisplaySize, NULL }, + { "dwDisplayOffset", FT_OFFSET, lpCallInfo->dwDisplayOffset, NULL }, + { "dwUserUserInfoSize", FT_SIZE, lpCallInfo->dwUserUserInfoSize, NULL }, + { "dwUserUserInfoOffset", FT_OFFSET, lpCallInfo->dwUserUserInfoOffset, NULL }, + { "dwHighLevelCompSize", FT_SIZE, lpCallInfo->dwHighLevelCompSize, NULL }, + { "dwHighLevelCompOffset", FT_OFFSET, lpCallInfo->dwHighLevelCompOffset, NULL }, + { "dwLowLevelCompSize", FT_SIZE, lpCallInfo->dwLowLevelCompSize, NULL }, + { "dwLowLevelCompOffset", FT_OFFSET, lpCallInfo->dwLowLevelCompOffset, NULL }, + { "dwChargingInfoSize", FT_SIZE, lpCallInfo->dwChargingInfoSize, NULL }, + { "dwChargingInfoOffset", FT_OFFSET, lpCallInfo->dwChargingInfoOffset, NULL }, + { "dwTerminalModesSize", FT_SIZE, lpCallInfo->dwTerminalModesSize, NULL }, + { "dwTerminalModesOffset", FT_OFFSET, lpCallInfo->dwTerminalModesOffset, NULL }, + { "dwDevSpecificSize", FT_SIZE, lpCallInfo->dwDevSpecificSize, NULL }, + { "dwDevSpecificOffset", FT_OFFSET, lpCallInfo->dwDevSpecificOffset, NULL } +#if TAPI_2_0 + , + { "dwCallTreatment", FT_DWORD, 0, NULL }, + { "dwCallDataSize", FT_SIZE, 0, NULL }, + { "dwCallDataOffset", FT_OFFSET, 0, NULL }, + { "dwSendingFlowspecSize", FT_SIZE, 0, NULL }, + { "dwSendingFlowspecOffset", FT_OFFSET, 0, NULL }, + { "dwReceivingFlowspecSize", FT_SIZE, 0, NULL }, + { "dwReceivingFlowspecOffset", FT_OFFSET, 0, NULL } +#endif + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpCallInfo, "LINECALLINFO", 0, fields + }; + + + if (pLineSel->dwAPIVersion < 0x00020000) + { + // + // Only show ver 1.0 params + // + + fieldHeader.dwNumFields = 71; + } +#if TAPI_2_0 + else + { + fieldHeader.dwNumFields = 78; + + fields[71].dwValue = lpCallInfo->dwCallTreatment; + fields[72].dwValue = lpCallInfo->dwCallDataSize; + fields[73].dwValue = lpCallInfo->dwCallDataOffset; + fields[74].dwValue = lpCallInfo->dwSendingFlowspecSize; + fields[75].dwValue = lpCallInfo->dwSendingFlowspecOffset; + fields[76].dwValue = lpCallInfo->dwReceivingFlowspecSize; + fields[77].dwValue = lpCallInfo->dwReceivingFlowspecOffset; + } +#endif + ShowStructByField (&fieldHeader, FALSE); + } + } + + break; + } + case lGetCallStatus: + { + LPLINECALLSTATUS lpCallStatus = (LPLINECALLSTATUS) pBigBuf; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "lpCallStatus", PT_POINTER, (DWORD) lpCallStatus, lpCallStatus } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineGetCallStatus }; + DWORD dwAPIVersion; + + + CHK_CALL_SELECTED() + + dwAPIVersion = pLineSel->dwAPIVersion; + + params[0].dwValue = (DWORD) pCallSel->hCall; + + memset (lpCallStatus, 0, (size_t) dwBigBufSize); + lpCallStatus->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpCallStatus); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + STRUCT_FIELD fields[] = + { + { "dwCallState", FT_FLAGS, lpCallStatus->dwCallState, aCallStates }, + { "dwCallStateMode", FT_FLAGS, lpCallStatus->dwCallStateMode, NULL }, + { "dwCallPrivilege", FT_FLAGS, lpCallStatus->dwCallPrivilege, aCallPrivileges }, + { "dwCallFeatures", FT_FLAGS, lpCallStatus->dwCallFeatures, aCallFeatures }, + { "dwDevSpecificSize", FT_SIZE, lpCallStatus->dwDevSpecificSize, NULL }, + { "dwDevSpecificOffset", FT_OFFSET, lpCallStatus->dwDevSpecificOffset, NULL } +#if TAPI_2_0 + , + { "dwCallFeatures2", FT_FLAGS, 0, aCallFeatures2 }, + { "tStateEntryTime[0]", FT_DWORD, 0, NULL }, + { "tStateEntryTime[1]", FT_DWORD, 0, NULL }, + { "tStateEntryTime[2]", FT_DWORD, 0, NULL }, + { "tStateEntryTime[3]", FT_DWORD, 0, NULL } +#endif + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpCallStatus, "LINECALLSTATUS", 0, fields + }; + + + switch (lpCallStatus->dwCallState) + { + case LINECALLSTATE_DIALTONE: + + fields[1].pLookup = aDialToneModes; + break; + + case LINECALLSTATE_BUSY: + + fields[1].pLookup = aBusyModes; + break; + + case LINECALLSTATE_SPECIALINFO: + + fields[1].pLookup = aSpecialInfo; + break; + + case LINECALLSTATE_DISCONNECTED: + + fields[1].pLookup = aDisconnectModes; + break; + + default: + + fields[1].dwType = FT_DWORD; + break; + } + + if (dwAPIVersion < 0x00020000) + { + fieldHeader.dwNumFields = 6; + } +#if TAPI_2_0 + else + { + fieldHeader.dwNumFields = 11; + + fields[6].dwValue = lpCallStatus->dwCallFeatures2; + fields[7].dwValue = *((LPDWORD) &lpCallStatus->tStateEntryTime); + fields[8].dwValue = *(((LPDWORD) &lpCallStatus->tStateEntryTime) + 1); + fields[9].dwValue = *(((LPDWORD) &lpCallStatus->tStateEntryTime) + 2); + fields[10].dwValue = *(((LPDWORD) &lpCallStatus->tStateEntryTime) + 3); + } +#endif + ShowStructByField (&fieldHeader, FALSE); + } + } + + break; + } + case lGetConfRelatedCalls: + { + LPLINECALLLIST lpCallList = (LPLINECALLLIST) pBigBuf; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "lpCallList", PT_POINTER, (DWORD) lpCallList, lpCallList } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineGetConfRelatedCalls }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + memset (lpCallList, 0, (size_t) dwBigBufSize); + lpCallList->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpCallList); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + STRUCT_FIELD fields[] = + { + { "dwCallsNumEntries", FT_DWORD, lpCallList->dwCallsNumEntries, NULL }, + { "dwCallsSize", FT_SIZE, lpCallList->dwCallsSize, NULL }, + { "dwCallsOffset", FT_OFFSET, lpCallList->dwCallsOffset, NULL } + + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpCallList, + "LINECALLLIST", + 3, + fields + }; + + ShowStructByField (&fieldHeader, FALSE); + } + } + + break; + } + case lGetDevCaps: +#if TAPI_2_0 + case lGetDevCapsW: +#endif + { + LPLINEDEVCAPS lpDevCaps = (LPLINEDEVCAPS) pBigBuf; + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { szdwDeviceID, PT_DWORD, dwDefLineDeviceID, NULL }, + { szdwAPIVersion, PT_ORDINAL, dwDefLineAPIVersion, aAPIVersions }, + { "dwExtVersion", PT_DWORD, dwDefLineExtVersion, NULL }, + { "lpLineDevCaps", PT_POINTER, (DWORD) lpDevCaps, lpDevCaps } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (funcIndex == lGetDevCaps ? + (PFN5) lineGetDevCaps : (PFN5) lineGetDevCapsW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) lineGetDevCaps }; +#endif + + CHK_LINEAPP_SELECTED() + + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + + memset (lpDevCaps, 0, (size_t) dwBigBufSize); + lpDevCaps->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpDevCaps); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + STRUCT_FIELD fields[] = + { + { "dwProviderInfoSize", FT_SIZE, lpDevCaps->dwProviderInfoSize, NULL }, + { "dwProviderInfoOffset", FT_OFFSET, lpDevCaps->dwProviderInfoOffset, NULL }, + { "dwSwitchInfoSize", FT_SIZE, lpDevCaps->dwSwitchInfoSize, NULL }, + { "dwSwitchInfoOffset", FT_OFFSET, lpDevCaps->dwSwitchInfoOffset, NULL }, + { "dwPermanentLineID", FT_DWORD, lpDevCaps->dwPermanentLineID, NULL }, + { "dwLineNameSize", FT_SIZE, lpDevCaps->dwLineNameSize, NULL }, + { "dwLineNameOffset", FT_OFFSET, lpDevCaps->dwLineNameOffset, NULL }, + { "dwStringFormat", FT_ORD, lpDevCaps->dwStringFormat, aStringFormats }, + { "dwAddressModes", FT_FLAGS, lpDevCaps->dwAddressModes, aAddressModes }, + { "dwNumAddresses", FT_DWORD, lpDevCaps->dwNumAddresses, NULL }, + { "dwBearerModes", FT_FLAGS, lpDevCaps->dwBearerModes, aBearerModes }, + { "dwMaxRate", FT_DWORD, lpDevCaps->dwMaxRate, NULL }, + { "dwMediaModes", FT_FLAGS, lpDevCaps->dwMediaModes, aMediaModes }, + { "dwGenerateToneModes", FT_FLAGS, lpDevCaps->dwGenerateToneModes, aToneModes }, + { "dwGenerateToneMaxNumFreq", FT_DWORD, lpDevCaps->dwGenerateToneMaxNumFreq, NULL }, + { "dwGenerateDigitModes", FT_FLAGS, lpDevCaps->dwGenerateDigitModes, aDigitModes }, + { "dwMonitorToneMaxNumFreq", FT_DWORD, lpDevCaps->dwMonitorToneMaxNumFreq, NULL }, + { "dwMonitorToneMaxNumEntries", FT_DWORD, lpDevCaps->dwMonitorToneMaxNumEntries, NULL }, + { "dwMonitorDigitModes", FT_FLAGS, lpDevCaps->dwMonitorDigitModes, aDigitModes }, + { "dwGatherDigitsMinTimeout", FT_DWORD, lpDevCaps->dwGatherDigitsMinTimeout, NULL }, + { "dwGatherDigitsMaxTimeout", FT_DWORD, lpDevCaps->dwGatherDigitsMaxTimeout, NULL }, + { "dwMedCtlDigitMaxListSize", FT_DWORD, lpDevCaps->dwMedCtlDigitMaxListSize, NULL }, + { "dwMedCtlMediaMaxListSize", FT_DWORD, lpDevCaps->dwMedCtlMediaMaxListSize, NULL }, + { "dwMedCtlToneMaxListSize", FT_DWORD, lpDevCaps->dwMedCtlToneMaxListSize, NULL }, + { "dwMedCtlCallStateMaxListSize", FT_DWORD, lpDevCaps->dwMedCtlCallStateMaxListSize, NULL }, + { "dwDevCapFlags", FT_FLAGS, lpDevCaps->dwDevCapFlags, aDevCapsFlags }, + { "dwMaxNumActiveCalls", FT_DWORD, lpDevCaps->dwMaxNumActiveCalls, NULL }, + { "dwAnswerMode", FT_FLAGS, lpDevCaps->dwAnswerMode, aAnswerModes }, + { "dwRingModes", FT_DWORD, lpDevCaps->dwRingModes, NULL }, + { "dwLineStates", FT_FLAGS, lpDevCaps->dwLineStates, aLineStates }, + { "dwUUIAcceptSize", FT_DWORD, lpDevCaps->dwUUIAcceptSize, NULL }, + { "dwUUIAnswerSize", FT_DWORD, lpDevCaps->dwUUIAnswerSize, NULL }, + { "dwUUIMakeCallSize", FT_DWORD, lpDevCaps->dwUUIMakeCallSize, NULL }, + { "dwUUIDropSize", FT_DWORD, lpDevCaps->dwUUIDropSize, NULL }, + { "dwUUISendUserUserInfoSize", FT_DWORD, lpDevCaps->dwUUISendUserUserInfoSize, NULL }, + { "dwUUICallInfoSize", FT_DWORD, lpDevCaps->dwUUICallInfoSize, NULL }, + { "MinDialParams.dwDialPause", FT_DWORD, lpDevCaps->MinDialParams.dwDialPause, NULL }, + { "MinDialParams.dwDialSpeed", FT_DWORD, lpDevCaps->MinDialParams.dwDialSpeed, NULL }, + { "MinDialParams.dwDigitDuration", FT_DWORD, lpDevCaps->MinDialParams.dwDigitDuration, NULL }, + { "MinDialParams.dwWaitForDialtone", FT_DWORD, lpDevCaps->MinDialParams.dwWaitForDialtone, NULL }, + { "MaxDialParams.dwDialPause", FT_DWORD, lpDevCaps->MaxDialParams.dwDialPause, NULL }, + { "MaxDialParams.dwDialSpeed", FT_DWORD, lpDevCaps->MaxDialParams.dwDialSpeed, NULL }, + { "MaxDialParams.dwDigitDuration", FT_DWORD, lpDevCaps->MaxDialParams.dwDigitDuration, NULL }, + { "MaxDialParams.dwWaitForDialtone", FT_DWORD, lpDevCaps->MaxDialParams.dwWaitForDialtone, NULL }, + { "DefDialParams.dwDialPause", FT_DWORD, lpDevCaps->DefaultDialParams.dwDialPause, NULL }, + { "DefDialParams.dwDialSpeed", FT_DWORD, lpDevCaps->DefaultDialParams.dwDialSpeed, NULL }, + { "DefDialParams.dwDigitDuration", FT_DWORD, lpDevCaps->DefaultDialParams.dwDigitDuration, NULL }, + { "DefDialParams.dwWaitForDialtone", FT_DWORD, lpDevCaps->DefaultDialParams.dwWaitForDialtone, NULL }, + { "dwNumTerminals", FT_DWORD, lpDevCaps->dwNumTerminals, NULL }, + { "dwTerminalCapsSize", FT_SIZE, lpDevCaps->dwTerminalCapsSize, NULL }, + { "dwTerminalCapsOffset", FT_OFFSET, lpDevCaps->dwTerminalCapsOffset, NULL }, + { "dwTerminalTextEntrySize", FT_DWORD, lpDevCaps->dwTerminalTextEntrySize, NULL }, + { "dwTerminalTextSize", FT_SIZE, lpDevCaps->dwTerminalTextSize, NULL }, + { "dwTerminalTextOffset", FT_OFFSET, lpDevCaps->dwTerminalTextOffset, NULL }, + { "dwDevSpecificSize", FT_SIZE, lpDevCaps->dwDevSpecificSize, NULL }, + { "dwDevSpecificOffset", FT_OFFSET, lpDevCaps->dwDevSpecificOffset, NULL } +#if TAPI_1_1 + , + { "dwLineFeatures", FT_FLAGS, 0, aLineFeatures } +#if TAPI_2_0 + , + { "dwSettableDevStatus", FT_FLAGS, 0, aLineDevStatusFlags }, + { "dwDeviceClassesSize", FT_SIZE, 0, NULL }, + { "dwDeviceClassesOffset", FT_OFFSET, 0, NULL } +#endif +#endif + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpDevCaps, "LINEDEVCAPS", 0, fields + }; + + if (params[2].dwValue == 0x10003) + { + // + // Only show ver 1.0 params + // + + fieldHeader.dwNumFields = 56; + } +#if TAPI_1_1 + else if (params[2].dwValue == 0x10004) + { + // + // Only show <= ver 1.1 params + // + + fieldHeader.dwNumFields = 57; + + fields[56].dwValue = lpDevCaps->dwLineFeatures; + } +#if TAPI_2_0 + else + { + // + // Only show <= ver 2.0 params + // + + fieldHeader.dwNumFields = 60; + + fields[56].dwValue = lpDevCaps->dwLineFeatures; + fields[57].dwValue = lpDevCaps->dwSettableDevStatus; + fields[58].dwValue = lpDevCaps->dwDeviceClassesSize; + fields[59].dwValue = lpDevCaps->dwDeviceClassesOffset; + } +#endif +#endif + + ShowStructByField (&fieldHeader, FALSE); + } + } + + break; + } + case lGetDevConfig: +#if TAPI_2_0 + case lGetDevConfigW: +#endif + { + char szDeviceClass[MAX_STRING_PARAM_SIZE]; + LPVARSTRING lpDevConfig = (LPVARSTRING) pBigBuf; + FUNC_PARAM params[] = + { + { szdwDeviceID, PT_DWORD, dwDefLineDeviceID, NULL }, + { "lpDeviceConfig", PT_POINTER, (DWORD) lpDevConfig, lpDevConfig }, + { szlpszDeviceClass, PT_STRING, (DWORD) szDeviceClass, szDeviceClass } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lGetDevConfig ? + (PFN3) lineGetDevConfig : (PFN3) lineGetDevConfigW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineGetDevConfig }; +#endif + + memset (lpDevConfig, 0, (size_t) dwBigBufSize); + lpDevConfig->dwTotalSize = dwBigBufSize; + + strcpy (szDeviceClass, szDefLineDeviceClass); + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpDevConfig); + + ShowVARSTRING (lpDevConfig); + } + + break; + } + case lGetIcon: +#if TAPI_2_0 + case lGetIconW: +#endif + { + char szDeviceClass[MAX_STRING_PARAM_SIZE] = ""; + HICON hIcon; + FUNC_PARAM params[] = + { + { szdwDeviceID, PT_DWORD, dwDefLineDeviceID, NULL }, + { szlpszDeviceClass, PT_STRING, (DWORD) szDeviceClass, szDeviceClass }, + { "lphIcon", PT_POINTER, (DWORD) &hIcon, &hIcon } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lGetIcon ? + (PFN3) lineGetIcon : (PFN3) lineGetIconW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineGetIcon }; +#endif + + strcpy (szDeviceClass, szDefLineDeviceClass); + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + DialogBoxParam ( + ghInst, + (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG5), + (HWND) ghwndMain, + (DLGPROC) IconDlgProc, + (LPARAM) hIcon + ); + } + + break; + } + case lGetID: +#if TAPI_2_0 + case lGetIDW: +#endif + { + char szDeviceClass[MAX_STRING_PARAM_SIZE]; + LPVARSTRING lpDevID = (LPVARSTRING) pBigBuf; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { szhCall, PT_DWORD, 0, NULL }, + { "dwSelect", PT_ORDINAL, LINECALLSELECT_LINE, aCallSelects }, + { "lpDeviceID", PT_POINTER, (DWORD) lpDevID, lpDevID }, + { szlpszDeviceClass, PT_STRING, (DWORD) szDeviceClass, szDeviceClass } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 6, funcIndex, params, (funcIndex == lGetID ? + (PFN6) lineGetID : (PFN6) lineGetIDW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 6, funcIndex, params, (PFN6) lineGetID }; +#endif + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + if (pCallSel) + { + params[2].dwValue = (DWORD) pCallSel->hCall; + params[3].dwValue = LINECALLSELECT_CALL; + } + else + { + params[3].dwValue = LINECALLSELECT_LINE; + } + + memset (lpDevID, 0, (size_t) dwBigBufSize); + lpDevID->dwTotalSize = dwBigBufSize; + + strcpy (szDeviceClass, szDefLineDeviceClass); + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpDevID); + + ShowVARSTRING (lpDevID); + } + + break; + } + case lGetLineDevStatus: +#if TAPI_2_0 + case lGetLineDevStatusW: +#endif + { + LPLINEDEVSTATUS lpDevStatus = (LPLINEDEVSTATUS) pBigBuf; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { "lpLineDevStatus", PT_POINTER, (DWORD) lpDevStatus, lpDevStatus } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (funcIndex == lGetLineDevStatus ? + (PFN2) lineGetLineDevStatus : (PFN2) lineGetLineDevStatusW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineGetLineDevStatus }; +#endif + DWORD dwAPIVersion; + + + CHK_LINE_SELECTED() + + dwAPIVersion = pLineSel->dwAPIVersion; + + params[0].dwValue = (DWORD) pLineSel->hLine; + + memset (lpDevStatus, 0, (size_t) dwBigBufSize); + lpDevStatus->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpDevStatus); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + STRUCT_FIELD fields[] = + { + { "dwNumOpens", FT_DWORD, lpDevStatus->dwNumOpens, NULL }, + { "dwOpenMediaModes", FT_FLAGS, lpDevStatus->dwOpenMediaModes, aMediaModes }, + { "dwNumActiveCalls", FT_DWORD, lpDevStatus->dwNumActiveCalls, NULL }, + { "dwNumOnHoldCalls", FT_DWORD, lpDevStatus->dwNumOnHoldCalls, NULL }, + { "dwNumOnHoldPendCalls", FT_DWORD, lpDevStatus->dwNumOnHoldPendCalls, NULL }, + { "dwLineFeatures", FT_FLAGS, lpDevStatus->dwLineFeatures, aLineFeatures }, + { "dwNumCallCompletions", FT_DWORD, lpDevStatus->dwNumCallCompletions, NULL }, + { "dwRingMode", FT_DWORD, lpDevStatus->dwRingMode, NULL }, + { "dwSignalLevel", FT_DWORD, lpDevStatus->dwSignalLevel, NULL }, + { "dwBatteryLevel", FT_DWORD, lpDevStatus->dwBatteryLevel, NULL }, + { "dwRoamMode", FT_FLAGS, lpDevStatus->dwRoamMode, aLineRoamModes }, + { "dwDevStatusFlags", FT_FLAGS, lpDevStatus->dwDevStatusFlags, aLineDevStatusFlags }, + { "dwTerminalModesSize", FT_SIZE, lpDevStatus->dwTerminalModesSize, NULL }, + { "dwTerminalModesOffset", FT_OFFSET, lpDevStatus->dwTerminalModesOffset, NULL }, + { "dwDevSpecificSize", FT_SIZE, lpDevStatus->dwDevSpecificSize, NULL }, + { "dwDevSpecificOffset", FT_OFFSET, lpDevStatus->dwDevSpecificOffset, NULL } +#if TAPI_2_0 + , + { "dwAvailableMediaModes", FT_FLAGS, 0, aMediaModes }, + { "dwAppInfoSize", FT_DWORD, 0, NULL }, + { "dwAppInfoOffset", FT_DWORD, 0, NULL } +#endif + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpDevStatus, "LINEDEVSTATUS", 0, fields + }; + + if (dwAPIVersion < 0x00020000) + { + fieldHeader.dwNumFields = 16; + } +#if TAPI_2_0 + else + { + fieldHeader.dwNumFields = 19; + + fields[16].dwValue = lpDevStatus->dwAvailableMediaModes; + fields[17].dwValue = lpDevStatus->dwAppInfoSize; + fields[18].dwValue = lpDevStatus->dwAppInfoOffset; + } +#endif + ShowStructByField (&fieldHeader, FALSE); + +#if TAPI_2_0 + if (dwAPIVersion >= 0x00020000 && lpDevStatus->dwAppInfoSize) + { + char szAppInfoN[16]; + DWORD i; + LPLINEAPPINFO pAppInfo; + STRUCT_FIELD fields[] = + { + { "dwMachineNameSize", FT_SIZE, 0, NULL }, + { "dwMachineNameOffset", FT_OFFSET, 0, NULL }, + { "dwUserNameSize", FT_SIZE, 0, NULL }, + { "dwUserNameOffset", FT_OFFSET, 0, NULL }, + { "dwModuleFilenameSize", FT_SIZE, 0, NULL }, + { "dwModuleFilenameOffset", FT_OFFSET, 0, NULL }, + { "dwFriendlyNameSize", FT_SIZE, 0, NULL }, + { "dwFriendlyNameOffset", FT_OFFSET, 0, NULL }, + { "dwMediaModes", FT_FLAGS, 0, aMediaModes }, + { "dwAddressID", FT_DWORD, 0, NULL }, + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpDevStatus, szAppInfoN, 10, fields + }; + + + pAppInfo = (LPLINEAPPINFO) (((LPBYTE) lpDevStatus) + + lpDevStatus->dwAppInfoOffset); + + for (i = 0; i < lpDevStatus->dwNumOpens; i++) + { + wsprintf (szAppInfoN, "APPINFO[%d]", i); + + fields[0].dwValue = pAppInfo->dwMachineNameSize; + fields[1].dwValue = pAppInfo->dwMachineNameOffset; + fields[2].dwValue = pAppInfo->dwUserNameSize; + fields[3].dwValue = pAppInfo->dwUserNameOffset; + fields[4].dwValue = pAppInfo->dwModuleFilenameSize; + fields[5].dwValue = pAppInfo->dwModuleFilenameOffset; + fields[6].dwValue = pAppInfo->dwFriendlyNameSize; + fields[7].dwValue = pAppInfo->dwFriendlyNameOffset; + fields[8].dwValue = pAppInfo->dwMediaModes;; + fields[9].dwValue = pAppInfo->dwAddressID; + + ShowStructByField (&fieldHeader, TRUE); + + pAppInfo++; + } + } +#endif + } + } + + break; + } +#if TAPI_2_0 + case lGetMessage: + { + LINEMESSAGE msg; + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { "lpMessage", PT_POINTER, (DWORD) &msg, &msg }, + { "dwTimeout", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, NULL }; + + + CHK_LINEAPP_SELECTED() + + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + // Max timeout of 2 seconds (don't want to hang app & excite user) + + params[2].dwValue = (params[2].dwValue > 2000 ? + 2000 : params[2].dwValue); + + DumpParams (¶msHeader); + + lResult = lineGetMessage( + (HLINEAPP) params[0].dwValue, + (LPLINEMESSAGE) params[1].dwValue, + (DWORD) params[2].dwValue + ); + + ShowLineFuncResult (aFuncNames[funcIndex], lResult); + + if (lResult == 0) + { + tapiCallback( + msg.hDevice, + msg.dwMessageID, + msg.dwCallbackInstance, + msg.dwParam1, + msg.dwParam2, + msg.dwParam3 + ); + } + + break; + } +#endif + case lGetNewCalls: + { + LPLINECALLLIST lpCallList = (LPLINECALLLIST) pBigBuf; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { "dwSelect", PT_ORDINAL, LINECALLSELECT_LINE, aCallSelects }, + { "lpCallList", PT_POINTER, (DWORD) lpCallList, lpCallList } + }; + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) lineGetNewCalls }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + memset (lpCallList, 0, (size_t) dwBigBufSize); + lpCallList->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpCallList); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + STRUCT_FIELD fields[] = + { + { "dwCallsNumEntries", FT_DWORD, lpCallList->dwCallsNumEntries, NULL }, + { "dwCallsSize", FT_SIZE, lpCallList->dwCallsSize, NULL }, + { "dwCallsOffset", FT_OFFSET, lpCallList->dwCallsOffset, NULL } + + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpCallList, + "LINECALLLIST", + 3, + fields + }; + + ShowStructByField (&fieldHeader, FALSE); + } + + + // + // If there are any hCalls returned in this struct we want + // to add them to the widget list + // + + if (lpCallList->dwCallsNumEntries) + { + PMYLINE pLine = GetLine ((HLINE) params[0].dwValue); + LPHCALL lphCall = (LPHCALL) + (((LPBYTE) lpCallList) + lpCallList->dwCallsOffset); + + + for (i = 0; i < (int) lpCallList->dwCallsNumEntries; i++) + { + PMYCALL pNewCall = AllocCall (pLine); + LINECALLSTATUS callStatus; + + + if (pNewCall) + { + pNewCall->hCall = *lphCall; + pNewCall->bMonitor = TRUE; + lphCall++; + + memset (&callStatus, 0, sizeof(LINECALLSTATUS)); + callStatus.dwTotalSize = sizeof(LINECALLSTATUS); + + if (lineGetCallStatus (pNewCall->hCall, &callStatus) + == 0) + { + // + // Special case chk for bNukeIdleMonitorCalls + // + + if ((callStatus.dwCallState + == LINECALLSTATE_IDLE) && + bNukeIdleMonitorCalls && + (callStatus.dwCallPrivilege + == LINECALLPRIVILEGE_MONITOR)) + { + if ((lResult = lineDeallocateCall( + (HCALL) pNewCall->hCall)) == 0) + { + ShowStr( + "Monitored call x%lx deallocated " \ + "on IDLE", + pNewCall->hCall + ); + + FreeCall (pNewCall); + } + else + { + ShowStr( + "lineDeallocateCall failed (x%lx) to" \ + " free idle monitored call x%lx", + lResult, + pNewCall->hCall + ); + + pNewCall->dwCallState = callStatus.dwCallState; + } + } + else + { + pNewCall->dwCallState = callStatus.dwCallState; + } + } + else + { + pNewCall->dwCallState = LINECALLSTATE_UNKNOWN; + } + } + } + + UpdateWidgetList(); + } + } + + break; + } + case lGetNumRings: + { + DWORD dwNumRings; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { "lpdwNumRings", PT_POINTER, (DWORD) &dwNumRings, &dwNumRings } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineGetNumRings }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStr ("%snum rings = x%lx", szTab, dwNumRings); + } + + break; + } + case lGetRequest: +#if TAPI_2_0 + case lGetRequestW: +#endif + { +#if TAPI_2_0 + LINEREQMEDIACALLW reqXxxCall; +#else + LINEREQMEDIACALL reqXxxCall; +#endif + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { "dwRequestMode", PT_ORDINAL, LINEREQUESTMODE_MAKECALL, aRequestModes }, + { "lpRequestBuffer", PT_POINTER, (DWORD) &reqXxxCall, &reqXxxCall } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lGetRequest ? + (PFN3) lineGetRequest : (PFN3) lineGetRequestW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineGetRequest }; +#endif + + CHK_LINEAPP_SELECTED() + + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + + memset (&reqXxxCall, 0, sizeof (reqXxxCall)); + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + if (params[1].dwValue == LINEREQUESTMODE_MAKECALL) + { +#if TAPI_2_0 + if (gbWideStringParams) + { + LPLINEREQMAKECALLW lpReqMakeCall = (LPLINEREQMAKECALLW) + &reqXxxCall; + + + ShowStr ("%sszDestAddress=%ws", szTab, lpReqMakeCall->szDestAddress); + ShowStr ("%sszAppName=%ws", szTab, lpReqMakeCall->szAppName); + ShowStr ("%sszCalledParty=%ws", szTab, lpReqMakeCall->szCalledParty); + ShowStr ("%sszComment=%ws", szTab, lpReqMakeCall->szComment); + } + else + { + LPLINEREQMAKECALL lpReqMakeCall = (LPLINEREQMAKECALL) + &reqXxxCall; + + ShowStr ("%sszDestAddress=%s", szTab, lpReqMakeCall->szDestAddress); + ShowStr ("%sszAppName=%s", szTab, lpReqMakeCall->szAppName); + ShowStr ("%sszCalledParty=%s", szTab, lpReqMakeCall->szCalledParty); + ShowStr ("%sszComment=%s", szTab, lpReqMakeCall->szComment); + } +#else + LPLINEREQMAKECALL lpReqMakeCall = (LPLINEREQMAKECALL) + &reqXxxCall; + + + ShowStr ("%sszDestAddress=%s", szTab, lpReqMakeCall->szDestAddress); + ShowStr ("%sszAppName=%s", szTab, lpReqMakeCall->szAppName); + ShowStr ("%sszCalledParty=%s", szTab, lpReqMakeCall->szCalledParty); + ShowStr ("%sszComment=%s", szTab, lpReqMakeCall->szComment); +#endif + } + else + { + // + // NOTE: lineGetRequest(MEDIACALL) is a NOOP for win32, + // so we don't have to sweat differing sizes for + // HWND & WPARAM in the struct + // + + LPLINEREQMEDIACALL lpReqMediaCall = (LPLINEREQMEDIACALL) + &reqXxxCall; + + + ShowStr ("%shWnd=x%x", szTab, lpReqMediaCall->hWnd); + ShowStr ("%swRequestID=x%x", szTab, lpReqMediaCall->wRequestID); + ShowStr ("%sszDeviceClass=%s", szTab, lpReqMediaCall->szDeviceClass); + ShowStr ("%sdwSize=x%lx", szTab, lpReqMediaCall->dwSize); + ShowStr ("%sdwSecure=x%lx", szTab, lpReqMediaCall->dwSecure); + ShowStr ("%sszDestAddress=%s", szTab, lpReqMediaCall->szDestAddress); + ShowStr ("%sszAppName=%s", szTab, lpReqMediaCall->szAppName); + ShowStr ("%sszCalledParty=%s", szTab, lpReqMediaCall->szCalledParty); + ShowStr ("%sszComment=%s", szTab, lpReqMediaCall->szComment); + } + } + + break; + } + case lGetStatusMessages: + { + DWORD aFlags[2]; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { "lpdwLineStates", PT_POINTER, (DWORD) &aFlags[0], &aFlags[0] }, + { "lpdwAddressStates", PT_POINTER, (DWORD) &aFlags[1], &aFlags[1] } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineGetStatusMessages }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + STRUCT_FIELD fields[] = + { + { "dwLineStates", FT_FLAGS, aFlags[0], aLineStates }, + { "dwAddressStates", FT_FLAGS, aFlags[1], aAddressStates } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + aFlags, + "", + 2, + fields + }; + + + ShowStructByField (&fieldHeader, TRUE); + } + + break; + } + case lGetTranslateCaps: +#if TAPI_2_0 + case lGetTranslateCapsW: +#endif + { + LPLINETRANSLATECAPS lpTranslateCaps = (LPLINETRANSLATECAPS) pBigBuf; + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { szdwAPIVersion, PT_ORDINAL, dwDefLineAPIVersion, aAPIVersions }, + { "lpTranslateCaps", PT_POINTER, (DWORD) lpTranslateCaps, lpTranslateCaps } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lGetTranslateCaps ? + (PFN3) lineGetTranslateCaps : (PFN3) lineGetTranslateCapsW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineGetTranslateCaps }; +#endif + + if (pLineAppSel) + { + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + } + + memset (lpTranslateCaps, 0, (size_t) dwBigBufSize); + lpTranslateCaps->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + UpdateResults (TRUE); + + ShowStructByDWORDs (lpTranslateCaps); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + DWORD i; + LPLINECARDENTRY lpCardEntry; + LPLINELOCATIONENTRY lpLocationEntry; + STRUCT_FIELD fields[] = + { + { "dwNumLocations", FT_DWORD, lpTranslateCaps->dwNumLocations, NULL }, + { "dwLocationListSize", FT_DWORD, lpTranslateCaps->dwLocationListSize, NULL }, + { "dwLocationListOffset", FT_DWORD, lpTranslateCaps->dwLocationListOffset, NULL }, + { "dwCurrentLocationID", FT_DWORD, lpTranslateCaps->dwCurrentLocationID, NULL }, + { "dwNumCards", FT_DWORD, lpTranslateCaps->dwNumCards, NULL }, + { "dwCardListSize", FT_DWORD, lpTranslateCaps->dwCardListSize, NULL }, + { "dwCardListOffset", FT_DWORD, lpTranslateCaps->dwCardListOffset, NULL }, + { "dwCurrentPreferredCardID", FT_DWORD, lpTranslateCaps->dwCurrentPreferredCardID, NULL } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpTranslateCaps, + "LINETRANSLATECAPS", + 8, + fields + }; + + ShowStructByField (&fieldHeader, FALSE); + + lpLocationEntry = (LPLINELOCATIONENTRY) + (((LPBYTE) lpTranslateCaps) + + lpTranslateCaps->dwLocationListOffset); + + for (i = 0; i < lpTranslateCaps->dwNumLocations; i++) + { + char buf[32]; + STRUCT_FIELD fields[] = + { + { "dwPermanentLocationID", FT_DWORD, lpLocationEntry->dwPermanentLocationID, NULL }, + { "dwLocationNameSize", FT_SIZE, lpLocationEntry->dwLocationNameSize, NULL }, + { "dwLocationNameOffset", FT_OFFSET, lpLocationEntry->dwLocationNameOffset, NULL }, + { "dwCountryCode", FT_DWORD, lpLocationEntry->dwCountryCode, NULL }, + { "dwCityCodeSize", FT_SIZE, lpLocationEntry->dwCityCodeSize, NULL }, + { "dwCityCodeOffset", FT_OFFSET, lpLocationEntry->dwCityCodeOffset, NULL }, + { "dwPreferredCardID", FT_DWORD, lpLocationEntry->dwPreferredCardID, NULL } +#if TAPI_1_1 + , + { "dwLocalAccessCodeSize", FT_SIZE, lpLocationEntry->dwLocalAccessCodeSize, NULL }, + { "dwLocalAccessCodeOffset", FT_OFFSET, lpLocationEntry->dwLocalAccessCodeOffset, NULL }, + { "dwLongDistanceAccessCodeSize", FT_SIZE, lpLocationEntry->dwLongDistanceAccessCodeSize, NULL }, + { "dwLongDistanceAccessCodeOffset", FT_OFFSET, lpLocationEntry->dwLongDistanceAccessCodeOffset, NULL }, + { "dwTollPrefixListSize", FT_SIZE, lpLocationEntry->dwTollPrefixListSize, NULL }, + { "dwTollPrefixListOffset", FT_OFFSET, lpLocationEntry->dwTollPrefixListOffset, NULL }, + { "dwCountryID", FT_DWORD, lpLocationEntry->dwCountryID, NULL }, + { "dwOptions", FT_FLAGS, lpLocationEntry->dwOptions, aLocationOptions }, + { "dwCancelCallWaitingSize", FT_SIZE, lpLocationEntry->dwCancelCallWaitingSize, NULL }, + { "dwCancelCallWaitingOffset", FT_OFFSET, lpLocationEntry->dwCancelCallWaitingOffset, NULL } +#endif + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpTranslateCaps, // size,offset relative to lpXlatCaps + buf, +#if TAPI_1_1 + 17, +#else + 7, +#endif + fields + }; + + + sprintf (buf, "LINELOCATIONENTRY[%ld]", i); + + lpLocationEntry++; +#if TAPI_1_1 + if (params[1].dwValue == 0x10003) + { + // + // Only show ver 1.0 params & munge ptr to + // compensate for for smaller struct size + // + + fieldHeader.dwNumFields = 7; + lpLocationEntry = (LPLINELOCATIONENTRY) + (((LPBYTE) lpLocationEntry) - 10*sizeof(DWORD)); + + } +#endif + ShowStructByField (&fieldHeader, TRUE); + + } + + lpCardEntry = (LPLINECARDENTRY) + (((LPBYTE) lpTranslateCaps) + + lpTranslateCaps->dwCardListOffset); + + for (i = 0; i < lpTranslateCaps->dwNumCards; i++) + { + char buf[32]; + STRUCT_FIELD fields[] = + { + { "dwPermanentCardID", FT_DWORD, lpCardEntry->dwPermanentCardID, NULL }, + { "dwCardNameSize", FT_SIZE, lpCardEntry->dwCardNameSize, NULL }, + { "dwCardNameOffset", FT_OFFSET, lpCardEntry->dwCardNameOffset, NULL } +#if TAPI_1_1 + , + { "dwCardNumberDigits", FT_DWORD, lpCardEntry->dwCardNumberDigits, NULL }, + { "dwSameAreaRuleSize", FT_SIZE, lpCardEntry->dwSameAreaRuleSize, NULL }, + { "dwSameAreaRuleOffset", FT_OFFSET, lpCardEntry->dwSameAreaRuleOffset, NULL }, + { "dwLongDistanceRuleSize", FT_SIZE, lpCardEntry->dwLongDistanceRuleSize, NULL }, + { "dwLongDistanceRuleOffset", FT_OFFSET, lpCardEntry->dwLongDistanceRuleOffset, NULL }, + { "dwInternationalRuleSize", FT_SIZE, lpCardEntry->dwInternationalRuleSize, NULL }, + { "dwInternationalRuleOffset", FT_OFFSET, lpCardEntry->dwInternationalRuleOffset, NULL }, + { "dwOptions", FT_FLAGS, lpCardEntry->dwOptions, aCardOptions } +#endif + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpTranslateCaps, // size,offset relative to lpXlatCaps + buf, +#if TAPI_1_1 + 11, +#else + 3, +#endif + fields + }; + + + sprintf (buf, "LINECARDENTRY[%ld]", i); + + lpCardEntry++; +#if TAPI_1_1 + if (params[1].dwValue == 0x10003) + { + // + // Only show ver 1.0 params & munge ptr to + // compensate for for smaller struct size + // + + fieldHeader.dwNumFields = 3; + lpCardEntry = (LPLINECARDENTRY) + (((LPBYTE) lpCardEntry) - 8*sizeof(DWORD)); + + } +#endif + ShowStructByField (&fieldHeader, TRUE); + } + } + + UpdateResults (FALSE); + } + + break; + } + case lHandoff: +#if TAPI_2_0 + case lHandoffW: +#endif + { + char szFilename[MAX_STRING_PARAM_SIZE] = "tb20.exe"; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "lpszFileName", PT_STRING, (DWORD) szFilename, szFilename }, + { "dwMediaMode", PT_FLAGS, dwDefMediaMode, aMediaModes } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lHandoff ? + (PFN3) lineHandoff : (PFN3) lineHandoffW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineHandoff }; +#endif + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } + case lHold: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 1, funcIndex, params, (PFN1) lineHold }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } + case lInitialize: + { + PMYLINEAPP pNewLineApp; + char szAppName[MAX_STRING_PARAM_SIZE]; + DWORD dwNumLineDevs; + FUNC_PARAM params[] = + { + { "lphLineApp", PT_POINTER, 0, NULL }, + { "hInstance", PT_DWORD, (DWORD) ghInst, NULL }, + { "lpfnCallback", PT_POINTER, (DWORD) tapiCallback, tapiCallback }, + { szlpszAppName, PT_STRING, (DWORD) szAppName, szAppName }, + { "lpdwNumDevs", PT_POINTER, (DWORD) &dwNumLineDevs, &dwNumLineDevs } + }; + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) lineInitialize }; + + + if (!(pNewLineApp = AllocLineApp())) + { + MessageBeep ((UINT) -1); + ShowStr ("error creating data structure"); + break; + } + + params[0].dwValue = + params[0].u.dwDefValue = (DWORD) &pNewLineApp->hLineApp; + + strcpy (szAppName, szDefAppName); + +#ifdef WIN32 + lResult = DoFunc (¶msHeader); +#else + // + // NOTE: on win16 HINSTANCEs are 16 bits, so we've to hard code this + // + + if (!LetUserMungeParams (¶msHeader)) + { + FreeLineApp (pNewLineApp); + + break; + } + + DumpParams (¶msHeader); + + lResult = lineInitialize( + (LPHLINEAPP) params[0].dwValue, + (HINSTANCE) params[1].dwValue, + (LINECALLBACK) params[2].dwValue, + (LPCSTR) params[3].dwValue, + (LPDWORD) params[4].dwValue + ); + + ShowLineFuncResult (aFuncNames[funcIndex], lResult); +#endif + if (lResult == 0) + { + ShowStr ("%snum line devs = %ld", szTab, dwNumLineDevs); + //SendMessage (ghwndLineApps, LB_SETCURSEL, (WPARAM) i, 0); + UpdateWidgetList(); + gdwNumLineDevs = dwNumLineDevs; + SelectWidget ((PMYWIDGET) pNewLineApp); + } + else + { + FreeLineApp (pNewLineApp); + } + + break; + } +#if TAPI_2_0 + case lInitializeEx: + case lInitializeExW: + { + char szAppName[MAX_STRING_PARAM_SIZE]; + DWORD dwNumLineDevs, dwAPIVersion; + PMYLINEAPP pNewLineApp; + LINEINITIALIZEEXPARAMS initExParams; + FUNC_PARAM params[] = + { + { "lphLineApp", PT_POINTER, 0, NULL }, + { "hInstance", PT_DWORD, (DWORD) ghInst, NULL }, + { "lpfnCallback", PT_POINTER, (DWORD) tapiCallback, tapiCallback }, + { szlpszFriendlyAppName, PT_STRING, (DWORD) szAppName, szAppName }, + { "lpdwNumDevs", PT_POINTER, (DWORD) &dwNumLineDevs, &dwNumLineDevs }, + { "lpdwAPIVersion", PT_POINTER, (DWORD) &dwAPIVersion, &dwAPIVersion }, + { " ->dwAPIVersion",PT_ORDINAL,(DWORD) 0x00020000, aAPIVersions }, + { "lpInitExParams", PT_POINTER, (DWORD) &initExParams, &initExParams }, + { " ->dwOptions", PT_ORDINAL, (DWORD) LINEINITIALIZEEXOPTION_USECOMPLETIONPORT, aInitExOptions } + }; + FUNC_PARAM_HEADER paramsHeader = + { 9, funcIndex, params, NULL }; + + + if (!(pNewLineApp = AllocLineApp())) + { + MessageBeep ((UINT) -1); + ShowStr ("error creating data structure"); + break; + } + + params[0].dwValue = + params[0].u.dwDefValue = (DWORD) &pNewLineApp->hLineApp; + + strcpy (szAppName, szDefAppName); + + if (!LetUserMungeParams (¶msHeader)) + { + FreeLineApp (pNewLineApp); + + break; + } + + initExParams.dwTotalSize = sizeof (LINEINITIALIZEEXPARAMS); + initExParams.dwOptions = params[8].dwValue; + initExParams.Handles.hCompletionPort = ghCompletionPort; + + dwAPIVersion = params[6].dwValue; + + DumpParams (¶msHeader); + + if (funcIndex == lInitializeEx) + { + lResult = lineInitializeEx( + (LPHLINEAPP) params[0].dwValue, + (HINSTANCE) params[1].dwValue, + (LINECALLBACK) params[2].dwValue, + (LPCSTR) params[3].dwValue, + (LPDWORD) params[4].dwValue, + (LPDWORD) params[5].dwValue, + (LPLINEINITIALIZEEXPARAMS) params[7].dwValue + ); + } + else + { + lResult = lineInitializeExW( + (LPHLINEAPP) params[0].dwValue, + (HINSTANCE) params[1].dwValue, + (LINECALLBACK) params[2].dwValue, + (LPCWSTR) params[3].dwValue, + (LPDWORD) params[4].dwValue, + (LPDWORD) params[5].dwValue, + (LPLINEINITIALIZEEXPARAMS) params[7].dwValue + ); + } + + ShowLineFuncResult (aFuncNames[funcIndex], lResult); + + if (lResult == 0) + { + ShowStr ("%snum line devs = %ld", szTab, dwNumLineDevs); + + if (params[7].dwValue != 0 && + (initExParams.dwOptions & 3) == + LINEINITIALIZEEXOPTION_USEEVENT) + { + ShowStr( + "hLineApp x%x was created with the\r\n" \ + "USEEVENT option, so you must use\r\n" \ + "lineGetMessage to retrieve messages.", + pNewLineApp->hLineApp + ); + } + + //SendMessage (ghwndLineApps, LB_SETCURSEL, (WPARAM) i, 0); + UpdateWidgetList(); + gdwNumLineDevs = dwNumLineDevs; + SelectWidget ((PMYWIDGET) pNewLineApp); + } + else + { + FreeLineApp (pNewLineApp); + } + + break; + } +#endif + case lMakeCall: +#if TAPI_2_0 + case lMakeCallW: +#endif + { + PMYCALL pNewCall; + char szAddress[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szlphCall, PT_POINTER, 0, NULL }, + { szlpszDestAddress, PT_STRING, (DWORD) szAddress, szAddress }, + { "dwCountryCode", PT_DWORD, dwDefCountryCode, NULL }, + { szlpCallParams, PT_CALLPARAMS, 0, lpCallParams } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (funcIndex == lMakeCall ? + (PFN5) lineMakeCall : (PFN5) lineMakeCallW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) lineMakeCall }; +#endif + + CHK_LINE_SELECTED() + + if (!(pNewCall = AllocCall (pLineSel))) + { + MessageBeep ((UINT) -1); + ShowStr ("error creating data structure"); + break; + } + + params[0].dwValue = (DWORD) pLineSel->hLine; + params[1].dwValue = params[1].u.dwDefValue = (DWORD) &pNewCall->hCall; + + strcpy (szAddress, szDefDestAddress); + + if ((lResult = DoFunc (¶msHeader)) > 0) + { + if (params[0].dwValue != (DWORD) pLineSel->hLine) + { + MoveCallToLine (pNewCall, (HLINE) params[0].dwValue); + } + + pNewCall->lMakeCallReqID = lResult; + dwNumPendingMakeCalls++; + SelectWidget ((PMYWIDGET) pNewCall); + } + else + { + FreeCall (pNewCall); + } + + break; + } + case lMonitorDigits: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "dwDigitModes", PT_FLAGS, LINEDIGITMODE_DTMF, aDigitModes } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineMonitorDigits }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } + case lMonitorMedia: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "dwMediaModes", PT_FLAGS, dwDefMediaMode, aMediaModes } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineMonitorMedia }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } + case lMonitorTones: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "lpToneList", PT_POINTER, (DWORD) pBigBuf, pBigBuf }, + { "dwNumEntries", PT_DWORD, 1, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineMonitorTones }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } + case lNegotiateAPIVersion: + { + DWORD dwAPIVersion; + LINEEXTENSIONID extID; + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { szdwDeviceID, PT_DWORD, dwDefLineDeviceID, NULL }, + { "dwAPILowVersion", PT_DWORD, 0x00010000, aAPIVersions }, + { "dwAPIHighVersion", PT_DWORD, 0x10000000, aAPIVersions }, + { "lpdwAPIVersion", PT_POINTER, (DWORD) &dwAPIVersion, &dwAPIVersion }, + { "lpExtensionID", PT_POINTER, (DWORD) &extID, &extID } + }; + FUNC_PARAM_HEADER paramsHeader = + { 6, funcIndex, params, (PFN6) lineNegotiateAPIVersion }; + + + CHK_LINEAPP_SELECTED() + + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStr ("%s%s=x%lx", szTab, szdwAPIVersion, dwAPIVersion); + ShowStr( + "%sextID.ID0=x%lx, .ID1=x%lx, .ID2=x%lx, .ID3=x%lx, ", + szTab, + extID.dwExtensionID0, + extID.dwExtensionID1, + extID.dwExtensionID2, + extID.dwExtensionID3 + ); + } + + break; + } + case lNegotiateExtVersion: + { + DWORD dwExtVersion; + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { szdwDeviceID, PT_DWORD, dwDefLineDeviceID, NULL }, + { szdwAPIVersion, PT_ORDINAL, dwDefLineAPIVersion, aAPIVersions }, + { "dwExtLowVersion", PT_DWORD, 0x00000000, NULL }, + { "dwExtHighVersion", PT_DWORD, 0x80000000, NULL }, + { "lpdwExtVersion", PT_POINTER, (DWORD) &dwExtVersion, &dwExtVersion } + }; + FUNC_PARAM_HEADER paramsHeader = + { 6, funcIndex, params, (PFN6) lineNegotiateExtVersion }; + + + CHK_LINEAPP_SELECTED() + + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + + if (DoFunc (¶msHeader) == 0) + { + ShowStr ("%sdwExtVersion=x%lx", szTab, dwExtVersion); + } + + break; + } + default: + + FuncDriver2 (funcIndex); + break; + } + + gbWideStringParams = FALSE; +} + +//#pragma code_seg () + +#pragma warning (default:4113) diff --git a/private/tapi/dev/apps/tb/tb.def b/private/tapi/dev/apps/tb/tb.def new file mode 100644 index 000000000..d2ced5f48 --- /dev/null +++ b/private/tapi/dev/apps/tb/tb.def @@ -0,0 +1,13 @@ +NAME TB +STUB 'WINSTUB.EXE' +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE +HEAPSIZE 2048 +STACKSIZE 16384 + +EXPORTS + MainWndProc + ParamsDlgProc + tapiCallback + AboutDlgProc + IconDlgProc diff --git a/private/tapi/dev/apps/tb/tb.h b/private/tapi/dev/apps/tb/tb.h new file mode 100644 index 000000000..f9e46174f --- /dev/null +++ b/private/tapi/dev/apps/tb/tb.h @@ -0,0 +1,872 @@ +/*++ BUILD Version: 0000 // Increment this if a change has global effects + +Copyright (c) 1994-96 Microsoft Corporation + +Module Name: + + tb.h + +Abstract: + + Header file for the TAPI Browser util + +Author: + + Dan Knudson (DanKn) 23-Aug-1994 + +Revision History: + +--*/ + + +#include <windows.h> +#include <tapi.h> + + +// +// Symbolic constants +// + +#define DS_NONZEROFIELDS 0x00000001 +#define DS_ZEROFIELDS 0x00000002 +#define DS_BYTEDUMP 0x00000004 + +#define WT_LINEAPP 1 +#define WT_LINE 2 +#define WT_CALL 3 +#define WT_PHONEAPP 4 +#define WT_PHONE 5 + +#define PT_DWORD 1 +#define PT_FLAGS 2 +#define PT_POINTER 3 +#define PT_STRING 4 +#define PT_CALLPARAMS 5 +#define PT_FORWARDLIST 6 +#define PT_ORDINAL 7 + +#define FT_DWORD 1 +#define FT_FLAGS 2 +#define FT_ORD 3 +#define FT_SIZE 4 +#define FT_OFFSET 5 + +#define MAX_STRING_PARAM_SIZE 96 + +#define MAX_USER_BUTTONS 6 + +#define MAX_USER_BUTTON_TEXT_SIZE 8 + +#define MAX_LINEFORWARD_ENTRIES 5 + +#define TABSIZE 4 + +#if TAPI_2_0 +#define LAST_LINEERR LINEERR_DIALVOICEDETECT +#else +#define LAST_LINEERR LINEERR_NOMULTIPLEINSTANCE +#endif + + +// +// +// + +typedef LONG (WINAPI *PFN1)(DWORD); +typedef LONG (WINAPI *PFN2)(DWORD, DWORD); +typedef LONG (WINAPI *PFN3)(DWORD, DWORD, DWORD); +typedef LONG (WINAPI *PFN4)(DWORD, DWORD, DWORD, DWORD); +typedef LONG (WINAPI *PFN5)(DWORD, DWORD, DWORD, DWORD, DWORD); +typedef LONG (WINAPI *PFN6)(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD); +typedef LONG (WINAPI *PFN7)(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD); +typedef LONG (WINAPI *PFN8)(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, + DWORD); +typedef LONG (WINAPI *PFN9)(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, + DWORD, DWORD); +typedef LONG (WINAPI *PFN10)(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, + DWORD, DWORD, DWORD); +typedef LONG (WINAPI *PFN12)(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, + DWORD, DWORD, DWORD, DWORD, DWORD); + + +typedef struct _MYWIDGET +{ + DWORD dwType; + + struct _MYWIDGET *pNext; + +} MYWIDGET, *PMYWIDGET; + + +typedef struct _MYLINEAPP +{ + MYWIDGET Widget; + + HLINEAPP hLineApp; + +} MYLINEAPP, *PMYLINEAPP; + + +typedef struct _MYLINE +{ + MYWIDGET Widget; + + HLINE hLine; + + HLINEAPP hLineApp; + + DWORD dwDevID; + + DWORD dwPrivileges; + + DWORD dwMediaModes; + + DWORD dwAPIVersion; + + PMYLINEAPP pLineApp; + +} MYLINE, *PMYLINE; + + +typedef struct _MYCALL +{ + MYWIDGET Widget; + + HCALL hCall; + + DWORD dwCallState; + + LONG lMakeCallReqID; + + LONG lDropReqID; + + DWORD dwCompletionID; + + DWORD dwNumGatheredDigits; + + char *lpsGatheredDigits; + + PMYLINE pLine; + + BOOL bMonitor; + +} MYCALL, *PMYCALL; + + +typedef struct _MYPHONEAPP +{ + MYWIDGET Widget; + + HPHONEAPP hPhoneApp; + +} MYPHONEAPP, *PMYPHONEAPP; + + +typedef struct _MYPHONE +{ + MYWIDGET Widget; + + HPHONE hPhone; + + HPHONEAPP hPhoneApp; + + DWORD dwDevID; + + DWORD dwPrivilege; + + DWORD dwAPIVersion; + + PMYPHONEAPP pPhoneApp; + +} MYPHONE, *PMYPHONE; + + +typedef struct _LOOKUP +{ + DWORD dwVal; + + char lpszVal[20]; + +} LOOKUP, *PLOOKUP; + + +typedef enum +{ + lAccept, +#if TAPI_1_1 + lAddProvider, +#if TAPI_2_0 + lAddProviderW, +#endif +#endif + lAddToConference, +#if TAPI_2_0 + lAgentSpecific, +#endif + lAnswer, + lBlindTransfer, +#if TAPI_2_0 + lBlindTransferW, +#endif + lClose, + lCompleteCall, + lCompleteTransfer, + lConfigDialog, +#if TAPI_2_0 + lConfigDialogW, +#endif +#if TAPI_1_1 + lConfigDialogEdit, +#if TAPI_2_0 + lConfigDialogEditW, +#endif + lConfigProvider, +#endif + lDeallocateCall, + lDevSpecific, + lDevSpecificFeature, + lDial, +#if TAPI_2_0 + lDialW, +#endif + lDrop, + lForward, +#if TAPI_2_0 + lForwardW, +#endif + lGatherDigits, +#if TAPI_2_0 + lGatherDigitsW, +#endif + lGenerateDigits, +#if TAPI_2_0 + lGenerateDigitsW, +#endif + lGenerateTone, + lGetAddressCaps, +#if TAPI_2_0 + lGetAddressCapsW, +#endif + lGetAddressID, +#if TAPI_2_0 + lGetAddressIDW, +#endif + lGetAddressStatus, +#if TAPI_2_0 + lGetAddressStatusW, + lGetAgentActivityList, + lGetAgentActivityListW, + lGetAgentCaps, + lGetAgentGroupList, + lGetAgentStatus, +#endif +#if TAPI_1_1 + lGetAppPriority, +#if TAPI_2_0 + lGetAppPriorityW, +#endif +#endif + lGetCallInfo, +#if TAPI_2_0 + lGetCallInfoW, +#endif + lGetCallStatus, + lGetConfRelatedCalls, +#if TAPI_1_1 + lGetCountry, +#if TAPI_2_0 + lGetCountryW, +#endif +#endif + lGetDevCaps, +#if TAPI_2_0 + lGetDevCapsW, +#endif + lGetDevConfig, +#if TAPI_2_0 + lGetDevConfigW, +#endif + lGetIcon, +#if TAPI_2_0 + lGetIconW, +#endif + lGetID, +#if TAPI_2_0 + lGetIDW, +#endif + lGetLineDevStatus, +#if TAPI_2_0 + lGetLineDevStatusW, + lGetMessage, +#endif + lGetNewCalls, + lGetNumRings, +#if TAPI_1_1 + lGetProviderList, +#if TAPI_2_0 + lGetProviderListW, +#endif +#endif + lGetRequest, +#if TAPI_2_0 + lGetRequestW, +#endif + lGetStatusMessages, + lGetTranslateCaps, +#if TAPI_2_0 + lGetTranslateCapsW, +#endif + lHandoff, +#if TAPI_2_0 + lHandoffW, +#endif + lHold, + lInitialize, +#if TAPI_2_0 + lInitializeEx, + lInitializeExW, +#endif + lMakeCall, +#if TAPI_2_0 + lMakeCallW, +#endif + lMonitorDigits, + lMonitorMedia, + lMonitorTones, + lNegotiateAPIVersion, + lNegotiateExtVersion, + lOpen, +#if TAPI_2_0 + lOpenW, +#endif + lPark, +#if TAPI_2_0 + lParkW, +#endif + lPickup, +#if TAPI_2_0 + lPickupW, +#endif + lPrepareAddToConference, +#if TAPI_2_0 + lPrepareAddToConferenceW, + lProxyMessage, + lProxyResponse, +#endif + lRedirect, +#if TAPI_2_0 + lRedirectW, +#endif + lRegisterRequestRecipient, +#if TAPI_1_1 + lReleaseUserUserInfo, +#endif + lRemoveFromConference, +#if TAPI_1_1 + lRemoveProvider, +#endif + lSecureCall, + lSendUserUserInfo, +#if TAPI_2_0 + lSetAgentActivity, + lSetAgentGroup, + lSetAgentState, +#endif +#if TAPI_1_1 + lSetAppPriority, +#if TAPI_2_0 + lSetAppPriorityW, +#endif +#endif + lSetAppSpecific, +#if TAPI_2_0 + lSetCallData, +#endif + lSetCallParams, + lSetCallPrivilege, +#if TAPI_2_0 + lSetCallQualityOfService, + lSetCallTreatment, +#endif + lSetCurrentLocation, + lSetDevConfig, +#if TAPI_2_0 + lSetDevConfigW, + lSetLineDevStatus, +#endif + lSetMediaControl, + lSetMediaMode, + lSetNumRings, + lSetStatusMessages, + lSetTerminal, + lSetTollList, +#if TAPI_2_0 + lSetTollListW, +#endif + lSetupConference, +#if TAPI_2_0 + lSetupConferenceW, +#endif + lSetupTransfer, +#if TAPI_2_0 + lSetupTransferW, +#endif + lShutdown, + lSwapHold, + lTranslateAddress, +#if TAPI_2_0 + lTranslateAddressW, +#endif +#if TAPI_1_1 + lTranslateDialog, +#if TAPI_2_0 + lTranslateDialogW, +#endif +#endif + lUncompleteCall, + lUnhold, + lUnpark, +#if TAPI_2_0 + lUnparkW, +#endif + + pClose, + pConfigDialog, +#if TAPI_2_0 + pConfigDialogW, +#endif + pDevSpecific, + pGetButtonInfo, +#if TAPI_2_0 + pGetButtonInfoW, +#endif + pGetData, + pGetDevCaps, +#if TAPI_2_0 + pGetDevCapsW, +#endif + pGetDisplay, + pGetGain, + pGetHookSwitch, + pGetIcon, +#if TAPI_2_0 + pGetIconW, +#endif + pGetID, +#if TAPI_2_0 + pGetIDW, +#endif + pGetLamp, +#if TAPI_2_0 + pGetMessage, +#endif + pGetRing, + pGetStatus, +#if TAPI_2_0 + pGetStatusW, +#endif + pGetStatusMessages, + pGetVolume, + pInitialize, +#if TAPI_2_0 + pInitializeEx, + pInitializeExW, +#endif + pOpen, + pNegotiateAPIVersion, + pNegotiateExtVersion, + pSetButtonInfo, +#if TAPI_2_0 + pSetButtonInfoW, +#endif + pSetData, + pSetDisplay, + pSetGain, + pSetHookSwitch, + pSetLamp, + pSetRing, + pSetStatusMessages, + pSetVolume, + pShutdown, + + tGetLocationInfo, +#if TAPI_2_0 + tGetLocationInfoW, +#endif + tRequestDrop, + tRequestMakeCall, +#if TAPI_2_0 + tRequestMakeCallW, +#endif + tRequestMediaCall, +#if TAPI_2_0 + tRequestMediaCallW, +#endif + + OpenAllLines, + OpenAllPhones, + CloseHandl, + DumpBuffer, + + MiscBegin, + + DefValues, + lCallParams, + lForwardList + +} FUNC_INDEX; + + +typedef struct _FUNC_PARAM +{ + char far *szName; + + DWORD dwType; + + DWORD dwValue; + + union + { + LPVOID pLookup; + + char far *buf; + + LPVOID ptr; + + DWORD dwDefValue; + + } u; + +} FUNC_PARAM, *PFUNC_PARAM; + + +typedef struct _FUNC_PARAM_HEADER +{ + DWORD dwNumParams; + + FUNC_INDEX FuncIndex; + + PFUNC_PARAM aParams; + + union + { + PFN1 pfn1; + PFN2 pfn2; + PFN3 pfn3; + PFN4 pfn4; + PFN5 pfn5; + PFN6 pfn6; + PFN7 pfn7; + PFN8 pfn8; + PFN9 pfn9; + PFN10 pfn10; + PFN12 pfn12; + + } u; + +} FUNC_PARAM_HEADER, *PFUNC_PARAM_HEADER; + + +typedef struct _STRUCT_FIELD +{ + char far *szName; + + DWORD dwType; + + DWORD dwValue; + + LPVOID pLookup; + +} STRUCT_FIELD, *PSTRUCT_FIELD; + + +typedef struct _STRUCT_FIELD_HEADER +{ + LPVOID pStruct; + + char far *szName; + + DWORD dwNumFields; + + PSTRUCT_FIELD aFields; + +} STRUCT_FIELD_HEADER, *PSTRUCT_FIELD_HEADER; + + +// +// Func prototypes +// + +BOOL +CALLBACK +MainWndProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam + ); + +void +FAR +ShowStr( + LPCSTR format, + ... + ); + +void +ShowBytes( + DWORD dwSize, + LPVOID lp, + DWORD dwNumTabs + ); + +VOID +CALLBACK +tapiCallback( + DWORD hDevice, + DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3 + ); + +BOOL +CALLBACK +ParamsDlgProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam + ); + +BOOL +CALLBACK +AboutDlgProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam + ); + +BOOL +CALLBACK +IconDlgProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam + ); + +BOOL +IsLineAppSelected( + void + ); + +BOOL +IsLineSelected( + void + ); + +BOOL +IsCallSelected( + void + ); + +BOOL +IsTwoCallsSelected( + void + ); + +BOOL +IsPhoneAppSelected( + void + ); + +BOOL +IsPhoneSelected( + void + ); + +LONG +DoFunc( + PFUNC_PARAM_HEADER pHeader + ); + +BOOL +LetUserMungeParams( + PFUNC_PARAM_HEADER pParamsHeader + ); + +void +ShowLineFuncResult( + LPSTR lpFuncName, + LONG lResult + ); + +void +FuncDriver( + FUNC_INDEX funcIndex + ); + +void +UpdateWidgetList( + void + ); + +void +InsertWidgetInList( + PMYWIDGET pNewWidget, + PMYWIDGET pWidgetInsertBefore + ); + +BOOL +RemoveWidgetFromList( + PMYWIDGET pWidgetToRemove + ); + +PMYLINEAPP +AllocLineApp( + void + ); + +PMYLINEAPP +GetLineApp( + HLINEAPP hLineApp + ); + +VOID +FreeLineApp( + PMYLINEAPP pLineApp + ); + +PMYLINE +AllocLine( + PMYLINEAPP pLineApp + ); + +PMYLINE +GetLine( + HLINE hLine + ); + +VOID +FreeLine( + PMYLINE pLine + ); + +PMYCALL +AllocCall( + PMYLINE pLine + ); + +PMYCALL +GetCall( + HCALL hCall + ); + +VOID +FreeCall( + PMYCALL pCall + ); + +VOID +MoveCallToLine( + PMYCALL pCall, + HLINE hLine + ); + +PMYPHONEAPP +AllocPhoneApp( + void + ); + +PMYPHONEAPP +GetPhoneApp( + HPHONEAPP hPhoneApp + ); + +VOID +FreePhoneApp( + PMYPHONEAPP pPhoneApp + ); + +PMYPHONE +AllocPhone( + PMYPHONEAPP pPhoneApp + ); + +PMYPHONE +GetPhone( + HPHONE hPhone + ); + +VOID +FreePhone( + PMYPHONE pPhone + ); + +int +GetWidgetIndex( + PMYWIDGET pWidget + ); + +void +SelectWidget( + PMYWIDGET pWidget + ); + +void +UpdateResults( + BOOL bBegin + ); + +BOOL +CALLBACK +UserButtonsDlgProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam + ); + + +// +// Macros +// + +#define CHK_LINEAPP_SELECTED() \ + if (!IsLineAppSelected()) \ + { \ + break; \ + } + +#define CHK_LINE_SELECTED() \ + if (!IsLineSelected()) \ + { \ + break; \ + } + +#define CHK_CALL_SELECTED() \ + if (!IsCallSelected()) \ + { \ + break; \ + } + +#define CHK_TWO_CALLS_SELECTED() \ + if (!IsTwoCallsSelected()) \ + { \ + break; \ + } + +#define CHK_PHONEAPP_SELECTED() \ + if (!IsPhoneAppSelected()) \ + { \ + break; \ + } + +#define CHK_PHONE_SELECTED() \ + if (!IsPhoneSelected()) \ + { \ + break; \ + } diff --git a/private/tapi/dev/apps/tb/tb.ico b/private/tapi/dev/apps/tb/tb.ico Binary files differnew file mode 100644 index 000000000..89de5322d --- /dev/null +++ b/private/tapi/dev/apps/tb/tb.ico diff --git a/private/tapi/dev/apps/tb/tb.rc b/private/tapi/dev/apps/tb/tb.rc new file mode 100644 index 000000000..21b3b8210 --- /dev/null +++ b/private/tapi/dev/apps/tb/tb.rc @@ -0,0 +1,266 @@ +//Microsoft App Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#ifdef WIN32 +#include "windows.h" +#else +#include "afxres.h" +#endif + +///////////////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +#ifdef APSTUDIO_INVOKED +////////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +///////////////////////////////////////////////////////////////////////////////////// +#endif // APSTUDIO_INVOKED + + +////////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 292, 217 +STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | + WS_THICKFRAME | WS_CLIPCHILDREN +CAPTION "Tapi Browser" +MENU IDR_MENU1 +FONT 6, "Courier" +BEGIN + CONTROL "Params",IDC_BUTTON12,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,2,4,25,10 + PUSHBUTTON "LAp+",IDC_BUTTON1,30,1,14,16 + PUSHBUTTON "LAp-",IDC_BUTTON2,44,1,14,16 + PUSHBUTTON "Line+",IDC_BUTTON3,58,1,14,16 + PUSHBUTTON "Line-",IDC_BUTTON4,72,1,14,16 + PUSHBUTTON "Call+",IDC_BUTTON5,86,1,14,16 + PUSHBUTTON "Call-",IDC_BUTTON6,100,1,14,16 + PUSHBUTTON "PAp+",IDC_BUTTON7,118,1,14,16 + PUSHBUTTON "PAp-",IDC_BUTTON8,132,1,14,16 + PUSHBUTTON "Pho+",IDC_BUTTON9,146,1,14,16 + PUSHBUTTON "Pho-",IDC_BUTTON10,160,1,14,16 + PUSHBUTTON "Clear",IDC_BUTTON11,178,1,14,16 + PUSHBUTTON "",IDC_BUTTON13,196,1,14,16 + PUSHBUTTON "",IDC_BUTTON14,210,1,14,16 + PUSHBUTTON "",IDC_BUTTON15,224,1,14,16 + PUSHBUTTON "",IDC_BUTTON16,238,1,14,16 + PUSHBUTTON "",IDC_BUTTON17,252,1,14,16 + PUSHBUTTON "",IDC_BUTTON18,266,1,14,16 + EDITTEXT IDC_EDIT1,129,19,117,195,ES_MULTILINE | ES_AUTOVSCROLL | + ES_AUTOHSCROLL | WS_VSCROLL | WS_HSCROLL | 0x1000 + LISTBOX IDC_LIST1,70,20,58,194, LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + LISTBOX IDC_LIST2,2,20,65,197,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | + WS_TABSTOP +END + +IDD_DIALOG2 DIALOG DISCARDABLE 0, 0, 205, 192 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Parameters:",55,4,6,42,7 + LISTBOX IDC_LIST1,4,16,100,148,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | + WS_TABSTOP + LTEXT "Value:",56,116,6,30,7 + COMBOBOX IDC_COMBO1,116,16,80,47,CBS_SIMPLE | CBS_AUTOHSCROLL | + CBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + LTEXT "Bit flags:",57,116,66,40,9 + LISTBOX IDC_LIST2,116,75,80,89,LBS_MULTIPLESEL | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,116,171,36,14 + PUSHBUTTON "Cancel",IDCANCEL,160,171,37,14 +// help PUSHBUTTON "Help",IDC_TB_HELP,4,171,36,14 +END + +IDD_DIALOG3 DIALOG DISCARDABLE 0, 0, 203, 198 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "User-defined buttons" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Button number:",55,8,8,54,7 + LISTBOX IDC_LIST1,8,18,50,72,LBS_SORT | LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + LTEXT "Button function:",56,78,8,58,7 + LISTBOX IDC_LIST2,79,18,118,174,LBS_SORT | LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + LTEXT "Button Text:",57,8,100,45,7 + EDITTEXT IDC_EDIT1,9,110,28,11,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,8,158,50,14 + PUSHBUTTON "Cancel",IDCANCEL,8,178,50,14 +END + +IDD_DIALOG4 DIALOG DISCARDABLE 0, 0, 185, 69 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "About TAPI Browser" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "OK",IDOK,69,50,50,14 + LTEXT "TAPI Browser v2.0",38,80,12,70,7 + LTEXT "Copyright (c) 1994-95 Microsoft Corporation",70,20,30,168, + 12 + ICON IDI_ICON1,IDC_STATIC1,52,5,18,20 +END + +IDD_DIALOG5 DIALOG DISCARDABLE 0, 0, 90, 69 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Displaying Icon" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "OK",IDOK,35,50,50,14 +END + +IDD_DIALOG6 DIALOG 6, 18, 192, 173 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Using the TAPI Browser" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "OK", IDOK, 66, 157, 60, 14 + EDITTEXT IDC_EDIT1, 4, 4, 184, 150, ES_MULTILINE | ES_AUTOVSCROLL | + ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL +END + +////////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Clear", IDM_CLEAR + MENUITEM SEPARATOR + MENUITEM "&Params", IDM_PARAMS + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_EXIT + END + POPUP "&Options" + BEGIN + MENUITEM "&Default values...", IDM_DEFAULTVALUES + MENUITEM SEPARATOR + MENUITEM "&User buttons...", IDM_USERBUTTONS + MENUITEM SEPARATOR + MENUITEM "Log ¶meters", IDM_DUMPPARAMS + POPUP "Log &structures" + BEGIN + MENUITEM "by &fields (all)", IDM_LOGSTRUCTALLFIELD + MENUITEM "by fields (&non-zero only)", IDM_LOGSTRUCTNONZEROFIELD + MENUITEM "by &DWORDs/ASCII", IDM_LOGSTRUCTDWORD + MENUITEM "by n&one", IDM_LOGSTRUCTNONE + END + MENUITEM SEPARATOR + MENUITEM "&Show time stamps", IDM_TIMESTAMP + MENUITEM SEPARATOR + MENUITEM "Record log &file", IDM_LOGFILE + MENUITEM SEPARATOR + MENUITEM "Auto-deallocate idle &monitored calls", IDM_NUKEIDLEMONITORCALLS + MENUITEM "Auto-deallocate idle &owned calls", IDM_NUKEIDLEOWNEDCALLS + MENUITEM SEPARATOR + MENUITEM "Disable handle checking", IDM_NOHANDLECHK + END + POPUP "&Help" + BEGIN + MENUITEM "&Using TB...", IDM_USINGTB +// help MENUITEM SEPARATOR +// help MENUITEM "&Telephony API help...\tF1", IDM_TAPIHLP +// help MENUITEM "Telephony &SPI help...", IDM_TSPIHLP + MENUITEM SEPARATOR + MENUITEM "&About TB...", IDM_ABOUT + END +END + + +////////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +IDI_ICON1 ICON DISCARDABLE "TB.ICO" + + +////////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE +BEGIN +// help VK_F1, IDC_F1HELP, VIRTKEY + VK_TAB, IDC_PREVCTRL, VIRTKEY, SHIFT + VK_TAB, IDC_NEXTCTRL, VIRTKEY + VK_RETURN, IDC_ENTER, VIRTKEY +END + + +#ifndef APSTUDIO_INVOKED +//////////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + +// ///////////////////////////////////////////////////////////////////////// +// ///////////////////////////////////////////////////////////////////////// + +#if WINNT +#include <ntverp.h> +#else +#include <ver.h> +#endif + +#define VER_FILEDESCRIPTION_STR "Microsoft\256 Windows(TM) TAPI Browser" +#if TAPI_1_1 +#if TAPI_2_0 +#define VER_INTERNALNAME_STR "tb20" +#define VER_ORIGINALFILENAME_STR "TB20.EXE" +#else +#define VER_INTERNALNAME_STR "tb14" +#define VER_ORIGINALFILENAME_STR "TB14.EXE" +#endif +#else +#define VER_INTERNALNAME_STR "tb13" +#define VER_ORIGINALFILENAME_STR "TB13.EXE" +#endif + +#define VER_LEGALCOPYRIGHT_STR "Copyright \251 Microsoft Corporation 1995. All Rights Reserved." + +#define VER_FILETYPE VFT_APP +#define VER_FILESUBTYPE VFT2_UNKNOWN + +#include <common.ver> + +// ///////////////////////////////////////////////////////////////////////// +// ///////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/private/tapi/dev/apps/tb/tb2.c b/private/tapi/dev/apps/tb/tb2.c new file mode 100644 index 000000000..242d4bd61 --- /dev/null +++ b/private/tapi/dev/apps/tb/tb2.c @@ -0,0 +1,3877 @@ +/*++ BUILD Version: 0000 // Increment this if a change has global effects + +Copyright (c) 1994-96 Microsoft Corporation + +Module Name: + + tb2.c + +Abstract: + + API wrapper code for the TAPI Browser util. Contains the big switch + statement for all the supported Telephony API's, & various support funcs. + +Author: + + Dan Knudson (DanKn) 18-Aug-1995 + +Revision History: + +--*/ + + +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <ctype.h> +#include <malloc.h> +#include "tb.h" +#include "vars.h" +#include "resource.h" + + +extern char szdwDeviceID[]; +extern char szdwSize[]; +extern char szhCall[]; +extern char szhLine[]; +extern char szhLineApp[]; +extern char szhPhone[]; +extern char szlpCallParams[]; + +extern char szlphCall[]; +extern char szlpParams[]; +extern char szhwndOwner[]; +extern char szdwAddressID[]; +extern char szlpszAppName[]; +extern char szdwAPIVersion[]; +extern char szlphConsultCall[]; +extern char szlpszDeviceClass[]; +extern char szlpszDestAddress[]; +extern char szlpsUserUserInfo[]; +extern char szlpszFriendlyAppName[]; + +char szhPhoneApp[] = "hPhoneApp"; + + +void +ShowStructByDWORDs( + LPVOID lp + ); + +void +ShowStructByField( + PSTRUCT_FIELD_HEADER pHeader, + BOOL bSubStructure + ); + +void +DumpParams( + PFUNC_PARAM_HEADER pHeader + ); + +void +ShowPhoneFuncResult( + LPSTR lpFuncName, + LONG lResult + ); + +void +ShowVARSTRING( + LPVARSTRING lpVarString + ); + +void +ShowTapiFuncResult( + LPSTR lpFuncName, + LONG lResult + ); + +VOID +UpdateWidgetListCall( + PMYCALL pCall + ); + + +// +// We get a slough of C4113 (func param lists differed) warnings down below +// in the initialization of FUNC_PARAM_HEADER structs as a result of the +// real func prototypes having params that are pointers rather than DWORDs, +// so since these are known non-interesting warnings just turn them off +// + +#pragma warning (disable:4113) + +void +FuncDriver2( + FUNC_INDEX funcIndex + ) +{ + int i; + LONG lResult; + + + switch (funcIndex) + { + case lOpen: +#if TAPI_2_0 + case lOpenW: +#endif + { + PMYLINE pNewLine; + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { szdwDeviceID, PT_DWORD, dwDefLineDeviceID, NULL }, + { "lphLine", PT_POINTER, 0, NULL }, + { szdwAPIVersion, PT_ORDINAL, dwDefLineAPIVersion, aAPIVersions }, + { "dwExtVersion", PT_DWORD, dwDefLineExtVersion, NULL }, + { "dwCallbackInstance", PT_DWORD, 0, NULL }, + { "dwPrivileges", PT_FLAGS, dwDefLinePrivilege, aLineOpenOptions }, + { "dwMediaModes", PT_FLAGS, dwDefMediaMode, aMediaModes }, + { szlpCallParams, PT_CALLPARAMS, 0, lpCallParams } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 9, funcIndex, params, (funcIndex == lOpen ? + (PFN9) lineOpen : (PFN9) lineOpenW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 9, funcIndex, params, (PFN9) lineOpen }; +#endif + + CHK_LINEAPP_SELECTED() + + if (!(pNewLine = AllocLine (pLineAppSel))) + { + MessageBeep ((UINT) -1); + ShowStr ("error creating data structure"); + break; + } + + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + params[2].dwValue = + params[2].u.dwDefValue = (DWORD) &pNewLine->hLine; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + if ((HLINEAPP) params[0].dwValue != pLineAppSel->hLineApp) + { + // + // User has switched line apps on us we need to recreate + // the line data structure under a different line app + // + + PMYLINE pNewLine2 = + AllocLine (GetLineApp((HLINEAPP)params[0].dwValue)); + + if (pNewLine2) + { + pNewLine2->hLine = pNewLine->hLine; + + FreeLine (pNewLine); + + pNewLine = pNewLine2; + } + else + { + // BUGBUG show error: couldn't alloc a new line struct + + lineClose (pNewLine->hLine); + FreeLine (pNewLine); + break; + } + } + + + // + // Save info about this line that we can display + // + + pNewLine->hLineApp = (HLINEAPP) params[0].dwValue; + pNewLine->dwDevID = params[1].dwValue; + pNewLine->dwAPIVersion = params[3].dwValue; + pNewLine->dwPrivileges = params[6].dwValue; + pNewLine->dwMediaModes = params[7].dwValue; + + //SendMessage (ghwndLines, LB_SETCURSEL, (WPARAM) i, 0); + UpdateWidgetList(); + SelectWidget ((PMYWIDGET) pNewLine); + } + else + { + FreeLine (pNewLine); + } + + break; + } + case lPark: +#if TAPI_2_0 + case lParkW: +#endif + { + char szDirAddress[MAX_STRING_PARAM_SIZE] = ""; + LPVARSTRING lpNonDirAddress = (LPVARSTRING) pBigBuf; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "dwParkMode", PT_ORDINAL, LINEPARKMODE_DIRECTED, aParkModes }, + { "lpszDirAddress", PT_STRING, (DWORD) szDirAddress, szDirAddress }, + { "lpNonDirAddress", PT_POINTER, (DWORD) lpNonDirAddress, lpNonDirAddress } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (funcIndex == lPark ? + (PFN4) linePark : (PFN4) lineParkW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) linePark }; +#endif + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + memset (lpNonDirAddress, 0, (size_t) dwBigBufSize); + lpNonDirAddress->dwTotalSize = dwBigBufSize; + + lResult = DoFunc (¶msHeader); + + break; + } + case lPickup: +#if TAPI_2_0 + case lPickupW: +#endif + { + PMYCALL pNewCall; + char szDestAddress[MAX_STRING_PARAM_SIZE]; + char szGroupID[MAX_STRING_PARAM_SIZE] = ""; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { szlphCall, PT_POINTER, 0, NULL }, + { szlpszDestAddress, PT_STRING, (DWORD) szDestAddress, szDestAddress }, + { "lpszGroupID", PT_STRING, (DWORD) szGroupID, szGroupID } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (funcIndex == lPickup ? + (PFN5) linePickup : (PFN5) linePickupW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) linePickup }; +#endif + + + CHK_LINE_SELECTED() + + + // + // Find a free entry in the call array + // + + if (!(pNewCall = AllocCall (pLineSel))) + { + break; + } + + params[0].dwValue = (DWORD) pLineSel->hLine; + params[2].dwValue = params[2].u.dwDefValue = (DWORD) &pNewCall->hCall; + + strcpy (szDestAddress, szDefDestAddress); + + if ((lResult = DoFunc (¶msHeader)) >= 0) + { + if (params[0].dwValue != (DWORD) pLineSel->hLine) + { + MoveCallToLine (pNewCall, (HLINE) params[0].dwValue); + } + + pNewCall->lMakeCallReqID = lResult; + dwNumPendingMakeCalls++; + SelectWidget ((PMYWIDGET) pNewCall); + } + else + { + FreeCall (pNewCall); + } + + break; + } + case lPrepareAddToConference: +#if TAPI_2_0 + case lPrepareAddToConferenceW: +#endif + { + PMYCALL pNewCall; + FUNC_PARAM params[] = + { + { "hConfCall", PT_DWORD, 0, NULL }, + { szlphConsultCall, PT_POINTER, 0, NULL }, + { szlpCallParams, PT_CALLPARAMS, 0, lpCallParams } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lPrepareAddToConference ? + (PFN3) linePrepareAddToConference : (PFN3) linePrepareAddToConferenceW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) linePrepareAddToConference }; +#endif + + CHK_CALL_SELECTED() + + if (!(pNewCall = AllocCall (pLineSel))) + { + break; + } + + params[0].dwValue = (DWORD) pCallSel->hCall; + params[1].dwValue = params[1].u.dwDefValue = (DWORD) &pNewCall->hCall; + + if ((lResult = DoFunc (¶msHeader)) >= 0) + { + // + // First make sure we're created the call under the right line, + // and if not move it to the right place in the widgets list + // + + LINECALLINFO callInfo; + + + memset (&callInfo, 0, sizeof(LINECALLINFO)); + callInfo.dwTotalSize = sizeof(LINECALLINFO); + if (lineGetCallInfo ((HCALL) params[0].dwValue, &callInfo) == 0) + { + if (callInfo.hLine != pLineSel->hLine) + { + MoveCallToLine (pNewCall, callInfo.hLine); + } + } + + pNewCall->lMakeCallReqID = lResult; + dwNumPendingMakeCalls++; + SelectWidget ((PMYWIDGET) pNewCall); + } + else + { + FreeCall (pNewCall); + } + + break; + } +#if TAPI_2_0 + case lProxyMessage: + { + static LOOKUP aValidProxyMsgs[] = + { + { LINE_AGENTSPECIFIC ,"AGENTSPECIFIC" }, + { LINE_AGENTSTATUS ,"AGENTSTATUS" }, + { 0xffffffff ,"" } + }; + + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, (DWORD) 0, NULL }, + { szhCall, PT_DWORD, (DWORD) 0, NULL }, + { "dwMsg", PT_ORDINAL, (DWORD) LINE_AGENTSTATUS, aValidProxyMsgs }, + { "dwParam1", PT_DWORD, (DWORD) 0, NULL }, + { "dwParam2", PT_FLAGS, (DWORD) 0, aAgentStatus }, + { "dwParam3", PT_ORDINAL, (DWORD) 0, aAgentStates } + }; + FUNC_PARAM_HEADER paramsHeader = + { 6, funcIndex, params, (PFN6) lineProxyMessage }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + if (pCallSel) + { + params[1].dwValue = (DWORD) pCallSel->hCall; + } + + DoFunc (¶msHeader); + + break; + } + case lProxyResponse: + { + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { "lpProxyBuffer", PT_DWORD, 0, NULL }, + { "dwResult", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineProxyResponse }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + DoFunc (¶msHeader); + + break; + } +#endif + case lRedirect: +#if TAPI_2_0 + case lRedirectW: +#endif + { + char szDestAddress[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { szlpszDestAddress, PT_STRING, (DWORD) szDestAddress, szDestAddress }, + { "dwCountryCode", PT_DWORD, dwDefCountryCode, NULL } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lRedirect ? + (PFN3) lineRedirect : (PFN3) lineRedirectW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineRedirect }; +#endif + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + strcpy (szDestAddress, szDefDestAddress); + + lResult = DoFunc (¶msHeader); + + break; + } + case lRegisterRequestRecipient: + { + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { "dwRegistrationInstance", PT_DWORD, 0, NULL }, + { "dwRequestMode", PT_FLAGS, LINEREQUESTMODE_MAKECALL, aRequestModes2 }, + { "bEnable", PT_DWORD, 1, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) lineRegisterRequestRecipient }; + + + CHK_LINEAPP_SELECTED() + + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + + lResult = DoFunc (¶msHeader); + + break; + } + case lRemoveFromConference: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 1, funcIndex, params, (PFN1) lineRemoveFromConference }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } + case lSecureCall: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 1, funcIndex, params, (PFN1) lineSecureCall }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } + case lSendUserUserInfo: + { + char szUserUserInfo[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { szlpsUserUserInfo, PT_STRING, (DWORD) szUserUserInfo, szUserUserInfo }, + { szdwSize, PT_DWORD, strlen(szDefUserUserInfo)+1, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineSendUserUserInfo }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + strcpy (szUserUserInfo, szDefUserUserInfo); + + lResult = DoFunc (¶msHeader); + + break; + } +#if TAPI_2_0 + case lSetAgentActivity: + { + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, 0, NULL }, + { "dwActivityID", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineSetAgentActivity }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + DoFunc (¶msHeader); + + break; + } + case lSetAgentGroup: + { + LPLINEAGENTGROUPLIST lpGroupList = (LPLINEAGENTGROUPLIST) pBigBuf; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { "lpAgentGroupList", PT_POINTER, (DWORD) lpGroupList, lpGroupList } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineGetAgentGroupList }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + +// BUGBUG SetAgentGRp: allow user to fill in agent group list + + memset (lpGroupList, 0, (size_t) dwBigBufSize); + lpGroupList->dwTotalSize = dwBigBufSize; + + DoFunc (¶msHeader); + + break; + } + case lSetAgentState: + { + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, (DWORD) 0, NULL }, + { szdwAddressID, PT_DWORD, (DWORD) 0, NULL }, + { "dwAgentState", PT_FLAGS, (DWORD) 0, aAgentStates }, + { "dwNextAgentState", PT_FLAGS, (DWORD) 0, aAgentStates } + }; + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) lineSetAgentState }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + DoFunc (¶msHeader); + + break; + } +#endif + case lSetAppSpecific: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "dwAppSpecific", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineSetAppSpecific }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } +#if TAPI_2_0 + case lSetCallData: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "lpCallData", PT_POINTER, (DWORD) pBigBuf, pBigBuf }, + { szdwSize, PT_DWORD, (DWORD) dwBigBufSize, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineSetCallData }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + DoFunc (¶msHeader); + + break; + } +#endif + case lSetCallParams: + { + LINEDIALPARAMS dialParams; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "dwBearerMode", PT_FLAGS, dwDefBearerMode, aBearerModes }, + { "dwMinRate", PT_DWORD, 3100, NULL }, + { "dwMaxRate", PT_DWORD, 3100, NULL }, + { "lpDialParams", PT_POINTER, 0, &dialParams }, + { " ->dwDialPause", PT_DWORD, 0, NULL }, + { " ->dwDialSpeed", PT_DWORD, 0, NULL }, + { " ->dwDigitDuration", PT_DWORD, 0, NULL }, + { " ->dwWaitForDialtone", PT_DWORD, 0, NULL } + + }; + FUNC_PARAM_HEADER paramsHeader = + { 9, funcIndex, params, NULL }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + dialParams.dwDialPause = params[5].dwValue; + dialParams.dwDialSpeed = params[6].dwValue; + dialParams.dwDigitDuration = params[7].dwValue; + dialParams.dwWaitForDialtone = params[8].dwValue; + + lResult = lineSetCallParams( + (HCALL) params[0].dwValue, + params[1].dwValue, + params[2].dwValue, + params[3].dwValue, + (LPLINEDIALPARAMS) params[4].dwValue + ); + + ShowLineFuncResult (aFuncNames[funcIndex], lResult); + + break; + } + case lSetCallPrivilege: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "dwCallPrivilege", PT_ORDINAL, LINECALLPRIVILEGE_OWNER, aCallPrivileges } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineSetCallPrivilege }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + if (params[0].dwValue == (DWORD) pCallSel->hCall) + { + pCallSel->bMonitor = (params[0].dwValue == + LINECALLPRIVILEGE_MONITOR ? TRUE : FALSE); + UpdateWidgetListCall (pCallSel); + } + else + { + PMYCALL pCall; + + + if ((pCall = GetCall ((HCALL) params[0].dwValue))) + { + pCall->bMonitor = (params[0].dwValue == + LINECALLPRIVILEGE_MONITOR ? TRUE : FALSE); + UpdateWidgetListCall (pCall); + } + } + } + + break; + } +#if TAPI_2_0 + case lSetCallQualityOfService: + { + char szSendingFlowspec[MAX_STRING_PARAM_SIZE] = "123"; + char szReceivingFlowspec[MAX_STRING_PARAM_SIZE] = "321"; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, (DWORD) 0, NULL }, + { "lpSendingFlowspec", PT_STRING, (DWORD) szSendingFlowspec, szSendingFlowspec }, + { "dwSendingFlowspecSize", PT_DWORD, (DWORD) 4, 0 }, + { "lpReceivingFlowspec", PT_STRING, (DWORD) szReceivingFlowspec, szReceivingFlowspec }, + { "dwReceivingFlowspecSize",PT_DWORD, (DWORD) 4, 0 } + }; + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) lineSetCallQualityOfService }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + DoFunc (¶msHeader); + + break; + } + case lSetCallTreatment: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "dwTreatment",PT_ORDINAL, LINECALLTREATMENT_SILENCE, aCallTreatments } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineSetCallTreatment }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + DoFunc (¶msHeader); + + break; + } +#endif + case lSetCurrentLocation: + { + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { "dwLocation", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineSetCurrentLocation }; + + + if (pLineAppSel) + { + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + } + + lResult = DoFunc (¶msHeader); + + break; + } + case lSetDevConfig: +#if TAPI_2_0 + case lSetDevConfigW: +#endif + { + char szDeviceClass[MAX_STRING_PARAM_SIZE]; + char szErrorMsg[] = "Bad config info in buffer"; + FUNC_PARAM params[] = + { + { szdwDeviceID, PT_DWORD, 0, NULL }, + { "lpDeviceConfig", PT_POINTER, 0, NULL }, + { szdwSize, PT_DWORD, 0, NULL }, + { szlpszDeviceClass, PT_STRING, (DWORD) szDeviceClass, szDeviceClass }, + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (funcIndex == lSetDevConfig ? + (PFN4) lineSetDevConfig : (PFN4) lineSetDevConfigW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) lineSetDevConfig }; +#endif + + // + // Check to see if there's existing config info in the global buffer + // (not a foolproof check, but good enough) + // + + ShowStr ("Call lineGetDevConfig before calling lineSetDevConfig"); + + if (dwBigBufSize >= sizeof (VARSTRING)) + { + DWORD dwMaxDataSize = dwBigBufSize - sizeof (VARSTRING); + LPVARSTRING pVarString = (LPVARSTRING) pBigBuf; + + + if (pVarString->dwStringSize > dwMaxDataSize || + + (pVarString->dwStringSize != 0 && + (pVarString->dwStringOffset < sizeof (VARSTRING) || + pVarString->dwStringOffset > + (dwBigBufSize - pVarString->dwStringSize)))) + { + ShowStr (szErrorMsg); + break; + } + + params[1].dwValue = + params[1].u.dwDefValue = (DWORD) + ((LPBYTE) pBigBuf + pVarString->dwStringOffset); + params[2].dwValue = + params[2].u.dwDefValue = pVarString->dwStringSize; + } + else + { + ShowStr (szErrorMsg); + break; + } + + strcpy (szDeviceClass, szDefLineDeviceClass); + + lResult = DoFunc (¶msHeader); + + break; + } +#if TAPI_2_0 + case lSetLineDevStatus: + { + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, (DWORD) 0, NULL }, + { "dwStatusToChange", PT_FLAGS, (DWORD) 0, aLineDevStatusFlags }, + { "fStatus", PT_DWORD, (DWORD) 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineSetLineDevStatus }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + DoFunc (¶msHeader); + + break; + } +#endif + case lSetMediaControl: + { + LINEMEDIACONTROLDIGIT aDigits[1]; + LINEMEDIACONTROLMEDIA aMedias[1]; + LINEMEDIACONTROLTONE aTones[1]; + LINEMEDIACONTROLCALLSTATE aCallSts[1]; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, 0, NULL }, + { szhCall, PT_DWORD, 0, NULL }, + { "dwSelect", PT_ORDINAL, 0, aCallSelects }, + + { "lpDigitList", PT_POINTER, (DWORD) aDigits, aDigits }, + { " ->dwDigit", PT_DWORD, (DWORD) 0, NULL }, + { " ->dwDigitModes", PT_FLAGS, (DWORD) 0, aDigitModes }, + { " ->dwMediaControl", PT_ORDINAL, (DWORD) 0, aMediaControls }, + { "dwDigitNumEntries", PT_DWORD, (DWORD) 0, NULL }, + + { "lpMediaList", PT_POINTER, (DWORD) aMedias, aMedias }, + { " ->dwMediaModes", PT_FLAGS, (DWORD) 0, aMediaModes }, + { " ->dwDuration", PT_DWORD, (DWORD) 0, 0 }, + { " ->dwMediaControl", PT_ORDINAL, (DWORD) 0, aMediaControls }, + { "dwMediaNumEntries", PT_DWORD, (DWORD) 0, NULL }, + + { "lpToneList", PT_POINTER, (DWORD) aTones, aTones }, + { " ->dwAppSpecific", PT_DWORD, (DWORD) 0, NULL }, + { " ->dwDuration", PT_DWORD, (DWORD) 0, NULL }, + { " ->dwFrequency1", PT_DWORD, (DWORD) 0, NULL }, + { " ->dwFrequency2", PT_DWORD, (DWORD) 0, NULL }, + { " ->dwFrequency3", PT_DWORD, (DWORD) 0, NULL }, + { " ->dwMediaControl", PT_ORDINAL, (DWORD) 0, aMediaControls }, + { "dwToneNumEntries", PT_DWORD, (DWORD) 0, NULL }, + + { "lpCallStateList", PT_POINTER, (DWORD) aCallSts, aCallSts }, + { " ->dwCallStates", PT_FLAGS, (DWORD) 0, aCallStates }, + { " ->dwMediaControl", PT_ORDINAL, (DWORD) 0, aMediaControls }, + { "dwCallStateNumEntries", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 26, funcIndex, params, (PFN12) lineSetMediaControl }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + if (pCallSel) + { + params[2].dwValue = (DWORD) pCallSel->hCall; + params[3].dwValue = LINECALLSELECT_CALL; + } + else + { + params[3].dwValue = LINECALLSELECT_LINE; + } + + if (LetUserMungeParams (¶msHeader)) + { + DumpParams (¶msHeader); + + lResult = lineSetMediaControl( + (HLINE) params[0].dwValue, + (DWORD) params[1].dwValue, + (HCALL) params[2].dwValue, + (DWORD) params[3].dwValue, + (LPLINEMEDIACONTROLDIGIT) params[4].dwValue, + (DWORD) params[8].dwValue, + (LPLINEMEDIACONTROLMEDIA) params[9].dwValue, + (DWORD) params[13].dwValue, + (LPLINEMEDIACONTROLTONE) params[14].dwValue, + (DWORD) params[21].dwValue, + (LPLINEMEDIACONTROLCALLSTATE) params[22].dwValue, + (DWORD) params[25].dwValue + ); + + ShowLineFuncResult (aFuncNames[funcIndex], lResult); + } + + break; + } + case lSetMediaMode: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { "dwMediaModes", PT_FLAGS, dwDefMediaMode, aMediaModes } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineSetMediaMode }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } + case lSetNumRings: + { + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { "dwNumRings", PT_DWORD, 5, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineSetNumRings }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + lResult = DoFunc (¶msHeader); + + break; + } + case lSetStatusMessages: + { + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { "dwLineStates", PT_FLAGS, 0, aLineStates }, + { "dwAddressStates", PT_FLAGS, 0, aAddressStates } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineSetStatusMessages }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + lResult = DoFunc (¶msHeader); + + break; + } + case lSetTerminal: + { + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { szhCall, PT_DWORD, 0, NULL }, + { "dwSelect", PT_ORDINAL, LINECALLSELECT_LINE, aCallSelects }, + { "dwTerminalModes", PT_FLAGS, LINETERMMODE_BUTTONS, aTerminalModes }, + { "dwTerminalID", PT_DWORD, 0, NULL }, + { "bEnable", PT_DWORD, 0, NULL }, + }; + FUNC_PARAM_HEADER paramsHeader = + { 7, funcIndex, params, (PFN7) lineSetTerminal }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + if (pCallSel) + { + params[2].dwValue = (DWORD) pCallSel->hCall; + } + + lResult = DoFunc (¶msHeader); + + break; + } + case lSetTollList: +#if TAPI_2_0 + case lSetTollListW: +#endif + { + char szAddressIn[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { szdwDeviceID, PT_DWORD, dwDefLineDeviceID, NULL }, + { "lpszAddressIn", PT_STRING, (DWORD) szAddressIn, szAddressIn }, + { "dwTollListOption", PT_FLAGS, LINETOLLLISTOPTION_ADD, aTollListOptions } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (funcIndex == lSetTollList ? + (PFN4) lineSetTollList : (PFN4) lineSetTollListW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) lineSetTollList }; +#endif + + if (pLineAppSel) + { + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + } + + strcpy (szAddressIn, szDefDestAddress); + + lResult = DoFunc (¶msHeader); + + break; + } + case lSetupConference: +#if TAPI_2_0 + case lSetupConferenceW: +#endif + { + PMYCALL pNewCall, pNewCall2; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { szhLine, PT_DWORD, 0, NULL }, + { "lphConfCall", PT_POINTER, 0, NULL }, + { szlphConsultCall, PT_POINTER, 0, NULL }, + { "dwNumParties", PT_DWORD, 3, NULL }, + { szlpCallParams, PT_CALLPARAMS, 0, lpCallParams } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 6, funcIndex, params, (funcIndex == lSetupConference ? + (PFN6) lineSetupConference : (PFN6) lineSetupConferenceW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 6, funcIndex, params, (PFN6) lineSetupConference }; +#endif + + CHK_LINE_SELECTED() + + if (!(pNewCall = AllocCall (pLineSel))) + { + break; + } + + if (!(pNewCall2 = AllocCall (pLineSel))) + { + FreeCall (pNewCall); + break; + } + + params[0].dwValue = (DWORD) (pCallSel ? pCallSel->hCall : 0); + params[1].dwValue = (DWORD) pLineSel->hLine; + params[2].dwValue = params[2].u.dwDefValue = (DWORD) &pNewCall->hCall; + params[3].dwValue = params[3].u.dwDefValue = (DWORD) &pNewCall2->hCall; + + if ((lResult = DoFunc (¶msHeader)) >= 0) + { + // + // Note that the hLine param is ignored if the hCall is non-NULL + // + + if (params[0].dwValue) + { + if (!pCallSel || + (params[0].dwValue != (DWORD) pCallSel->hCall)) + { + // + // Get the assoc pLine, if it's diff need to move new calls + // + + PMYWIDGET pWidget = aWidgets; + PMYLINE pLine = (PMYLINE) NULL; + + + while (1) + { + if ((pWidget->dwType == WT_CALL) && + (params[0].dwValue == (DWORD) + ((PMYCALL)pWidget)->hCall)) + { + break; + } + else if (pWidget->dwType == WT_LINE) + { + pLine = (PMYLINE) pWidget; + } + + pWidget = pWidget->pNext; + } + + if (pLine != pLineSel) + { + MoveCallToLine (pNewCall, pLine->hLine); + MoveCallToLine (pNewCall2, pLine->hLine); + } + } + } + else if (params[1].dwValue != (DWORD) pLineSel->hLine) + { + MoveCallToLine (pNewCall, (HLINE) params[1].dwValue); + MoveCallToLine (pNewCall2, (HLINE) params[1].dwValue); + } + + pNewCall->lMakeCallReqID = + pNewCall2->lMakeCallReqID = lResult; + dwNumPendingMakeCalls += 2; + SelectWidget ((PMYWIDGET) pNewCall); + } + else + { + FreeCall (pNewCall); + FreeCall (pNewCall2); + } + + break; + } + case lSetupTransfer: +#if TAPI_2_0 + case lSetupTransferW: +#endif + { + PMYCALL pNewCall; + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL }, + { szlphConsultCall, PT_POINTER, 0, NULL }, + { szlpCallParams, PT_CALLPARAMS, 0, lpCallParams } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lSetupTransfer ? + (PFN3) lineSetupTransfer : (PFN3) lineSetupTransferW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineSetupTransfer }; +#endif + + CHK_CALL_SELECTED() + + if (!(pNewCall = AllocCall (pLineSel))) + { + break; + } + + params[0].dwValue = (DWORD) pCallSel->hCall; + params[1].dwValue = params[1].u.dwDefValue = (DWORD) &pNewCall->hCall; + + if ((lResult = DoFunc (¶msHeader)) >= 0) + { + // + // First make sure we're created the call under the right line, + // and if not move it to the right place in the widgets list + // + + LINECALLINFO callInfo; + + + memset (&callInfo, 0, sizeof(LINECALLINFO)); + callInfo.dwTotalSize = sizeof(LINECALLINFO); + if (lineGetCallInfo ((HCALL) params[0].dwValue, &callInfo) == 0) + { + if (callInfo.hLine != pLineSel->hLine) + { + MoveCallToLine (pNewCall, callInfo.hLine); + } + } + + pNewCall->lMakeCallReqID = lResult; + dwNumPendingMakeCalls++; + SelectWidget ((PMYWIDGET) pNewCall); + } + else + { + FreeCall (pNewCall); + } + + break; + } + case lShutdown: + { + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 1, funcIndex, params, (PFN1) lineShutdown }; + + + CHK_LINEAPP_SELECTED() + + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + + lResult = DoFunc (¶msHeader); + + if (lResult == 0) + { + FreeLineApp (GetLineApp((HLINEAPP) params[0].dwValue)); + } + + break; + } + case lSwapHold: + { + FUNC_PARAM params[] = + { + { "hActiveCall", PT_DWORD, 0, NULL }, + { "hHeldCall", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineSwapHold }; + + + CHK_TWO_CALLS_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + params[1].dwValue = (DWORD) pCallSel2->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } + case lTranslateAddress: +#if TAPI_2_0 + case lTranslateAddressW: +#endif + { + char szAddressIn[MAX_STRING_PARAM_SIZE]; + LPLINETRANSLATEOUTPUT lpXlatOutput = (LPLINETRANSLATEOUTPUT) pBigBuf; + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { szdwDeviceID, PT_DWORD, dwDefLineDeviceID, NULL }, + { szdwAPIVersion, PT_ORDINAL, dwDefLineAPIVersion, aAPIVersions }, + { "lpszAddressIn", PT_STRING, (DWORD) szAddressIn, szAddressIn }, + { "dwCard", PT_DWORD, 0, NULL }, + { "dwTranslateOptions", PT_FLAGS, LINETRANSLATEOPTION_CARDOVERRIDE, aTranslateOptions }, + { "lpTranslateOutput", PT_POINTER, (DWORD) lpXlatOutput, lpXlatOutput } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 7, funcIndex, params, (funcIndex == lTranslateAddress ? + (PFN7) lineTranslateAddress : (PFN7) lineTranslateAddressW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 7, funcIndex, params, (PFN7) lineTranslateAddress }; +#endif + + if (pLineAppSel) + { + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + } + else + { + params[0].dwValue = 0; + } + + memset (lpXlatOutput, 0, (size_t) dwBigBufSize); + lpXlatOutput->dwTotalSize = dwBigBufSize; + + strcpy (szAddressIn, szDefDestAddress); + + lResult = DoFunc (¶msHeader); + + if (lResult == 0) + { + ShowStructByDWORDs (lpXlatOutput); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + STRUCT_FIELD fields[] = + { + { "dwDialableStringSize", FT_SIZE, lpXlatOutput->dwDialableStringSize, NULL }, + { "dwDialableStringOffset", FT_OFFSET, lpXlatOutput->dwDialableStringOffset, NULL }, + { "dwDisplayableStringSize", FT_SIZE, lpXlatOutput->dwDisplayableStringSize, NULL }, + { "dwDisplayableStringOffset", FT_OFFSET, lpXlatOutput->dwDisplayableStringOffset, NULL }, + { "dwCurrentCountry", FT_DWORD, lpXlatOutput->dwCurrentCountry, NULL }, + { "dwDestCountry", FT_DWORD, lpXlatOutput->dwDestCountry, NULL }, + { "dwTranslateResults", FT_FLAGS, lpXlatOutput->dwTranslateResults, aTranslateResults }, + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpXlatOutput, + "LINETRANSLATEOUTPUT", + 7, + fields + }; + + ShowStructByField (&fieldHeader, FALSE); + } + } + + break; + } + case lUncompleteCall: + { + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { "dwCompletionID", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineUncompleteCall }; + + + CHK_LINE_SELECTED() + + params[0].dwValue = (DWORD) pLineSel->hLine; + + lResult = DoFunc (¶msHeader); + + break; + } + case lUnhold: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 1, funcIndex, params, (PFN1) lineUnhold }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } + case lUnpark: +#if TAPI_2_0 + case lUnparkW: +#endif + { + PMYCALL pNewCall; + char szDestAddress[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { szhLine, PT_DWORD, 0, NULL }, + { szdwAddressID, PT_DWORD, dwDefAddressID, NULL }, + { szlphCall, PT_POINTER, 0, NULL }, + { szlpszDestAddress, PT_STRING, (DWORD) szDestAddress, szDestAddress } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (funcIndex == lUnpark ? + (PFN4) lineUnpark : (PFN4) lineUnparkW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) lineUnpark }; +#endif + + CHK_LINE_SELECTED() + + if (!(pNewCall = AllocCall (pLineSel))) + { + break; + } + + params[0].dwValue = (DWORD) pLineSel->hLine; + params[2].dwValue = params[2].u.dwDefValue = (DWORD) &pNewCall->hCall; + + strcpy (szDestAddress, szDefDestAddress); + + if ((lResult = DoFunc (¶msHeader)) >= 0) + { + if (params[0].dwValue != (DWORD) pLineSel->hLine) + { + MoveCallToLine (pNewCall, (HLINE) params[0].dwValue); + } + + pNewCall->lMakeCallReqID = lResult; + dwNumPendingMakeCalls++; + SelectWidget ((PMYWIDGET) pNewCall); + } + else + { + FreeCall (pNewCall); + } + + break; + } +#if TAPI_1_1 + case lAddProvider: +#if TAPI_2_0 + case lAddProviderW: +#endif + { +#if TAPI_2_0 + char szProviderFilename[MAX_STRING_PARAM_SIZE] = "esp32.tsp"; +#else + char szProviderFilename[MAX_STRING_PARAM_SIZE] = "esp.tsp"; +#endif + DWORD dwPermanentProviderID; + FUNC_PARAM params[] = + { + { "lpszProviderFilename", PT_STRING, (DWORD) szProviderFilename, szProviderFilename }, + { szhwndOwner, PT_DWORD, (DWORD) ghwndMain, NULL }, + { "lpdwPermanentProviderID", PT_POINTER, (DWORD) &dwPermanentProviderID, &dwPermanentProviderID } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lAddProvider ? + (PFN3) lineAddProvider : (PFN3) lineAddProviderW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineAddProvider }; +#endif + +#ifdef WIN32 + lResult = DoFunc (¶msHeader); +#else + // + // NOTE: on win16 HWNDs are 16 bits, so we've to hard code this + // + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + DumpParams (¶msHeader); + + lResult = lineAddProvider( + (LPCSTR) params[0].dwValue, + (HWND) params[1].dwValue, + (LPDWORD) params[2].dwValue + ); + + ShowLineFuncResult (aFuncNames[funcIndex], lResult); + + if (lResult == 0) + { + ShowStr ("%sdwPermanentProviderID = x%lx", szTab, dwPermanentProviderID); + } +#endif + break; + } + case lConfigDialogEdit: +#if TAPI_2_0 + case lConfigDialogEditW: +#endif + { + char szDeviceClass[MAX_STRING_PARAM_SIZE]; + char szDeviceConfigIn[MAX_STRING_PARAM_SIZE] = ""; + char szErrorMsg[] = "Bad config info in buffer"; + LPBYTE pDataIn; + LPVARSTRING lpDeviceConfigOut = (LPVARSTRING) pBigBuf; + FUNC_PARAM params[] = + { + { szdwDeviceID, PT_DWORD, (DWORD) dwDefLineDeviceID, NULL }, + { szhwndOwner, PT_DWORD, (DWORD) ghwndMain, NULL }, + { szlpszDeviceClass, PT_STRING, (DWORD) szDeviceClass, szDeviceClass }, + { "lpDeviceConfigIn", PT_POINTER, (DWORD) 0, NULL }, + { szdwSize, PT_DWORD, (DWORD) 0, NULL }, + { "lpDeviceConfigOut", PT_POINTER, (DWORD) lpDeviceConfigOut, lpDeviceConfigOut } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 6, funcIndex, params, (funcIndex == lConfigDialogEdit ? + (PFN6) lineConfigDialogEdit : (PFN6) lineConfigDialogEditW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 6, funcIndex, params, (PFN6) lineConfigDialogEdit }; +#endif + + // + // Check to see if there's existing config info in the global buffer + // (not a foolproof check, but good enough), and if so alloc an + // intermediate buffer to use for config in data & copy the + // existing data over + // + + ShowStr ("Call lineGetDevConfig before calling lineConfigDialogEdit"); + + if (dwBigBufSize >= sizeof (VARSTRING)) + { + DWORD dwMaxDataSize = dwBigBufSize - sizeof (VARSTRING); + LPVARSTRING pVarString = (LPVARSTRING) pBigBuf; + + + if (pVarString->dwStringSize > dwMaxDataSize || + + (pVarString->dwStringSize != 0 && + (pVarString->dwStringOffset < sizeof (VARSTRING) || + pVarString->dwStringOffset > + (dwBigBufSize - pVarString->dwStringSize)))) + { + ShowStr (szErrorMsg); + break; + } + + pDataIn = malloc (pVarString->dwStringSize); + + memcpy( + pDataIn, + (LPBYTE) pBigBuf + pVarString->dwStringOffset, + pVarString->dwStringSize + ); + + params[3].dwValue = + params[3].u.dwDefValue = (DWORD) pDataIn; + } + else + { + ShowStr (szErrorMsg); + break; + } + + strcpy (szDeviceClass, szDefLineDeviceClass); + + memset (lpDeviceConfigOut, 0, (size_t) dwBigBufSize); + + lpDeviceConfigOut->dwTotalSize = dwBigBufSize; + +#ifdef WIN32 + lResult = DoFunc (¶msHeader); +#else + // + // NOTE: on win16 HWNDSs are 16 bits, so we've to hard code this + // + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + DumpParams (¶msHeader); + + lResult = lineConfigDialogEdit( + params[0].dwValue, + (HWND) params[1].dwValue, + (LPCSTR) params[2].dwValue, + (LPVOID) params[3].dwValue, + params[4].dwValue, + (LPVARSTRING) params[5].dwValue + ); + + ShowLineFuncResult (aFuncNames[funcIndex], lResult); +#endif + if (lResult == 0) + { + ShowStructByDWORDs (lpDeviceConfigOut); + + ShowVARSTRING (lpDeviceConfigOut); + } + + free (pDataIn); + + break; + } + case lConfigProvider: + { + FUNC_PARAM params[] = + { + { szhwndOwner, PT_DWORD, (DWORD) ghwndMain, NULL }, + { "dwPermanentProviderID", PT_DWORD, 2, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineConfigProvider }; + + +#ifdef WIN32 + lResult = DoFunc (¶msHeader); +#else + // + // NOTE: on win16 HWNDs are 16 bits, so we've to hard code this + // + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + DumpParams (¶msHeader); + + lResult = lineConfigProvider( + (HWND) params[0].dwValue, + params[1].dwValue + ); + + ShowLineFuncResult (aFuncNames[funcIndex], lResult); +#endif + break; + } + case lGetAppPriority: +#if TAPI_2_0 + case lGetAppPriorityW: +#endif + { + DWORD dwPriority; + LINEEXTENSIONID extID; + char szAppName[MAX_STRING_PARAM_SIZE]; + LPVARSTRING lpExtName = (LPVARSTRING) pBigBuf; + FUNC_PARAM params[] = + { + { szlpszAppName, PT_STRING, (DWORD) szAppName, szAppName }, + { "dwMediaMode", PT_FLAGS, dwDefMediaMode, aMediaModes }, + { "lpExtensionID", PT_POINTER, (DWORD) &extID, &extID }, + { " ->dwExtensionID0", PT_DWORD, 0, NULL }, + { " ->dwExtensionID1", PT_DWORD, 0, NULL }, + { " ->dwExtensionID2", PT_DWORD, 0, NULL }, + { " ->dwExtensionID3", PT_DWORD, 0, NULL }, + { "dwRequestMode", PT_FLAGS, LINEREQUESTMODE_MAKECALL, aRequestModes }, + { "lpExtensionName", PT_POINTER, (DWORD) lpExtName, lpExtName }, + { "lpdwPriority", PT_POINTER, (DWORD) &dwPriority, &dwPriority } + }; + FUNC_PARAM_HEADER paramsHeader = + { 10, funcIndex, params, NULL }; + + + memset (lpExtName, 0, (size_t) dwBigBufSize); + lpExtName->dwTotalSize = dwBigBufSize; + + strcpy (szAppName, szDefAppName); + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + extID.dwExtensionID0 = params[3].dwValue; + extID.dwExtensionID1 = params[4].dwValue; + extID.dwExtensionID2 = params[5].dwValue; + extID.dwExtensionID3 = params[6].dwValue; + +#if TAPI_2_0 + if (funcIndex == lGetAppPriority) + { + lResult = lineGetAppPriority( + (LPCSTR) params[0].dwValue, + params[1].dwValue, + (LPLINEEXTENSIONID) params[2].dwValue, + params[7].dwValue, + (LPVARSTRING) params[8].dwValue, + (LPDWORD) params[9].dwValue + ); + } + else + { + if (params[0].dwValue == (DWORD) szAppName) + { + int len = strlen (szAppName) + 1; + WCHAR buf[MAX_STRING_PARAM_SIZE/2]; + + + MultiByteToWideChar( + GetACP(), + MB_PRECOMPOSED, + (LPCSTR) szAppName, + (len > MAX_STRING_PARAM_SIZE/2 ? + MAX_STRING_PARAM_SIZE/2 - 1 : -1), + buf, + MAX_STRING_PARAM_SIZE/2 + ); + + buf[MAX_STRING_PARAM_SIZE/2 - 1] = 0; + + lstrcpyW ((WCHAR *) szAppName, buf); + } + + lResult = lineGetAppPriorityW( + (LPCWSTR) params[0].dwValue, + params[1].dwValue, + (LPLINEEXTENSIONID) params[2].dwValue, + params[7].dwValue, + (LPVARSTRING) params[8].dwValue, + (LPDWORD) params[9].dwValue + ); + } +#else + lResult = lineGetAppPriority( + (LPCSTR) params[0].dwValue, + params[1].dwValue, + (LPLINEEXTENSIONID) params[2].dwValue, + params[7].dwValue, + (LPVARSTRING) params[8].dwValue, + (LPDWORD) params[9].dwValue + ); +#endif + ShowLineFuncResult (aFuncNames[funcIndex], lResult); + + if (lResult == 0) + { + ShowStr ("%sdwPriority = x%lx", szTab, dwPriority); + ShowStructByDWORDs (lpExtName); + } + + break; + } + case lGetCountry: +#if TAPI_2_0 + case lGetCountryW: +#endif + { + LPLINECOUNTRYLIST lpCountryList = (LPLINECOUNTRYLIST) pBigBuf; + FUNC_PARAM params[] = + { + { "dwCountryID", PT_DWORD, 1, NULL }, + { szdwAPIVersion, PT_ORDINAL, dwDefLineAPIVersion, aAPIVersions }, + { "lpLineCountryList", PT_POINTER, (DWORD) lpCountryList, lpCountryList } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == lGetCountry ? + (PFN3) lineGetCountry : (PFN3) lineGetCountryW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) lineGetCountry }; +#endif + + memset (lpCountryList, 0, (size_t) dwBigBufSize); + lpCountryList->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + UpdateResults (TRUE); + + ShowStructByDWORDs (lpCountryList); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + DWORD i; + LPLINECOUNTRYENTRY lpCountryEntry; + STRUCT_FIELD fields[] = + { + { "dwNumCountries", FT_DWORD, lpCountryList->dwNumCountries, NULL }, + { "dwCountryListSize", FT_DWORD, lpCountryList->dwCountryListSize, NULL }, + { "dwCountryListOffset", FT_DWORD, lpCountryList->dwCountryListOffset, NULL } + + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpCountryList, + "LINECOUNTRYLIST", + 3, + fields + }; + + + ShowStructByField (&fieldHeader, FALSE); + + lpCountryEntry = (LPLINECOUNTRYENTRY) + (((LPBYTE)lpCountryList) + + lpCountryList->dwCountryListOffset); + + for (i = 0; i < lpCountryList->dwNumCountries; i++) + { + char buf[32]; + STRUCT_FIELD fields[] = + { + { "dwCountryID", FT_DWORD, lpCountryEntry->dwCountryID, NULL }, + { "dwCountryCode", FT_DWORD, lpCountryEntry->dwCountryCode, NULL }, + { "dwNextCountryID", FT_DWORD, lpCountryEntry->dwNextCountryID, NULL }, + { "dwCountryNameSize", FT_SIZE, lpCountryEntry->dwCountryNameSize, NULL }, + { "dwCountryNameOffset", FT_OFFSET, lpCountryEntry->dwCountryNameOffset, NULL }, + { "dwSameAreaRuleSize", FT_SIZE, lpCountryEntry->dwSameAreaRuleSize, NULL }, + { "dwSameAreaRuleOffset", FT_OFFSET, lpCountryEntry->dwSameAreaRuleOffset, NULL }, + { "dwLongDistanceRuleSize", FT_SIZE, lpCountryEntry->dwLongDistanceRuleSize, NULL }, + { "dwLongDistanceRuleOffset", FT_OFFSET, lpCountryEntry->dwLongDistanceRuleOffset, NULL }, + { "dwInternationalRuleSize", FT_SIZE, lpCountryEntry->dwInternationalRuleSize, NULL }, + { "dwInternationalRuleOffset", FT_OFFSET, lpCountryEntry->dwInternationalRuleOffset, NULL } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpCountryList, // size,offset relative to ctrylist + buf, + 11, + fields + }; + + + sprintf (buf, "LINECOUNTRYENTRY[%ld]", i); + + ShowStructByField (&fieldHeader, TRUE); + + lpCountryEntry++; + } + } + + UpdateResults (FALSE); + } + + break; + } + case lGetProviderList: +#if TAPI_2_0 + case lGetProviderListW: +#endif + { + LPLINEPROVIDERLIST lpProviderList = (LPLINEPROVIDERLIST) pBigBuf; + FUNC_PARAM params[] = + { + { szdwAPIVersion, PT_ORDINAL, dwDefLineAPIVersion, aAPIVersions }, + { "lpProviderList", PT_POINTER, (DWORD) lpProviderList, lpProviderList } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (funcIndex == lGetProviderList ? + (PFN3) lineGetProviderList : (PFN3) lineGetProviderListW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN3) lineGetProviderList }; +#endif + + memset (lpProviderList, 0, (size_t) dwBigBufSize); + lpProviderList->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + UpdateResults (TRUE); + + ShowStructByDWORDs (lpProviderList); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + DWORD i; + LPLINEPROVIDERENTRY lpProviderEntry; + STRUCT_FIELD fields[] = + { + { "dwNumProviders", FT_DWORD, lpProviderList->dwNumProviders, NULL }, + { "dwProviderListSize", FT_DWORD, lpProviderList->dwProviderListSize, NULL }, + { "dwProviderListOffset", FT_DWORD, lpProviderList->dwProviderListOffset, NULL }, + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpProviderList, + "LINEPROVIDERLIST", + 3, + fields + }; + + ShowStructByField (&fieldHeader, FALSE); + + lpProviderEntry = (LPLINEPROVIDERENTRY) + (((LPBYTE) lpProviderList) + + lpProviderList->dwProviderListOffset); + + for (i = 0; i < lpProviderList->dwNumProviders; i++) + { + char buf[32]; + STRUCT_FIELD fields[] = + { + { "dwPermanentProviderID", FT_DWORD, lpProviderEntry->dwPermanentProviderID, NULL }, + { "dwProviderFilenameSize", FT_SIZE, lpProviderEntry->dwProviderFilenameSize, NULL }, + { "dwProviderFilenameOffset", FT_OFFSET, lpProviderEntry->dwProviderFilenameOffset, NULL } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpProviderList, // size,offset relative to ctrylist + buf, + 3, + fields + }; + + + sprintf (buf, "LINEPROVIDERENTRY[%ld]", i); + + ShowStructByField (&fieldHeader, TRUE); + + lpProviderEntry++; + } + + } + + UpdateResults (FALSE); + } + + break; + } + case lReleaseUserUserInfo: + { + FUNC_PARAM params[] = + { + { szhCall, PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 1, funcIndex, params, (PFN1) lineReleaseUserUserInfo }; + + + CHK_CALL_SELECTED() + + params[0].dwValue = (DWORD) pCallSel->hCall; + + lResult = DoFunc (¶msHeader); + + break; + } + case lRemoveProvider: + { + FUNC_PARAM params[] = + { + { "dwPermanentProviderID", PT_DWORD, 2, NULL }, + { szhwndOwner, PT_DWORD, (DWORD) ghwndMain, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) lineRemoveProvider }; + + +#ifdef WIN32 + lResult = DoFunc (¶msHeader); +#else + // + // NOTE: on win16 HWNDs are 16 bits, so we've to hard code this + // + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + DumpParams (¶msHeader); + + lResult = lineRemoveProvider( + params[0].dwValue, + (HWND) params[1].dwValue + ); + + ShowLineFuncResult (aFuncNames[funcIndex], lResult); +#endif + break; + } + case lSetAppPriority: +#if TAPI_2_0 + case lSetAppPriorityW: +#endif + { + char szAppName[MAX_STRING_PARAM_SIZE]; + char szExtName[MAX_STRING_PARAM_SIZE] = ""; + LINEEXTENSIONID extID; + FUNC_PARAM params[] = + { + { szlpszAppName, PT_STRING, (DWORD) szAppName, szAppName }, + { "dwMediaMode", PT_FLAGS, dwDefMediaMode, aMediaModes }, + { "lpExtensionID", PT_POINTER, (DWORD) &extID, &extID }, + { " ->dwExtensionID0", PT_DWORD, 0, NULL }, + { " ->dwExtensionID1", PT_DWORD, 0, NULL }, + { " ->dwExtensionID2", PT_DWORD, 0, NULL }, + { " ->dwExtensionID3", PT_DWORD, 0, NULL }, + { "dwRequestMode", PT_FLAGS, LINEREQUESTMODE_MAKECALL, aRequestModes }, + { "lpszExtensionName", PT_STRING, (DWORD) szExtName, szExtName }, + { "dwPriority", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 10, funcIndex, params, NULL }; + + + strcpy (szAppName, szDefAppName); + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + extID.dwExtensionID0 = params[3].dwValue; + extID.dwExtensionID1 = params[4].dwValue; + extID.dwExtensionID2 = params[5].dwValue; + extID.dwExtensionID3 = params[6].dwValue; + +#if TAPI_2_0 + if (funcIndex == lSetAppPriority) + { + lResult = lineSetAppPriority( + (LPCSTR) params[0].dwValue, + params[1].dwValue, + (LPLINEEXTENSIONID) params[2].dwValue, + params[7].dwValue, + (LPCSTR) params[8].dwValue, + params[9].dwValue + ); + } + else + { + if (params[0].dwValue == (DWORD) szAppName) + { + int len = strlen (szAppName) + 1; + WCHAR buf[MAX_STRING_PARAM_SIZE/2]; + + + MultiByteToWideChar( + GetACP(), + MB_PRECOMPOSED, + (LPCSTR) szAppName, + (len > MAX_STRING_PARAM_SIZE/2 ? + MAX_STRING_PARAM_SIZE/2 - 1 : -1), + buf, + MAX_STRING_PARAM_SIZE/2 + ); + + buf[MAX_STRING_PARAM_SIZE/2 - 1] = 0; + + lstrcpyW ((WCHAR *) szAppName, buf); + } + + lResult = lineSetAppPriorityW( + (LPCWSTR) params[0].dwValue, + params[1].dwValue, + (LPLINEEXTENSIONID) params[2].dwValue, + params[7].dwValue, + (LPCWSTR) params[8].dwValue, + params[9].dwValue + ); + } +#else + lResult = lineSetAppPriority( + (LPCSTR) params[0].dwValue, + params[1].dwValue, + (LPLINEEXTENSIONID) params[2].dwValue, + params[7].dwValue, + (LPCSTR) params[8].dwValue, + params[9].dwValue + ); +#endif + ShowLineFuncResult (aFuncNames[funcIndex], lResult); + + break; + } + case lTranslateDialog: +#if TAPI_2_0 + case lTranslateDialogW: +#endif + { + char szAddressIn[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { szhLineApp, PT_DWORD, 0, NULL }, + { szdwDeviceID, PT_DWORD, dwDefLineDeviceID, NULL }, + { szdwAPIVersion, PT_ORDINAL, dwDefLineAPIVersion, aAPIVersions }, + { szhwndOwner, PT_DWORD, (DWORD) ghwndMain, 0 }, + { "lpszAddressIn", PT_STRING, (DWORD) szAddressIn, szAddressIn } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (funcIndex == lTranslateDialog ? + (PFN5) lineTranslateDialog : (PFN5) lineTranslateDialogW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) lineTranslateDialog }; +#endif + + if (pLineAppSel) + { + params[0].dwValue = (DWORD) pLineAppSel->hLineApp; + } + + strcpy (szAddressIn, szDefDestAddress); + +#ifdef WIN32 + lResult = DoFunc (¶msHeader); +#else + // + // NOTE: on win16 HWNDs are 16 bits, so we've to hard code this + // + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + DumpParams (¶msHeader); + + lResult = lineTranslateDialog( + (HLINEAPP) params[0].dwValue, + params[1].dwValue, + params[2].dwValue, + (HWND) params[3].dwValue, + (LPCSTR) params[4].dwValue + ); + + ShowLineFuncResult (aFuncNames[funcIndex], lResult); +#endif + break; + } +#endif // TAPI_1_1 + case pClose: + { + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 1, funcIndex, params, (PFN1) phoneClose }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + if ((lResult = DoFunc(¶msHeader)) == 0) + { + FreePhone (GetPhone((HPHONE) params[0].dwValue)); + + // Try to auto select the next valid hPhone in the list + } + + break; + } + case pConfigDialog: +#if TAPI_2_0 + case pConfigDialogW: +#endif + { + char szDeviceClass[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { szdwDeviceID, PT_DWORD, dwDefPhoneDeviceID, NULL }, + { szhwndOwner, PT_DWORD, (DWORD) ghwndMain, NULL }, + { szlpszDeviceClass, PT_STRING, (DWORD) szDeviceClass, szDeviceClass } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == pConfigDialog ? + (PFN3) phoneConfigDialog : (PFN3) phoneConfigDialogW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneConfigDialog }; +#endif + + CHK_PHONEAPP_SELECTED() + + strcpy (szDeviceClass, szDefPhoneDeviceClass); + +#ifdef WIN32 + lResult = DoFunc (¶msHeader); +#else + // + // NOTE: on win16 HWNDSs are 16 bits, so we've to hard code this + // + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + DumpParams (¶msHeader); + + lResult = phoneConfigDialog( + params[0].dwValue, + (HWND) params[1].dwValue, + (LPCSTR) params[2].dwValue + ); + + ShowPhoneFuncResult (aFuncNames[funcIndex], lResult); +#endif + break; + } + case pDevSpecific: + { + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { szlpParams, PT_STRING, (DWORD) pBigBuf, pBigBuf }, + { szdwSize, PT_DWORD, dwBigBufSize, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneDevSpecific }; + + + CHK_PHONE_SELECTED() + + memset (pBigBuf, 0, (size_t) dwBigBufSize); + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + DoFunc (¶msHeader); + + break; + } + case pGetButtonInfo: +#if TAPI_2_0 + case pGetButtonInfoW: +#endif + { + LPPHONEBUTTONINFO lpButtonInfo = (LPPHONEBUTTONINFO) pBigBuf; + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwButtonLampID", PT_DWORD, 0, NULL }, + { "lpButtonInfo", PT_POINTER, (DWORD) lpButtonInfo, lpButtonInfo } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == pGetButtonInfo ? + (PFN3) phoneGetButtonInfo : (PFN3) phoneGetButtonInfoW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneGetButtonInfo }; +#endif + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + memset (pBigBuf, 0, (size_t) dwBigBufSize); + lpButtonInfo->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpButtonInfo); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + STRUCT_FIELD fields[] = + { + { "dwButtonMode", FT_FLAGS, lpButtonInfo->dwButtonMode, aButtonModes }, + { "dwButtonFunction", FT_FLAGS, lpButtonInfo->dwButtonFunction, aButtonFunctions }, + { "dwButtonTextSize", FT_SIZE, lpButtonInfo->dwButtonTextSize, NULL }, + { "dwButtonTextOffset", FT_OFFSET, lpButtonInfo->dwButtonTextOffset, NULL }, + { "dwDevSpecificSize", FT_SIZE, lpButtonInfo->dwDevSpecificSize, NULL }, + { "dwDevSpecificOffset", FT_OFFSET, lpButtonInfo->dwDevSpecificOffset, NULL } +#if TAPI_1_1 + , + { "dwButtonState", FT_FLAGS, lpButtonInfo->dwButtonState, aButtonStates } +#endif + + + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpButtonInfo, + "PHONEBUTTONINFO", +#if TAPI_1_1 + 7, +#else + 6, +#endif + fields + }; + +#if TAPI_1_1 + + // BUGBUG only show v1.0 fields if APIver == 0x10003 + // fieldHeader.dwNumFields--; +#endif + ShowStructByField (&fieldHeader, FALSE); + } + } + + break; + } + case pGetData: + { + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwDataID", PT_DWORD, 0, NULL }, + { "lpData", PT_POINTER, (DWORD) pBigBuf, pBigBuf }, + { szdwSize, PT_DWORD, (dwBigBufSize > 64 ? 64 : dwBigBufSize), 0} + }; + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) phoneGetData }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowBytes( + (dwBigBufSize > params[3].dwValue ? + params[3].dwValue : dwBigBufSize), + pBigBuf, + 0 + ); + } + + break; + } + case pGetDevCaps: +#if TAPI_2_0 + case pGetDevCapsW: +#endif + { + LPPHONECAPS lpDevCaps = (LPPHONECAPS) pBigBuf; + FUNC_PARAM params[] = + { + { szhPhoneApp, PT_DWORD, 0, NULL }, + { szdwDeviceID, PT_DWORD, dwDefPhoneDeviceID, NULL }, + { szdwAPIVersion, PT_ORDINAL, dwDefPhoneAPIVersion, aAPIVersions }, + { "dwExtVersion", PT_DWORD, dwDefPhoneExtVersion, NULL }, + { "lpPhoneDevCaps", PT_POINTER, (DWORD) lpDevCaps, lpDevCaps } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) phoneGetDevCaps }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (funcIndex == pGetDevCaps ? + (PFN5) phoneGetDevCaps : (PFN5) phoneGetDevCapsW ) }; +#endif + + CHK_PHONEAPP_SELECTED() + + params[0].dwValue = (DWORD) pPhoneAppSel->hPhoneApp; + + memset (lpDevCaps, 0, (size_t) dwBigBufSize); + lpDevCaps->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpDevCaps); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + STRUCT_FIELD fields[] = + { + { "dwProviderInfoSize", FT_SIZE, lpDevCaps->dwProviderInfoSize, NULL }, + { "dwProviderInfoOffset", FT_OFFSET, lpDevCaps->dwProviderInfoOffset, NULL }, + { "dwPhoneInfoSize", FT_SIZE, lpDevCaps->dwPhoneInfoSize, NULL }, + { "dwPhoneInfoOffset", FT_OFFSET, lpDevCaps->dwPhoneInfoOffset, NULL }, + { "dwPermanentPhoneID", FT_DWORD, lpDevCaps->dwPermanentPhoneID, NULL }, + { "dwPhoneNameSize", FT_SIZE, lpDevCaps->dwPhoneNameSize, NULL }, + { "dwPhoneNameOffset", FT_OFFSET, lpDevCaps->dwPhoneNameOffset, NULL }, + { "dwStringFormat", FT_ORD, lpDevCaps->dwStringFormat, aStringFormats }, + { "dwPhoneStates", FT_FLAGS, lpDevCaps->dwPhoneStates, aPhoneStates }, + { "dwHookSwitchDevs", FT_FLAGS, lpDevCaps->dwHookSwitchDevs, aHookSwitchDevs }, + { "dwHandsetHookSwitchModes", FT_FLAGS, lpDevCaps->dwHandsetHookSwitchModes, aHookSwitchModes }, + { "dwSpeakerHookSwitchModes", FT_FLAGS, lpDevCaps->dwSpeakerHookSwitchModes, aHookSwitchModes }, + { "dwHeadsetHookSwitchModes", FT_FLAGS, lpDevCaps->dwHeadsetHookSwitchModes, aHookSwitchModes }, + { "dwVolumeFlags", FT_FLAGS, lpDevCaps->dwVolumeFlags, aHookSwitchDevs }, + { "dwGainFlags", FT_FLAGS, lpDevCaps->dwGainFlags, aHookSwitchDevs }, + { "dwDisplayNumRows", FT_DWORD, lpDevCaps->dwDisplayNumRows, NULL }, + { "dwDisplayNumColumns", FT_DWORD, lpDevCaps->dwDisplayNumColumns, NULL }, + { "dwNumRingModes", FT_DWORD, lpDevCaps->dwNumRingModes, NULL }, + { "dwNumButtonLamps", FT_DWORD, lpDevCaps->dwNumButtonLamps, NULL }, + { "dwButtonModesSize", FT_SIZE, lpDevCaps->dwButtonModesSize, NULL }, + { "dwButtonModesOffset", FT_OFFSET, lpDevCaps->dwButtonModesOffset, NULL }, + { "dwButtonFunctionsSize", FT_SIZE, lpDevCaps->dwButtonFunctionsSize, NULL }, + { "dwButtonFunctionsOffset", FT_OFFSET, lpDevCaps->dwButtonFunctionsOffset, NULL }, + { "dwLampModesSize", FT_SIZE, lpDevCaps->dwLampModesSize, NULL }, + { "dwLampModesOffset", FT_OFFSET, lpDevCaps->dwLampModesOffset, NULL }, + { "dwNumSetData", FT_DWORD, lpDevCaps->dwNumSetData, NULL }, + { "dwSetDataSize", FT_SIZE, lpDevCaps->dwSetDataSize, NULL }, + { "dwSetDataOffset", FT_OFFSET, lpDevCaps->dwSetDataOffset, NULL }, + { "dwNumGetData", FT_DWORD, lpDevCaps->dwNumGetData, NULL }, + { "dwGetDataSize", FT_SIZE, lpDevCaps->dwGetDataSize, NULL }, + { "dwGetDataOffset", FT_OFFSET, lpDevCaps->dwGetDataOffset, NULL }, + { "dwDevSpecificSize", FT_SIZE, lpDevCaps->dwDevSpecificSize, NULL }, + { "dwDevSpecificOffset", FT_OFFSET, lpDevCaps->dwDevSpecificOffset, NULL } +#if TAPI_2_0 + , + { "dwDeviceClassesSize", FT_SIZE, 0, NULL }, + { "dwDeviceClassesOffset", FT_OFFSET, 0, NULL }, + { "dwPhoneFeatures", FT_FLAGS, 0, aPhoneFeatures }, + { "dwSettableHandsetHookSwitchModes", FT_FLAGS, 0, aHookSwitchModes }, + { "dwSettableSpeakerHookSwitchModes", FT_FLAGS, 0, aHookSwitchModes }, + { "dwSettableHeadsetHookSwitchModes", FT_FLAGS, 0, aHookSwitchModes }, + { "dwMonitoredHandsetHookSwitchModes", FT_FLAGS, 0, aHookSwitchModes }, + { "dwMonitoredSpeakerHookSwitchModes", FT_FLAGS, 0, aHookSwitchModes }, + { "dwMonitoredHeadsetHookSwitchModes", FT_FLAGS, 0, aHookSwitchModes } +#endif + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpDevCaps, "PHONECAPS", 0, fields + }; + + + if (params[2].dwValue < 0x00020000) + { + fieldHeader.dwNumFields = 33; + } +#if TAPI_2_0 + else + { + fieldHeader.dwNumFields = 42; + + fields[33].dwValue = lpDevCaps->dwDeviceClassesSize; + fields[34].dwValue = lpDevCaps->dwDeviceClassesOffset; + fields[35].dwValue = lpDevCaps->dwPhoneFeatures; + fields[36].dwValue = lpDevCaps->dwSettableHandsetHookSwitchModes; + fields[37].dwValue = lpDevCaps->dwSettableSpeakerHookSwitchModes; + fields[38].dwValue = lpDevCaps->dwSettableHeadsetHookSwitchModes; + fields[39].dwValue = lpDevCaps->dwMonitoredHandsetHookSwitchModes; + fields[40].dwValue = lpDevCaps->dwMonitoredSpeakerHookSwitchModes; + fields[41].dwValue = lpDevCaps->dwMonitoredHeadsetHookSwitchModes; + } +#endif + + ShowStructByField (&fieldHeader, FALSE); + } + } + + break; + } + case pGetDisplay: + { + LPVARSTRING lpDisplay = (LPVARSTRING) pBigBuf; + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "lpDisplay", PT_POINTER, (DWORD) lpDisplay, lpDisplay } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) phoneGetDisplay }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + memset (pBigBuf, 0, (size_t) dwBigBufSize); + lpDisplay->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpDisplay); + + ShowVARSTRING (lpDisplay); + } + + break; + } + case pGetGain: + { + DWORD dwGain; + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwHookSwitchDev", PT_ORDINAL, PHONEHOOKSWITCHDEV_HANDSET, aHookSwitchDevs }, + { "lpdwGain", PT_POINTER, (DWORD) &dwGain, &dwGain } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneGetGain }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + if (DoFunc (¶msHeader) == 0) + { + ShowStr ("%sdwGain=x%lx", szTab, dwGain); + } + + break; + } + case pGetHookSwitch: + { + DWORD dwHookSwitchDevs; + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "lpdwHookSwitchDevs", PT_POINTER, (DWORD) &dwHookSwitchDevs, &dwHookSwitchDevs }, + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) phoneGetHookSwitch }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + if (DoFunc (¶msHeader) == 0) + { + char szDevsOnHook[32] = ""; + char szDevsOffHook[32] = ""; + + if (dwHookSwitchDevs & PHONEHOOKSWITCHDEV_HANDSET) + { + strcat (szDevsOffHook, "HANDSET "); + } + else + { + strcat (szDevsOnHook, "HANDSET "); + } + + if (dwHookSwitchDevs & PHONEHOOKSWITCHDEV_SPEAKER) + { + strcat (szDevsOffHook, "SPEAKER "); + } + else + { + strcat (szDevsOnHook, "SPEAKER "); + } + + if (dwHookSwitchDevs & PHONEHOOKSWITCHDEV_HEADSET) + { + strcat (szDevsOffHook, "HEADSET"); + } + else + { + strcat (szDevsOnHook, "HEADSET"); + } + + ShowStr ("%sOn hook : %s", szTab, szDevsOnHook); + ShowStr ("%sOff hook: %s", szTab, szDevsOffHook); + } + + break; + } + case pGetIcon: +#if TAPI_2_0 + case pGetIconW: +#endif + { + char szDeviceClass[MAX_STRING_PARAM_SIZE]; + HICON hIcon; + FUNC_PARAM params[] = + { + { szdwDeviceID, PT_DWORD, dwDefPhoneDeviceID, NULL }, + { szlpszDeviceClass, PT_STRING, (DWORD) szDeviceClass, szDeviceClass }, + { "lphIcon", PT_POINTER, (DWORD) &hIcon, &hIcon } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == pGetIcon ? + (PFN3) phoneGetIcon : (PFN3) phoneGetIconW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneGetIcon }; +#endif + + strcpy (szDeviceClass, szDefPhoneDeviceClass); + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + DialogBoxParam ( + ghInst, + (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG5), + (HWND) ghwndMain, + (DLGPROC) IconDlgProc, + (LPARAM) hIcon + ); + } + + break; + } + case pGetID: +#if TAPI_2_0 + case pGetIDW: +#endif + { + char szDeviceClass[MAX_STRING_PARAM_SIZE]; + LPVARSTRING lpDevID = (LPVARSTRING) pBigBuf; + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "lpDeviceID", PT_POINTER, (DWORD) lpDevID, lpDevID }, + { szlpszDeviceClass, PT_STRING, (DWORD) szDeviceClass, szDeviceClass } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (funcIndex == pGetID ? + (PFN3) phoneGetID : (PFN3) phoneGetIDW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneGetID }; +#endif + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + memset (lpDevID, 0, (size_t) dwBigBufSize); + lpDevID->dwTotalSize = dwBigBufSize; + + strcpy (szDeviceClass, szDefPhoneDeviceClass); + + if (DoFunc (¶msHeader) == 0) + { + ShowStructByDWORDs (lpDevID); + + ShowVARSTRING (lpDevID); + } + + break; + } + case pGetLamp: + { + DWORD dwLampMode; + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwButtonLampID", PT_DWORD, 0, NULL }, + { "lpdwLampMode", PT_POINTER, (DWORD) &dwLampMode, &dwLampMode } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneGetLamp }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + if (DoFunc (¶msHeader) == 0) + { + int i; + + for (i = 0; aLampModes[i].dwVal != 0xffffffff; i++) + { + if (dwLampMode == aLampModes[i].dwVal) + { + ShowStr ("%slamp mode = %s", szTab, aLampModes[i].lpszVal); + break; + } + } + + if (aLampModes[i].dwVal == 0xffffffff) + { + ShowStr ("%sdwLampMode=%xlx (invalid)", szTab, dwLampMode); + } + } + + break; + } +#if TAPI_2_0 + case pGetMessage: + { + PHONEMESSAGE msg; + FUNC_PARAM params[] = + { + { szhPhoneApp, PT_DWORD, 0, NULL }, + { "lpMessage", PT_POINTER, (DWORD) &msg, &msg }, + { "dwTimeout", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, NULL }; + + + CHK_PHONEAPP_SELECTED() + + params[0].dwValue = (DWORD) pPhoneAppSel->hPhoneApp; + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + // Max timeout of 2 seconds (don't want to hang app & excite user) + + params[2].dwValue = (params[2].dwValue > 2000 ? + 2000 : params[2].dwValue); + + DumpParams (¶msHeader); + + lResult = phoneGetMessage( + (HPHONEAPP) params[0].dwValue, + (LPPHONEMESSAGE) params[1].dwValue, + (DWORD) params[2].dwValue + ); + + ShowPhoneFuncResult (aFuncNames[funcIndex], lResult); + + if (lResult == 0) + { + tapiCallback( + msg.hDevice, + msg.dwMessageID, + msg.dwCallbackInstance, + msg.dwParam1, + msg.dwParam2, + msg.dwParam3 + ); + } + + break; + } +#endif + case pGetRing: + { + DWORD dwRingMode, dwVolume; + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "lpdwRingMode", PT_POINTER, (DWORD) &dwRingMode, &dwRingMode }, + { "lpdwVolume", PT_POINTER, (DWORD) &dwVolume, &dwVolume } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneGetRing }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + if (DoFunc (¶msHeader) == 0) + { + ShowStr( + "%sdwRingMode=x%lx, dwVolume=x%lx", + szTab, + dwRingMode, + dwVolume + ); + } + + break; + } + case pGetStatus: +#if TAPI_2_0 + case pGetStatusW: +#endif + { + LPPHONESTATUS lpPhoneStatus = (LPPHONESTATUS) pBigBuf; + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "lpPhoneStatus", PT_POINTER, (DWORD) lpPhoneStatus, lpPhoneStatus } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (funcIndex == pGetStatus ? + (PFN2) phoneGetStatus : (PFN2) phoneGetStatusW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) phoneGetStatus }; +#endif + DWORD dwAPIVersion; + + + CHK_PHONE_SELECTED() + + dwAPIVersion = pPhoneSel->dwAPIVersion; + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + memset (pBigBuf, 0, (size_t) dwBigBufSize); + lpPhoneStatus->dwTotalSize = dwBigBufSize; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStructByDWORDs (lpPhoneStatus); + + if (dwDumpStructsFlags & DS_NONZEROFIELDS) + { + STRUCT_FIELD fields[] = + { + { "dwStatusFlags", FT_FLAGS, lpPhoneStatus->dwStatusFlags, aPhoneStatusFlags }, + { "dwNumOwners", FT_DWORD, lpPhoneStatus->dwNumOwners, NULL }, + { "dwNumMonitors", FT_DWORD, lpPhoneStatus->dwNumMonitors, NULL }, + { "dwRingMode", FT_DWORD, lpPhoneStatus->dwRingMode, NULL }, + { "dwRingVolume", FT_DWORD, lpPhoneStatus->dwRingVolume, NULL }, + { "dwHandsetHookSwitchMode", FT_FLAGS, lpPhoneStatus->dwHandsetHookSwitchMode, aHookSwitchModes }, + { "dwHandsetVolume", FT_DWORD, lpPhoneStatus->dwHandsetVolume, NULL }, + { "dwHandsetGain", FT_DWORD, lpPhoneStatus->dwHandsetGain, NULL }, + { "dwSpeakerHookSwitchMode", FT_FLAGS, lpPhoneStatus->dwSpeakerHookSwitchMode, aHookSwitchModes }, + { "dwSpeakerVolume", FT_DWORD, lpPhoneStatus->dwSpeakerVolume, NULL }, + { "dwSpeakerGain", FT_DWORD, lpPhoneStatus->dwSpeakerGain, NULL }, + { "dwHeadsetHookSwitchMode", FT_FLAGS, lpPhoneStatus->dwHeadsetHookSwitchMode, aHookSwitchModes }, + { "dwHeadsetVolume", FT_DWORD, lpPhoneStatus->dwHeadsetVolume, NULL }, + { "dwHeadsetGain", FT_DWORD, lpPhoneStatus->dwHeadsetGain, NULL }, + { "dwDisplaySize", FT_SIZE, lpPhoneStatus->dwDisplaySize, NULL }, + { "dwDisplayOffset", FT_OFFSET, lpPhoneStatus->dwDisplayOffset, NULL }, + { "dwLampModesSize", FT_SIZE, lpPhoneStatus->dwLampModesSize, NULL }, + { "dwLampModesOffset", FT_OFFSET, lpPhoneStatus->dwLampModesOffset, NULL }, + { "dwOwnerNameSize", FT_SIZE, lpPhoneStatus->dwOwnerNameSize, NULL }, + { "dwOwnerNameOffset", FT_OFFSET, lpPhoneStatus->dwOwnerNameOffset, NULL }, + { "dwDevSpecificSize", FT_SIZE, lpPhoneStatus->dwDevSpecificSize, NULL }, + { "dwDevSpecificOffset", FT_OFFSET, lpPhoneStatus->dwDevSpecificOffset, NULL } +#if TAPI_2_0 + , + { "dwPhoneFeatures", FT_FLAGS, 0, aPhoneFeatures } +#endif + }; + STRUCT_FIELD_HEADER fieldHeader = + { + lpPhoneStatus, "PHONESTATUS", 0, fields + }; + + + if (dwAPIVersion < 0x00020000) + { + fieldHeader.dwNumFields = 22; + } +#if TAPI_2_0 + else + { + fieldHeader.dwNumFields = 23; + + fields[22].dwValue = lpPhoneStatus->dwPhoneFeatures; + } +#endif + ShowStructByField (&fieldHeader, FALSE); + } + } + + break; + } + case pGetStatusMessages: + { + DWORD aFlags[3]; + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "lpdwPhoneStates", PT_POINTER, (DWORD) &aFlags[0], &aFlags[0] }, + { "lpdwButtonModes", PT_POINTER, (DWORD) &aFlags[1], &aFlags[1] }, + { "lpdwButtonStates", PT_POINTER, (DWORD) &aFlags[2], &aFlags[2] } + }; + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) phoneGetStatusMessages }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + if (DoFunc (¶msHeader) == 0) + { + STRUCT_FIELD fields[] = + { + { "dwPhoneStates", FT_FLAGS, aFlags[0], aPhoneStates }, + { "dwButtonModes", FT_FLAGS, aFlags[1], aButtonModes }, + { "dwButtonStates", FT_FLAGS, aFlags[2], aButtonStates } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + aFlags, + "", + 3, + fields + }; + + + ShowStructByField (&fieldHeader, TRUE); + } + + break; + } + case pGetVolume: + { + DWORD dwVolume; + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwHookSwitchDev", PT_ORDINAL, PHONEHOOKSWITCHDEV_HANDSET, aHookSwitchDevs }, + { "lpdwVolume", PT_POINTER, (DWORD) &dwVolume, &dwVolume } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneGetVolume }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + if (DoFunc (¶msHeader) == 0) + { + ShowStr ("%sdwVolume=x%lx", szTab, dwVolume); + } + + break; + } + case pInitialize: + { + DWORD dwNumDevs; + PMYPHONEAPP pNewPhoneApp; + char szAppName[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { "lphPhoneApp", PT_POINTER, 0, NULL }, + { "hInstance", PT_DWORD, (DWORD) ghInst, NULL }, + { "lpfnCallback", PT_POINTER, (DWORD) tapiCallback, tapiCallback }, + { szlpszAppName, PT_STRING, (DWORD) szAppName, szAppName }, + { "lpdwNumDevs", PT_POINTER, (DWORD) &dwNumDevs, &dwNumDevs } + }; + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) phoneInitialize }; + + + if (!(pNewPhoneApp = AllocPhoneApp())) + { + MessageBeep ((UINT) -1); + ShowStr ("error creating data structure"); + break; + } + + params[0].dwValue = + params[0].u.dwDefValue = (DWORD) &pNewPhoneApp->hPhoneApp; + + strcpy (szAppName, szDefAppName); + +#ifdef WIN32 + lResult = DoFunc (¶msHeader); +#else + // + // NOTE: on win16 HINSTANCEs are 16 bits, so we've to hard code this + // + + if (!LetUserMungeParams (¶msHeader)) + { + FreePhoneApp (pNewPhoneApp); + break; + } + + DumpParams (¶msHeader); + + lResult = phoneInitialize( + (LPHPHONEAPP) params[0].dwValue, + (HINSTANCE) params[1].dwValue, + (PHONECALLBACK) params[2].dwValue, + (LPCSTR) params[3].dwValue, + (LPDWORD) params[4].dwValue + ); + + ShowPhoneFuncResult (aFuncNames[funcIndex], lResult); +#endif // WIN32 + if (lResult == 0) + { + ShowStr ("%snum phone devs=%ld", szTab, dwNumDevs); + UpdateWidgetList(); + gdwNumPhoneDevs = dwNumDevs; + SelectWidget ((PMYWIDGET) pNewPhoneApp); + } + else + { + FreePhoneApp (pNewPhoneApp); + } + + break; + } +#if TAPI_2_0 + case pInitializeEx: + case pInitializeExW: + { + char szAppName[MAX_STRING_PARAM_SIZE]; + DWORD dwNumDevs, dwAPIVersion; + PMYPHONEAPP pNewPhoneApp; + PHONEINITIALIZEEXPARAMS initExParams; + FUNC_PARAM params[] = + { + { "lphPhoneApp", PT_POINTER, 0, NULL }, + { "hInstance", PT_DWORD, (DWORD) ghInst, NULL }, + { "lpfnCallback", PT_POINTER, (DWORD) tapiCallback, tapiCallback }, + { szlpszFriendlyAppName,PT_STRING, (DWORD) szAppName, szAppName }, + { "lpdwNumDevs", PT_POINTER, (DWORD) &dwNumDevs, &dwNumDevs }, + { "lpdwAPIVersion", PT_POINTER, (DWORD) &dwAPIVersion, &dwAPIVersion }, + { " ->dwAPIVersion",PT_ORDINAL,(DWORD) 0x00020000, aAPIVersions }, + { "lpInitExParams", PT_POINTER, (DWORD) &initExParams, &initExParams }, + { " ->dwOptions", PT_ORDINAL, (DWORD) PHONEINITIALIZEEXOPTION_USECOMPLETIONPORT, aInitExOptions } + }; + FUNC_PARAM_HEADER paramsHeader = + { 9, funcIndex, params, NULL }; + + + if (!(pNewPhoneApp = AllocPhoneApp())) + { + MessageBeep ((UINT) -1); + ShowStr ("error creating data structure"); + break; + } + + params[0].dwValue = + params[0].u.dwDefValue = (DWORD) &pNewPhoneApp->hPhoneApp; + + strcpy (szAppName, szDefAppName); + + if (!LetUserMungeParams (¶msHeader)) + { + FreePhoneApp (pNewPhoneApp); + + break; + } + + initExParams.dwTotalSize = sizeof (PHONEINITIALIZEEXPARAMS); + initExParams.dwOptions = params[8].dwValue; + initExParams.Handles.hCompletionPort = ghCompletionPort; + + dwAPIVersion = params[6].dwValue; + + DumpParams (¶msHeader); + + if (funcIndex == pInitializeEx) + { + lResult = phoneInitializeEx( + (LPHPHONEAPP) params[0].dwValue, + (HINSTANCE) params[1].dwValue, + (PHONECALLBACK) params[2].dwValue, + (LPCSTR) params[3].dwValue, + (LPDWORD) params[4].dwValue, + (LPDWORD) params[5].dwValue, + (LPPHONEINITIALIZEEXPARAMS) params[7].dwValue + ); + } + else + { + lResult = phoneInitializeExW( + (LPHPHONEAPP) params[0].dwValue, + (HINSTANCE) params[1].dwValue, + (PHONECALLBACK) params[2].dwValue, + (LPCWSTR) params[3].dwValue, + (LPDWORD) params[4].dwValue, + (LPDWORD) params[5].dwValue, + (LPPHONEINITIALIZEEXPARAMS) params[7].dwValue + ); + } + + ShowPhoneFuncResult (aFuncNames[funcIndex], lResult); + + if (lResult == 0) + { + ShowStr ("%snum phone devs = %ld", szTab, dwNumDevs); + + if (params[7].dwValue != 0 && + (initExParams.dwOptions & 3) == + PHONEINITIALIZEEXOPTION_USEEVENT) + { + ShowStr( + "hPhoneApp x%x was created with the\r\n" \ + "USEEVENT option, so you must use\r\n" \ + "phoneGetMessage to retrieve messages.", + pNewPhoneApp->hPhoneApp + ); + } + + + //SendMessage (ghwndLineApps, LB_SETCURSEL, (WPARAM) i, 0); + UpdateWidgetList(); + gdwNumPhoneDevs = dwNumDevs; + SelectWidget ((PMYWIDGET) pNewPhoneApp); + } + else + { + FreePhoneApp (pNewPhoneApp); + } + + break; + } +#endif + case pOpen: + { + PMYPHONE pNewPhone; + FUNC_PARAM params[] = + { + { "hPhoneApp", PT_DWORD, 0, NULL }, + { szdwDeviceID, PT_DWORD, dwDefPhoneDeviceID, NULL }, + { "lphPhone", PT_POINTER, 0, NULL }, + { szdwAPIVersion, PT_ORDINAL, dwDefPhoneAPIVersion, aAPIVersions }, + { "dwExtVersion", PT_DWORD, dwDefPhoneExtVersion, NULL }, + { "dwCallbackInstance", PT_DWORD, 0, NULL }, + { "dwPrivilege", PT_ORDINAL, dwDefPhonePrivilege, aPhonePrivileges } + }; + FUNC_PARAM_HEADER paramsHeader = + { 7, funcIndex, params, (PFN7) phoneOpen }; + + + CHK_PHONEAPP_SELECTED() + + if (!(pNewPhone = AllocPhone(pPhoneAppSel))) + { + MessageBeep ((UINT) -1); + ShowStr ("error creating data structure"); + break; + } + + params[0].dwValue = (DWORD) pPhoneAppSel->hPhoneApp; + params[2].dwValue = + params[2].u.dwDefValue = (DWORD) &pNewPhone->hPhone; + + if ((lResult = DoFunc(¶msHeader)) == 0) + { + if ((HPHONEAPP) params[0].dwValue != pPhoneAppSel->hPhoneApp) + { + // + // User has switched phone apps on us we need to recreate + // the phone data structure under a different phone app + // + + PMYPHONE pNewPhone2 = + AllocPhone (GetPhoneApp((HPHONEAPP)params[0].dwValue)); + + if (pNewPhone2) + { + pNewPhone2->hPhone = pNewPhone->hPhone; + + FreePhone (pNewPhone); + + pNewPhone = pNewPhone2; + } + else + { + // BUGBUG show error: couldn't alloc a new phone struct + + phoneClose (pNewPhone->hPhone); + FreePhone (pNewPhone); + break; + } + } + + + // + // Save info about this phone that we can display later + // + + pNewPhone->hPhoneApp = (HPHONEAPP) params[0].dwValue; + pNewPhone->dwDevID = params[1].dwValue; + pNewPhone->dwAPIVersion = params[3].dwValue; + pNewPhone->dwPrivilege = params[6].dwValue; + + UpdateWidgetList(); + SelectWidget ((PMYWIDGET) pNewPhone); + } + else + { + FreePhone (pNewPhone); + } + + break; + } + case pNegotiateAPIVersion: + { + DWORD dwAPIVersion; + PHONEEXTENSIONID extID; + FUNC_PARAM params[] = + { + { "hPhoneApp", PT_DWORD, 0, NULL }, + { szdwDeviceID, PT_DWORD, dwDefPhoneDeviceID, NULL }, + { "dwAPILowVersion", PT_DWORD, 0x00010000, aAPIVersions }, + { "dwAPIHighVersion", PT_DWORD, 0x10000000, aAPIVersions }, + { "lpdwAPIVersion", PT_POINTER, (DWORD) &dwAPIVersion, &dwAPIVersion }, + { "lpExtensionID", PT_POINTER, (DWORD) &extID, &extID } + }; + FUNC_PARAM_HEADER paramsHeader = + { 6, funcIndex, params, (PFN6) phoneNegotiateAPIVersion }; + + + CHK_PHONEAPP_SELECTED() + + params[0].dwValue = (DWORD) pPhoneAppSel->hPhoneApp; + + if ((lResult = DoFunc (¶msHeader)) == 0) + { + ShowStr ("%s%s=x%lx", szTab, szdwAPIVersion, dwAPIVersion); + ShowStr( + "%sextID.ID0=x%lx, .ID1=x%lx, .ID2=x%lx, .ID3=x%lx, ", + szTab, + extID.dwExtensionID0, + extID.dwExtensionID1, + extID.dwExtensionID2, + extID.dwExtensionID3 + ); + } + + break; + } + case pNegotiateExtVersion: + { + DWORD dwExtVersion; + FUNC_PARAM params[] = + { + { szhPhoneApp, PT_DWORD, 0, NULL }, + { szdwDeviceID, PT_DWORD, dwDefPhoneDeviceID, NULL }, + { szdwAPIVersion, PT_ORDINAL, dwDefPhoneAPIVersion, aAPIVersions }, + { "dwExtLowVersion", PT_DWORD, 0x00000000, NULL }, + { "dwExtHighVersion", PT_DWORD, 0x80000000, NULL }, + { "lpdwExtVersion", PT_POINTER, (DWORD) &dwExtVersion, &dwExtVersion } + }; + FUNC_PARAM_HEADER paramsHeader = + { 6, funcIndex, params, (PFN6) phoneNegotiateExtVersion }; + + + CHK_PHONEAPP_SELECTED() + + params[0].dwValue = (DWORD) pPhoneAppSel->hPhoneApp; + + if (DoFunc (¶msHeader) == 0) + { + ShowStr ("%sdwExtVersion=x%lx", szTab, dwExtVersion); + } + + break; + } + case pSetButtonInfo: +#if TAPI_2_0 + case pSetButtonInfoW: +#endif + { + char szButtonText[MAX_STRING_PARAM_SIZE] = "button text"; + char szDevSpecific[MAX_STRING_PARAM_SIZE] = "dev specific info"; + LPPHONEBUTTONINFO lpButtonInfo = (LPPHONEBUTTONINFO) pBigBuf; + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwButtonLampID", PT_DWORD, 0, NULL }, + { "lpData", PT_POINTER, (DWORD) lpButtonInfo, lpButtonInfo }, + { " ->dwButtonMode", PT_FLAGS, PHONEBUTTONMODE_CALL, aButtonModes }, + { " ->dwButtonFunction", PT_DWORD, 0, NULL }, +// { " ->dwButtonFunction", PT_???, , aButtonFunctions }, + { " ->ButtonText", PT_STRING, (DWORD) szButtonText, szButtonText }, + { " ->DevSpecific", PT_STRING, (DWORD) szDevSpecific, szDevSpecific }, +#if TAPI_1_1 + { " ->dwButtonState", PT_FLAGS, 0, aButtonStates } +#endif + }; + FUNC_PARAM_HEADER paramsHeader = +#if TAPI_1_1 + { 8, funcIndex, params, NULL }; +#else + { 7, funcIndex, params, NULL }; +#endif + DWORD dwFixedStructSize = sizeof(PHONEBUTTONINFO), dwLength; + + + // BUGBUG need a PT_ type to specify constants (ords?) for ->dwButtonFunction + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + + // + // Note: the dwButtonState field in PHONEBUTTONINFO is only valid + // in 1.4+. It'll be ignored for phones opened w/ ver 1.3. + // + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + memset (lpButtonInfo, 0, (size_t) dwBigBufSize); + + if (dwBigBufSize >= 4) + { + lpButtonInfo->dwTotalSize = dwBigBufSize; + + if (dwBigBufSize >= 0x24) // sizeof(PHONEBUTTONINFO) in ver 0x10003 + { + lpButtonInfo->dwButtonMode = params[3].dwValue; + lpButtonInfo->dwButtonFunction = params[4].dwValue; + + if ((params[5].dwValue == (DWORD) szButtonText) && + (dwLength = (DWORD) strlen (szButtonText)) && + (dwBigBufSize >= (dwFixedStructSize + dwLength + 1))) + { + lpButtonInfo->dwButtonTextSize = dwLength + 1; + lpButtonInfo->dwButtonTextOffset = dwFixedStructSize; +#if TAPI_2_0 + if (gbWideStringParams) + { + lpButtonInfo->dwButtonTextSize *= sizeof (WCHAR); + + MultiByteToWideChar( + CP_ACP, + MB_PRECOMPOSED, + (LPCSTR) szButtonText, + -1, + (LPWSTR) (((char far *) lpButtonInfo) + + dwFixedStructSize), + MAX_STRING_PARAM_SIZE / 2 + ); + } + else + { + strcpy( + ((char far *) lpButtonInfo) + dwFixedStructSize, + szButtonText + ); + } +#else + strcpy( + ((char far *) lpButtonInfo) + dwFixedStructSize, + szButtonText + ); +#endif + } + + if ((params[6].dwValue == (DWORD) szDevSpecific) && + (dwLength = (DWORD) strlen (szDevSpecific)) && + (dwBigBufSize >= (dwFixedStructSize + dwLength + 1 + + lpButtonInfo->dwButtonTextSize))) + { + lpButtonInfo->dwDevSpecificSize = dwLength + 1; + lpButtonInfo->dwDevSpecificOffset = dwFixedStructSize + + lpButtonInfo->dwButtonTextSize; +#if TAPI_2_0 + if (gbWideStringParams) + { + lpButtonInfo->dwDevSpecificSize *= sizeof (WCHAR); + + MultiByteToWideChar( + CP_ACP, + MB_PRECOMPOSED, + (LPCSTR) szDevSpecific, + -1, + (LPWSTR) (((char far *) lpButtonInfo) + + lpButtonInfo->dwDevSpecificOffset), + MAX_STRING_PARAM_SIZE / 2 + ); + } + else + { + strcpy( + ((char far *) lpButtonInfo) + + lpButtonInfo->dwDevSpecificOffset, + szDevSpecific + ); + } +#else + strcpy( + ((char far *) lpButtonInfo) + + lpButtonInfo->dwDevSpecificOffset, + szDevSpecific + ); +#endif + } +#if TAPI_1_1 + if (dwBigBufSize >= dwFixedStructSize) + { + lpButtonInfo->dwButtonState = params[7].dwValue; + } +#endif + } + } + +#if TAPI_2_0 + if (funcIndex == pSetButtonInfo) + { + lResult = phoneSetButtonInfo( + (HPHONE) params[0].dwValue, + params[1].dwValue, + (LPPHONEBUTTONINFO) params[2].dwValue + ); + } + else + { + lResult = phoneSetButtonInfoW( + (HPHONE) params[0].dwValue, + params[1].dwValue, + (LPPHONEBUTTONINFO) params[2].dwValue + ); + } +#else + lResult = phoneSetButtonInfo( + (HPHONE) params[0].dwValue, + params[1].dwValue, + (LPPHONEBUTTONINFO) params[2].dwValue + ); +#endif + ShowPhoneFuncResult (aFuncNames[funcIndex], lResult); + + break; + } + case pSetData: + { + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwDataID", PT_DWORD, 0, NULL }, + { "lpData", PT_POINTER, (DWORD) pBigBuf, pBigBuf }, + { szdwSize, PT_DWORD, dwBigBufSize, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) phoneSetData }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + DoFunc (¶msHeader); + + break; + } + case pSetDisplay: + { + char szDisplay[MAX_STRING_PARAM_SIZE] = "123"; + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwRow", PT_DWORD, 0, NULL }, + { "dwColumn", PT_DWORD, 0, NULL }, + { "lpsDisplay", PT_STRING, (DWORD) szDisplay, szDisplay }, + { szdwSize, PT_DWORD, 3, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 5, funcIndex, params, (PFN5) phoneSetDisplay }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + lResult = DoFunc (¶msHeader); + + break; + } + case pSetGain: + { + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwHookSwitchDev", PT_ORDINAL, PHONEHOOKSWITCHDEV_HANDSET, aHookSwitchDevs }, + { "dwGain", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneSetGain }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + lResult = DoFunc (¶msHeader); + + break; + } + case pSetHookSwitch: + { + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwHookSwitchDevs", PT_FLAGS, PHONEHOOKSWITCHDEV_HANDSET, aHookSwitchDevs }, + { "dwHookSwitchMode", PT_ORDINAL, PHONEHOOKSWITCHMODE_ONHOOK, aHookSwitchModes } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneSetHookSwitch }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + lResult = DoFunc (¶msHeader); + + break; + } + case pSetLamp: + { + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwButtonLampID", PT_DWORD, 0, NULL }, + { "dwLampMode", PT_ORDINAL, PHONELAMPMODE_OFF, aLampModes } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneSetLamp }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + lResult = DoFunc (¶msHeader); + + break; + } + case pSetRing: + { + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwRingMode", PT_DWORD, 0, NULL }, + { "dwVolume", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneSetRing }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + lResult = DoFunc (¶msHeader); + + break; + } + case pSetStatusMessages: + { + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwPhoneStates", PT_FLAGS, 0, aPhoneStates }, + { "dwButtonModes", PT_FLAGS, 0, aButtonModes }, + { "dwButtonStates", PT_FLAGS, 0, aButtonStates } + }; + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) phoneSetStatusMessages }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + lResult = DoFunc (¶msHeader); + + break; + } + case pSetVolume: + { + FUNC_PARAM params[] = + { + { szhPhone, PT_DWORD, 0, NULL }, + { "dwHookSwitchDev", PT_ORDINAL, PHONEHOOKSWITCHDEV_HANDSET, aHookSwitchDevs }, + { "dwVolume", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 3, funcIndex, params, (PFN3) phoneSetVolume }; + + + CHK_PHONE_SELECTED() + + params[0].dwValue = (DWORD) pPhoneSel->hPhone; + + lResult = DoFunc (¶msHeader); + + break; + } + case pShutdown: + { + FUNC_PARAM params[] = + { + { szhPhoneApp, PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 1, funcIndex, params, (PFN1) phoneShutdown }; + + + CHK_PHONEAPP_SELECTED() + + params[0].dwValue = (DWORD) pPhoneAppSel->hPhoneApp; + + if (DoFunc (¶msHeader) == 0) + { + FreePhoneApp (GetPhoneApp((HPHONEAPP) params[0].dwValue)); + } + + break; + } + case tGetLocationInfo: +#if TAPI_2_0 + case tGetLocationInfoW: +#endif + { + char szCountryCode[MAX_STRING_PARAM_SIZE] = ""; + char szCityCode[MAX_STRING_PARAM_SIZE] = ""; + FUNC_PARAM params[] = + { + { "lpszCountryCode", PT_POINTER, (DWORD) szCountryCode, szCountryCode }, + { "lpszCityCode", PT_POINTER, (DWORD) szCityCode, szCityCode } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (funcIndex == tGetLocationInfo ? + (PFN2) tapiGetLocationInfo : (PFN2) tapiGetLocationInfoW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) tapiGetLocationInfo }; +#endif + + if (DoFunc (¶msHeader) == 0) + { +#if TAPI_2_0 + ShowStr( + (gbWideStringParams ? "%s*lpszCountryCode='%ws'" : + "%s*lpszCountryCode='%s'"), + szTab, + szCountryCode + ); + + ShowStr( + (gbWideStringParams ? "%s*lpszCityCode='%ws'" : + "%s*lpszCityCode='%s'"), + szTab, + szCityCode + ); +#else + ShowStr ("%s*lpszCountryCode='%s'", szTab, szCountryCode); + ShowStr ("%s*lpszCityCode='%s'", szTab, szCityCode); +#endif + } + + break; + } + case tRequestDrop: + { + FUNC_PARAM params[] = + { + { "hWnd", PT_DWORD, (DWORD) ghwndMain, 0 }, + { "wRequestID", PT_DWORD, (DWORD) 0, 0 } + }; + FUNC_PARAM_HEADER paramsHeader = + { 2, funcIndex, params, (PFN2) tapiRequestDrop }; + +#ifdef WIN32 + DoFunc (¶msHeader); +#else + // + // NOTE: on win16 HWNDSs & WPARAMs are 16 bits, so we've to hard + // code this + // + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + DumpParams (¶msHeader); + + lResult = tapiRequestDrop( + (HWND) params[0].dwValue, + (WPARAM) params[1].dwValue + ); + + ShowTapiFuncResult (aFuncNames[funcIndex], lResult); +#endif // WIN32 + break; + } + case tRequestMakeCall: +#if TAPI_2_0 + case tRequestMakeCallW: +#endif + { + char szDestAddress[MAX_STRING_PARAM_SIZE]; + char szAppName[MAX_STRING_PARAM_SIZE]; + char szCalledParty[MAX_STRING_PARAM_SIZE] = ""; + char szComment[MAX_STRING_PARAM_SIZE] = ""; + FUNC_PARAM params[] = + { + { szlpszDestAddress, PT_STRING, (DWORD) szDestAddress, szDestAddress }, + { szlpszAppName, PT_STRING, (DWORD) szAppName, szAppName }, + { "lpszCalledParty", PT_STRING, (DWORD) szCalledParty, szCalledParty }, + { "lpszComment", PT_STRING, (DWORD) szComment, szComment } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (funcIndex == tRequestMakeCall ? + (PFN4) tapiRequestMakeCall : (PFN4) tapiRequestMakeCallW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 4, funcIndex, params, (PFN4) tapiRequestMakeCall }; +#endif + + strcpy (szDestAddress, szDefDestAddress); + strcpy (szAppName, szDefAppName); + + DoFunc (¶msHeader); + + break; + } + case tRequestMediaCall: +#if TAPI_2_0 + case tRequestMediaCallW: +#endif + { + char szDeviceClass[MAX_STRING_PARAM_SIZE]; + char szDevID[MAX_STRING_PARAM_SIZE] = "0"; + char szDestAddress[MAX_STRING_PARAM_SIZE]; + char szAppName[MAX_STRING_PARAM_SIZE]; + char szCalledParty[MAX_STRING_PARAM_SIZE] = ""; + char szComment[MAX_STRING_PARAM_SIZE] = ""; + FUNC_PARAM params[] = + { + { "hWnd", PT_DWORD, (DWORD) ghwndMain, 0 }, + { "wRequestID", PT_DWORD, (DWORD) 0, 0 }, + { szlpszDeviceClass, PT_STRING, (DWORD) szDeviceClass, szDeviceClass }, + { "lpDeviceID", PT_STRING, (DWORD) szDevID, szDevID }, + { szdwSize, PT_DWORD, 0, 0 }, + { "dwSecure", PT_DWORD, 0, 0 }, + { szlpszDestAddress, PT_STRING, (DWORD) szDestAddress, szDestAddress }, + { szlpszAppName, PT_STRING, (DWORD) szAppName, szAppName }, + { "lpszCalledParty", PT_STRING, (DWORD) szCalledParty, szCalledParty }, + { "lpszComment", PT_STRING, (DWORD) szComment, szComment } + }; +#if TAPI_2_0 + FUNC_PARAM_HEADER paramsHeader = + { 10, funcIndex, params, (funcIndex == tRequestMediaCall ? + (PFN10) tapiRequestMediaCall : (PFN10) tapiRequestMediaCallW) }; +#else + FUNC_PARAM_HEADER paramsHeader = + { 10, funcIndex, params, (PFN10) tapiRequestMediaCall }; +#endif + + strcpy (szDeviceClass, szDefLineDeviceClass); // BUGBUG szDefTapiDeviceClass); + strcpy (szDestAddress, szDefDestAddress); + strcpy (szAppName, szDefAppName); + +#ifdef WIN32 + DoFunc (¶msHeader); +#else + // + // NOTE: on win16 HWNDSs & WPARAMs are 16 bits, so we've to hard + // code this + // + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + DumpParams (¶msHeader); + + lResult = tapiRequestMediaCall( + (HWND) params[0].dwValue, + (WPARAM) params[1].dwValue, + (LPCSTR) params[2].dwValue, + (LPCSTR) params[3].dwValue, + params[4].dwValue, + params[5].dwValue, + (LPCSTR) params[6].dwValue, + (LPCSTR) params[7].dwValue, + (LPCSTR) params[8].dwValue, + (LPCSTR) params[9].dwValue + ); + + ShowTapiFuncResult (aFuncNames[funcIndex], lResult); +#endif // WIN32 + break; + } + case OpenAllLines: + { + DWORD dwDefLineDeviceIDSav = dwDefLineDeviceID; + + + CHK_LINEAPP_SELECTED() + + for( + dwDefLineDeviceID = 0; + dwDefLineDeviceID < gdwNumLineDevs; + dwDefLineDeviceID++ + ) + { + FuncDriver (lOpen); + } + + dwDefLineDeviceID = dwDefLineDeviceIDSav; + + break; + } + case OpenAllPhones: + { + DWORD dwDefPhoneDeviceIDSav = dwDefPhoneDeviceID; + + + CHK_PHONEAPP_SELECTED() + + for( + dwDefPhoneDeviceID = 0; + dwDefPhoneDeviceID < gdwNumPhoneDevs; + dwDefPhoneDeviceID++ + ) + { + FuncDriver (pOpen); + } + + dwDefPhoneDeviceID = dwDefPhoneDeviceIDSav; + + break; + } + case CloseHandl: + { +#ifdef WIN32 + FUNC_PARAM params[] = + { + { "hObject", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 1, funcIndex, params, NULL }; + + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + if (CloseHandle ((HANDLE) params[0].dwValue)) + { + ShowStr ("Handle x%lx closed", params[0].dwValue); + } + else + { + ShowStr ("CloseHandle failed, err=%lx", GetLastError()); + } +#else + FUNC_PARAM params[] = + { + { "idCommDev", PT_DWORD, 0, NULL } + }; + FUNC_PARAM_HEADER paramsHeader = + { 1, funcIndex, params, NULL }; + + + if (!LetUserMungeParams (¶msHeader)) + { + break; + } + + if (CloseComm ((int) params[0].dwValue) == 0) + { + ShowStr ("Comm dev x%lx closed", params[0].dwValue); + } + else + { + ShowStr ("CloseComm() failed"); + } +#endif + + break; + } + case DumpBuffer: + + ShowStr ("Buffer contents:"); + + ShowBytes( + (dwBigBufSize > 256 ? 256 : dwBigBufSize), + pBigBuf, + 1 + ); + + break; + + default: + + MessageBeep ((UINT)-1); + break; + } +} + +#pragma warning (default:4113) diff --git a/private/tapi/dev/apps/tb/ui.c b/private/tapi/dev/apps/tb/ui.c new file mode 100644 index 000000000..b57a34dee --- /dev/null +++ b/private/tapi/dev/apps/tb/ui.c @@ -0,0 +1,4704 @@ +/*++ BUILD Version: 0000 // Increment this if a change has global effects + +Copyright (c) 1994-96 Microsoft Corporation + +Module Name: + + ui.c + +Abstract: + + Contains UI support for TAPI Browser util. + +Author: + + Dan Knudson (DanKn) 23-Oct-1994 + +Revision History: + +--*/ + + +#include "tb.h" +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <ctype.h> +#include <io.h> +#include <malloc.h> +#include <time.h> +#include <commdlg.h> +#include "resource.h" +#include "vars.h" + + +extern char szdwSize[]; +extern char szdwAddressID[]; + + +HWND hwndEdit2; + + +char * +PASCAL +GetTimeStamp( + void + ); + +void +ShowStructByField( + PSTRUCT_FIELD_HEADER pHeader, + BOOL bSubStructure + ); + +void +CompletionPortThread( + LPVOID pParams + ); + + +int +WINAPI +WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow + ) +{ + MSG msg; + HWND hwnd; + HACCEL hAccel; + + + ghInst = hInstance; + + hwnd = CreateDialog( + ghInst, + (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG1), + (HWND)NULL, + (DLGPROC) MainWndProc + ); + + hwndEdit2 = CreateWindow ("edit", "", 0, 0, 0, 0, 0, NULL, NULL, ghInst, NULL); + + if (!hwndEdit2) + { + MessageBox (NULL, "err creating edit ctl", "", MB_OK); + } + + hAccel = LoadAccelerators( + ghInst, + (LPCSTR)MAKEINTRESOURCE(IDR_ACCELERATOR1) + ); + +#if TAPI_2_0 + + if ((ghCompletionPort = CreateIoCompletionPort( + INVALID_HANDLE_VALUE, + NULL, + 0, + 0 + ))) + { + DWORD dwTID; + HANDLE hThread; + + + if ((hThread = CreateThread( + (LPSECURITY_ATTRIBUTES) NULL, + 0, + (LPTHREAD_START_ROUTINE) CompletionPortThread, + NULL, + 0, + &dwTID + ))) + { + CloseHandle (hThread); + } + else + { + ShowStr( + "CreateThread(CompletionPortThread) failed, err=%d", + GetLastError() + ); + } + } + else + { + ShowStr ("CreateIoCompletionPort failed, err=%d", GetLastError()); + } + +#endif + + while (GetMessage (&msg, NULL, 0, 0)) + { + if (!TranslateAccelerator (hwnd, hAccel, &msg)) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } + + DestroyWindow (hwndEdit2); + + return 0; +} + + +void +CompletionPortThread( + LPVOID pParams + ) +{ + DWORD dwNumBytesTransfered, dwCompletionKey; + LPLINEMESSAGE pMsg; + + + while (GetQueuedCompletionStatus( + ghCompletionPort, + &dwNumBytesTransfered, + &dwCompletionKey, + (LPOVERLAPPED *) &pMsg, + INFINITE + )) + { + if (pMsg) + { + tapiCallback( + pMsg->hDevice, + pMsg->dwMessageID, + pMsg->dwCallbackInstance, + pMsg->dwParam1, + pMsg->dwParam2, + pMsg->dwParam3 + ); + + LocalFree (pMsg); + } + else + { + break; + } + } +} + + +void +GetCurrentSelections( + void + ) +{ + LONG lSel = SendMessage (ghwndList1, LB_GETCURSEL, 0, 0); + PMYWIDGET pWidget = aWidgets; + + + // + // Init all pXxxSel ptrs to NULL + // + + pLineAppSel = (PMYLINEAPP) NULL; + pLineSel = (PMYLINE) NULL; + pCallSel = + pCallSel2 = (PMYCALL) NULL; + pPhoneAppSel = (PMYPHONEAPP) NULL; + pPhoneSel = (PMYPHONE) NULL; + + + if (lSel != LB_ERR) + { + // + // Find the selected widget & set globals appropriately + // + + pWidget = (PMYWIDGET) SendMessage( + ghwndList1, + LB_GETITEMDATA, + (WPARAM) lSel, + 0 + ); + + switch (pWidget->dwType) + { + case WT_LINEAPP: + + pLineAppSel = (PMYLINEAPP) pWidget; + break; + + case WT_LINE: + + pLineSel = (PMYLINE) pWidget; + pLineAppSel = pLineSel->pLineApp; + break; + + case WT_CALL: + + pCallSel = (PMYCALL) pWidget; + pLineSel = pCallSel->pLine; + pLineAppSel = pCallSel->pLine->pLineApp; + + if (pWidget->pNext && (pWidget->pNext->dwType == WT_CALL)) + { + pCallSel2 = (PMYCALL) pWidget->pNext; + } + else if ((((PMYWIDGET)pLineSel)->pNext != pWidget) && + (((PMYWIDGET)pLineSel)->pNext->dwType == WT_CALL)) + { + pCallSel2 = (PMYCALL) (((PMYWIDGET)pLineSel)->pNext); + } + + break; + + case WT_PHONEAPP: + + pPhoneAppSel = (PMYPHONEAPP) pWidget; + break; + + case WT_PHONE: + + pPhoneSel = (PMYPHONE) pWidget; + pPhoneAppSel = pPhoneSel->pPhoneApp; + break; + } + } + + + // + // The following is an attempt to up the usability level a little bit. + // Most folks are going to be messing around with 1 lineapp/line/call + // at a time, and it'd end up being a real PITA for them to have to + // select a widget each time (and it's fairly obvious which widget + // are referring to). So we're going to try to make some intelligent + // decisions in case they haven't selected a widget... (Obviously this + // could be cleaned up a bit, like maybe maintaining dwNumXxx as + // globals rather than walking the list each time.) + // + + { + DWORD dwNumLineApps = 0, dwNumLines = 0, dwNumCalls = 0, + dwNumPhoneApps = 0, dwNumPhones = 0; + PMYPHONEAPP pPhoneApp = NULL; + + + pWidget = aWidgets; + + while (pWidget) + { + switch (pWidget->dwType) + { + case WT_LINEAPP: + + dwNumLineApps++; + break; + + case WT_LINE: + + dwNumLines++; + break; + + case WT_CALL: + + dwNumCalls++; + break; + + case WT_PHONEAPP: + + dwNumPhoneApps++; + + if (dwNumPhoneApps == 1) + { + pPhoneApp = (PMYPHONEAPP) pWidget; + } + + break; + + case WT_PHONE: + + dwNumPhones++; + break; + } + + pWidget = pWidget->pNext; + } + + if (dwNumLineApps == 1) + { + pLineAppSel = (PMYLINEAPP) aWidgets; + + if (dwNumLines == 1) + { + pLineSel = (PMYLINE) pLineAppSel->Widget.pNext; + + if (dwNumCalls == 1) + { + pCallSel = (PMYCALL) pLineSel->Widget.pNext; + } + } + } + + if (dwNumPhoneApps == 1) + { + pPhoneAppSel = (PMYPHONEAPP) pPhoneApp; + + if (dwNumPhones == 1) + { + pPhoneSel = (PMYPHONE) pPhoneAppSel->Widget.pNext; + } + } + } +} + +/* help +VOID +MyWinHelp( + HWND hwndOwner, + BOOL bTapiHlp, + UINT uiCommand, + DWORD dwData + ) +{ + char *lpszHelpFile = (bTapiHlp ? szTapiHlp : szTspiHlp); + + + if (lpszHelpFile[0] == 0 || _access (lpszHelpFile, 0)) + { + // + // Prompt user for helpfile path + // + + OPENFILENAME ofn; + char szDirName[256] = ".\\"; + char szFile[256] = "tapi.hlp\0"; + char szFileTitle[256] = ""; + char szFilter[] = "Telephony API Help\0tapi.hlp\0\0"; + + + if (MessageBox( + hwndOwner, + "Help file not found- do you want to specify a new help file?", + "Warning", + MB_YESNO + ) == IDNO) + { + return; + } + + if (!bTapiHlp) + { + szFile[1] = 's'; + szFilter[10] = 'S'; + szFilter[20] = 's'; + } + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwndOwner; + ofn.lpstrFilter = szFilter; + ofn.lpstrCustomFilter = (LPSTR) NULL; + ofn.nMaxCustFilter = 0L; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = szDirName; + ofn.lpstrTitle = (LPSTR) NULL; + ofn.Flags = 0L; + ofn.nFileOffset = 0; + ofn.nFileExtension = 0; + ofn.lpstrDefExt = "HLP"; + + if (!GetOpenFileName(&ofn)) + { + return; + } + + strcpy (lpszHelpFile, szFile); + } + + if (!WinHelp (ghwndMain, (LPCSTR) lpszHelpFile, uiCommand, dwData)) + { + lpszHelpFile[0] = 0; + } +} +*/ + +BOOL +CALLBACK +MainWndProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam + ) +{ + static HICON hIcon; + static HMENU hMenu; + static int icyButton, icyBorder; + static HFONT hFont, hFont2; + + int i; + + static LONG cxList1, cxList2, cxWnd, xCapture, cxVScroll, lCaptureFlags = 0; + static int cyWnd; + + typedef struct _XXX + { + DWORD dwMenuID; + + DWORD dwFlags; + + } XXX, *PXXX; + + static XXX aXxx[] = + { + { IDM_LOGSTRUCTDWORD ,DS_BYTEDUMP }, + { IDM_LOGSTRUCTALLFIELD ,DS_NONZEROFIELDS|DS_ZEROFIELDS }, + { IDM_LOGSTRUCTNONZEROFIELD ,DS_NONZEROFIELDS }, + { IDM_LOGSTRUCTNONE ,0 } + }; + + switch (msg) + { + case WM_INITDIALOG: + { + RECT rect; + char buf[64]; + + + ghwndMain = hwnd; + ghwndList1 = GetDlgItem (hwnd, IDC_LIST1); + ghwndList2 = GetDlgItem (hwnd, IDC_LIST2); + ghwndEdit = GetDlgItem (hwnd, IDC_EDIT1); + hMenu = GetMenu (hwnd); + hIcon = LoadIcon (ghInst, MAKEINTRESOURCE(IDI_ICON1)); + + icyBorder = GetSystemMetrics (SM_CYFRAME); + cxVScroll = 2*GetSystemMetrics (SM_CXVSCROLL); + + GetWindowRect (GetDlgItem (hwnd, IDC_BUTTON1), &rect); + icyButton = (rect.bottom - rect.top) + icyBorder + 3; + + for (i = 0; aFuncNames[i]; i++) + { + SendMessage( + ghwndList2, + LB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) aFuncNames[i] + ); + } + + SendMessage (ghwndList2, LB_SETCURSEL, (WPARAM) lInitialize, 0); + + +#ifdef WIN32 + SetWindowText (hwnd, "TAPI32 Browser"); +#else + SetWindowText (hwnd, "TAPI16 Browser"); +#endif + + // + // Read in defaults from ini file + // + + { + typedef struct _DEF_VALUE + { + char far *lpszEntry; + char far *lpszDefValue; + LPVOID lp; + + } DEF_VALUE; + + DEF_VALUE aDefVals[] = + { + { "BufSize", "1000", &dwBigBufSize }, + { "AddressID", "0", &dwDefAddressID }, +#if TAPI_2_0 + { "20LineAPIVersion", "20000", &dwDefLineAPIVersion }, +#else +#if TAPI_1_1 + { "14LineAPIVersion", "10004", &dwDefLineAPIVersion }, +#else + { "13LineAPIVersion", "10003", &dwDefLineAPIVersion }, +#endif +#endif + { "BearerMode", "1", &dwDefBearerMode }, + { "CountryCode", "0", &dwDefCountryCode }, + { "LineDeviceID", "0", &dwDefLineDeviceID }, + { "LineExtVersion", "0", &dwDefLineExtVersion }, + { "MediaMode", "10", &dwDefMediaMode }, // DATAMODEM + { "LinePrivilege", "1", &dwDefLinePrivilege }, // NONE (dialout only) +#if TAPI_2_0 + { "20PhoneAPIVersion", "20000", &dwDefPhoneAPIVersion }, +#else +#if TAPI_1_1 + { "14PhoneAPIVersion", "10004", &dwDefPhoneAPIVersion }, +#else + { "13PhoneAPIVersion", "10003", &dwDefPhoneAPIVersion }, +#endif +#endif + { "PhoneDeviceID", "0", &dwDefPhoneDeviceID }, + { "PhoneExtVersion", "0", &dwDefPhoneExtVersion }, + { "PhonePrivilege", "2", &dwDefPhonePrivilege }, // OWNER +#if TAPI_2_0 + { "20UserButton1", "500", aUserButtonFuncs }, + { "20UserButton2", "500", aUserButtonFuncs + 1 }, + { "20UserButton3", "500", aUserButtonFuncs + 2 }, + { "20UserButton4", "500", aUserButtonFuncs + 3 }, + { "20UserButton5", "500", aUserButtonFuncs + 4 }, + { "20UserButton6", "500", aUserButtonFuncs + 5 }, +#else +#if TAPI_1_1 + { "14UserButton1", "500", aUserButtonFuncs }, + { "14UserButton2", "500", aUserButtonFuncs + 1 }, + { "14UserButton3", "500", aUserButtonFuncs + 2 }, + { "14UserButton4", "500", aUserButtonFuncs + 3 }, + { "14UserButton5", "500", aUserButtonFuncs + 4 }, + { "14UserButton6", "500", aUserButtonFuncs + 5 }, +#else + { "13UserButton1", "500", aUserButtonFuncs }, + { "13UserButton2", "500", aUserButtonFuncs + 1 }, + { "13UserButton3", "500", aUserButtonFuncs + 2 }, + { "13UserButton4", "500", aUserButtonFuncs + 3 }, + { "13UserButton5", "500", aUserButtonFuncs + 4 }, + { "13UserButton6", "500", aUserButtonFuncs + 5 }, +#endif +#endif + { "TimeStamp", "0", &bTimeStamp }, + { "NukeIdleMonitorCalls", "1", &bNukeIdleMonitorCalls }, + { "NukeIdleOwnedCalls", "0", &bNukeIdleOwnedCalls }, + { "DisableHandleChecking", "0", &gbDisableHandleChecking }, + { "DumpStructsFlags", "1", &dwDumpStructsFlags }, + { NULL, NULL, NULL }, + { "UserUserInfo", "my user user info", szDefUserUserInfo }, + { "DestAddress", "55555", szDefDestAddress }, + { "LineDeviceClass", "tapi/line", szDefLineDeviceClass }, + { "PhoneDeviceClass", "tapi/phone", szDefPhoneDeviceClass }, + { "AppName", "Tapi Browser", szDefAppName }, + { NULL, NULL, NULL }, +#if TAPI_2_0 + { "20UserButton1Text", "", &aUserButtonsText[0] }, + { "20UserButton2Text", "", &aUserButtonsText[1] }, + { "20UserButton3Text", "", &aUserButtonsText[2] }, + { "20UserButton4Text", "", &aUserButtonsText[3] }, + { "20UserButton5Text", "", &aUserButtonsText[4] }, + { "20UserButton6Text", "", &aUserButtonsText[5] }, +#else +#if TAPI_1_1 + { "14UserButton1Text", "", &aUserButtonsText[0] }, + { "14UserButton2Text", "", &aUserButtonsText[1] }, + { "14UserButton3Text", "", &aUserButtonsText[2] }, + { "14UserButton4Text", "", &aUserButtonsText[3] }, + { "14UserButton5Text", "", &aUserButtonsText[4] }, + { "14UserButton6Text", "", &aUserButtonsText[5] }, +#else + { "13UserButton1Text", "", &aUserButtonsText[0] }, + { "13UserButton2Text", "", &aUserButtonsText[1] }, + { "13UserButton3Text", "", &aUserButtonsText[2] }, + { "13UserButton4Text", "", &aUserButtonsText[3] }, + { "13UserButton5Text", "", &aUserButtonsText[4] }, + { "13UserButton6Text", "", &aUserButtonsText[5] }, +#endif +#endif + { NULL, NULL, NULL } + }; + + int i, j; + + #define MYSECTION "Tapi Browser" + + + for (i = 0; aDefVals[i].lpszEntry; i++) + { + GetProfileString( + MYSECTION, + aDefVals[i].lpszEntry, + aDefVals[i].lpszDefValue, + buf, + 15 + ); + + sscanf (buf, "%lx", aDefVals[i].lp); + } + + i++; + + for (; aDefVals[i].lpszEntry; i++) + { + GetProfileString( + MYSECTION, + aDefVals[i].lpszEntry, + aDefVals[i].lpszDefValue, + (LPSTR) aDefVals[i].lp, + MAX_STRING_PARAM_SIZE - 1 + ); + } + + i++; + + for (j = i; aDefVals[i].lpszEntry; i++) + { + GetProfileString( + MYSECTION, + aDefVals[i].lpszEntry, + aDefVals[i].lpszDefValue, + (LPSTR) aDefVals[i].lp, + MAX_USER_BUTTON_TEXT_SIZE - 1 + ); + + SetDlgItemText( + hwnd, + IDC_BUTTON13 + (i - j), + (LPCSTR)aDefVals[i].lp + ); + } + + lpszDefAppName = szDefAppName; + lpszDefUserUserInfo = szDefUserUserInfo; + lpszDefDestAddress = szDefDestAddress; + lpszDefLineDeviceClass = szDefLineDeviceClass; + lpszDefPhoneDeviceClass = szDefPhoneDeviceClass; + + if (GetProfileString ( + MYSECTION, + "Version", + "", + buf, + 15 + ) == 0 || (strcmp (buf, szCurrVer))) + { + // + // If here assume this is first time user had started + // TB, so post a msg that will automatically bring up + // the hlp dlg + // + + PostMessage (hwnd, WM_COMMAND, IDM_USINGTB, 0); + } + +// help GetProfileString (MYSECTION, "TapiHlpPath", "", szTapiHlp, 256); +// help GetProfileString (MYSECTION, "TspiHlpPath", "", szTspiHlp, 256); + } + + pBigBuf = malloc ((size_t)dwBigBufSize); + + { + //HFONT hFontMenu = SendMessage (hMenu, WM_GETFONT, 0, 0); + + hFont = CreateFont( + 13, 5, 0, 0, 400, 0, 0, 0, 0, 1, 2, 1, 34, "MS Sans Serif" + ); + hFont2 = CreateFont( + 13, 8, 0, 0, 400, 0, 0, 0, 0, 1, 2, 1, 49, "Courier" + ); + + for (i = 0; i < 18; i++) + { + SendDlgItemMessage( + hwnd, + IDC_BUTTON1 + i, + WM_SETFONT, + (WPARAM) hFont, + 0 + ); + } + + SendMessage (ghwndList1, WM_SETFONT, (WPARAM) hFont, 0); + SendMessage (ghwndList2, WM_SETFONT, (WPARAM) hFont, 0); + SendMessage (ghwndEdit, WM_SETFONT, (WPARAM) hFont2, 0); + } + + GetProfileString( + MYSECTION, + "ControlRatios", + "20, 20, 100", + buf, + 63 + ); + + sscanf (buf, "%ld,%ld,%ld", &cxList2, &cxList1, &cxWnd); + + GetProfileString( + MYSECTION, + "Position", + "max", + buf, + 63 + ); + + if (strcmp (buf, "max") == 0) + { + ShowWindow (hwnd, SW_SHOWMAXIMIZED); + } + else + { + int left = 100, top = 100, right = 600, bottom = 400; + + + sscanf (buf, "%d,%d,%d,%d", &left, &top, &right, &bottom); + + + // + // Check to see if wnd pos is wacky, if so reset to reasonable vals + // + + if (left < 0 || + left >= (GetSystemMetrics (SM_CXSCREEN) - 32) || + top < 0 || + top >= (GetSystemMetrics (SM_CYSCREEN) - 32)) + { + left = top = 100; + right = 600; + bottom = 400; + } + + SetWindowPos( + hwnd, + HWND_TOP, + left, + top, + right - left, + bottom - top, + SWP_SHOWWINDOW + ); + + GetClientRect (hwnd, &rect); + + SendMessage( + hwnd, + WM_SIZE, + 0, + MAKELONG((rect.right-rect.left),(rect.bottom-rect.top)) + ); + + ShowWindow (hwnd, SW_SHOW); + } + + for (i = 0; aXxx[i].dwFlags != dwDumpStructsFlags; i++); + + CheckMenuItem (hMenu, aXxx[i].dwMenuID, MF_BYCOMMAND | MF_CHECKED); + + CheckMenuItem( + hMenu, + IDM_TIMESTAMP, + MF_BYCOMMAND | (bTimeStamp ? MF_CHECKED : MF_UNCHECKED) + ); + + CheckMenuItem( + hMenu, + IDM_NUKEIDLEMONITORCALLS, + MF_BYCOMMAND | (bNukeIdleMonitorCalls ? MF_CHECKED : MF_UNCHECKED) + ); + + CheckMenuItem( + hMenu, + IDM_NUKEIDLEOWNEDCALLS, + MF_BYCOMMAND | (bNukeIdleOwnedCalls ? MF_CHECKED : MF_UNCHECKED) + ); + + CheckMenuItem( + hMenu, + IDM_NOHANDLECHK, + MF_BYCOMMAND | (gbDisableHandleChecking ? MF_CHECKED : MF_UNCHECKED) + ); + + // + // Alloc & init the global call params + // + +#if TAPI_2_0 + + lpCallParamsW = NULL; + +init_call_params: + +#endif + { +#if TAPI_2_0 + size_t callParamsSize = + sizeof(LINECALLPARAMS) + 15 * MAX_STRING_PARAM_SIZE; +#else + size_t callParamsSize = + sizeof(LINECALLPARAMS) + 8 * MAX_STRING_PARAM_SIZE; +#endif + + if ((lpCallParams = (LPLINECALLPARAMS) malloc (callParamsSize))) + { + LPDWORD lpdwXxxOffset = &lpCallParams->dwOrigAddressOffset; + + + memset (lpCallParams, 0, callParamsSize); + + lpCallParams->dwTotalSize = (DWORD) callParamsSize; + lpCallParams->dwBearerMode = LINEBEARERMODE_VOICE; + lpCallParams->dwMinRate = 3100; + lpCallParams->dwMaxRate = 3100; + lpCallParams->dwMediaMode = LINEMEDIAMODE_INTERACTIVEVOICE; + lpCallParams->dwAddressMode = LINEADDRESSMODE_ADDRESSID; + + for (i = 0; i < 8; i++) + { + *(lpdwXxxOffset + 2*i) = + sizeof(LINECALLPARAMS) + i*MAX_STRING_PARAM_SIZE; + } +#if TAPI_2_0 + { + LPDWORD pdwProxyRequests = (LPDWORD) + (((LPBYTE) lpCallParams) + + lpCallParams->dwDevSpecificOffset); + + + for (i = 0; i < 8; i++) + { + *(pdwProxyRequests + i) = i + + LINEPROXYREQUEST_SETAGENTGROUP; + } + } + + lpdwXxxOffset = &lpCallParams->dwTargetAddressOffset; + + for (i = 0; i < 6; i++) + { + *(lpdwXxxOffset + 2 * i) = + sizeof(LINECALLPARAMS) + (8+i)*MAX_STRING_PARAM_SIZE; + } + + lpCallParams->dwCallingPartyIDOffset = + sizeof(LINECALLPARAMS) + 14 * MAX_STRING_PARAM_SIZE; + + if (!lpCallParamsW) + { + lpCallParamsW = lpCallParams; + goto init_call_params; + } +#endif + } + else + { + // BUGBUG + } + } + + break; + } + case WM_COMMAND: + { + FUNC_INDEX funcIndex; + BOOL bShowParamsSave = bShowParams; + + switch (LOWORD((DWORD)wParam)) + { + case IDC_EDIT1: + +#ifdef WIN32 + if (HIWORD(wParam) == EN_CHANGE) +#else + if (HIWORD(lParam) == EN_CHANGE) +#endif + { + // + // Watch to see if the edit control is full, & if so + // purge the top half of the text to make room for more + // + + int length = GetWindowTextLength (ghwndEdit); + + + if (length > 29998) + { +#ifdef WIN32 + SendMessage( + ghwndEdit, + EM_SETSEL, + (WPARAM) 0, + (LPARAM) 10000 + ); +#else + SendMessage( + ghwndEdit, + EM_SETSEL, + (WPARAM) 1, + (LPARAM) MAKELONG (0, 10000) + ); +#endif + + SendMessage( + ghwndEdit, + EM_REPLACESEL, + 0, + (LPARAM) (char far *) "" + ); + +#ifdef WIN32 + SendMessage( + ghwndEdit, + EM_SETSEL, + (WPARAM)0xfffffffd, + (LPARAM)0xfffffffe + ); +#else + SendMessage( + ghwndEdit, + EM_SETSEL, + (WPARAM)1, + (LPARAM) MAKELONG (0xfffd, 0xfffe) + ); +#endif + } + } + break; + + case IDC_BUTTON1: + + funcIndex = lInitialize; + goto IDC_BUTTON10_callFuncDriver; + + case IDC_BUTTON2: + + funcIndex = lShutdown; + goto IDC_BUTTON10_callFuncDriver; + + case IDC_BUTTON3: + + funcIndex = lOpen; + goto IDC_BUTTON10_callFuncDriver; + + case IDC_BUTTON4: + + funcIndex = lClose; + goto IDC_BUTTON10_callFuncDriver; + + case IDC_BUTTON5: + + funcIndex = lMakeCall; + goto IDC_BUTTON10_callFuncDriver; + + case IDC_BUTTON6: + + GetCurrentSelections(); + + if (pCallSel && (pCallSel->dwCallState == LINECALLSTATE_IDLE)) + { + funcIndex = lDeallocateCall; + } + else + { + funcIndex = lDrop; + gbDeallocateCall = TRUE; + } + + FuncDriver (funcIndex); + gbDeallocateCall = FALSE; + break; + + case IDC_BUTTON7: + + funcIndex = pInitialize; + goto IDC_BUTTON10_callFuncDriver; + + case IDC_BUTTON8: + + funcIndex = pShutdown; + goto IDC_BUTTON10_callFuncDriver; + + case IDC_BUTTON9: + + funcIndex = pOpen; + goto IDC_BUTTON10_callFuncDriver; + + case IDC_BUTTON10: + + funcIndex = pClose; + +IDC_BUTTON10_callFuncDriver: + + // + // Want to make the "hot buttons" as simple as possible, so + // turn off the show params flag, then call FuncDriver, and + // finally restore the flag + // + + GetCurrentSelections (); + FuncDriver (funcIndex); + break; + + case IDC_BUTTON11: + case IDM_CLEAR: + + SetWindowText (ghwndEdit, ""); + break; + + + case IDM_PARAMS: + case IDC_BUTTON12: + + bShowParams = (bShowParams ? FALSE : TRUE); + + if (bShowParams) + { + CheckMenuItem( + hMenu, + IDM_PARAMS, + MF_BYCOMMAND | MF_CHECKED + ); + + CheckDlgButton (hwnd, IDC_BUTTON12, 1); + } + else + { + CheckMenuItem( + hMenu, + IDM_PARAMS, + MF_BYCOMMAND | MF_UNCHECKED + ); + + CheckDlgButton (hwnd, IDC_BUTTON12, 0); + } + + break; + + case IDC_BUTTON13: + case IDC_BUTTON14: + case IDC_BUTTON15: + case IDC_BUTTON16: + case IDC_BUTTON17: + case IDC_BUTTON18: + { + DWORD i = (DWORD) (LOWORD((DWORD)wParam)) - IDC_BUTTON13; + + + if (aUserButtonFuncs[i] >= MiscBegin) + { + // + // Hot button func id is bogus, so bring + // up hot button init dlg + // + + DialogBoxParam( + ghInst, + (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3), + (HWND) hwnd, + (DLGPROC) UserButtonsDlgProc, + (LPARAM) &i + ); + } + else + { + // + // Invoke the user button's corresponding func + // + + GetCurrentSelections (); + FuncDriver ((FUNC_INDEX) aUserButtonFuncs[i]); + } + + break; + } +/* help case IDC_F1HELP: + + if ((GetFocus() == ghwndEdit) && + SendMessage (ghwndEdit, EM_GETSEL, 0, 0)) + { + // + // Display help for the selected text in the edit ctrl + // + + char buf[32]; + + + // + // Copy the selected text in the edit ctrl to our + // temp edit control, then query the temp edit ctrl's + // text (this seems to be the easiest way to get the + // selected text) + // + + SendMessage (ghwndEdit, WM_COPY, 0, 0); + SetWindowText (hwndEdit2, ""); + SendMessage (hwndEdit2, WM_PASTE, 0, 0); + + + // + // In the interest of getting an exact match on a + // helpfile key strip off any trailing spaces + // + + GetWindowText (hwndEdit2, buf, 32); + buf[31] = 0; + for (i = 0; i < 32; i++) + { + if (buf[i] == ' ') + { + buf[i] = 0; + break; + } + } + + MyWinHelp (hwnd, TRUE, HELP_PARTIALKEY, (DWORD) buf); + } + else + { + // + // Display help for the currently selected func + // + + FUNC_INDEX funcIndex = (FUNC_INDEX) + SendMessage (ghwndList2, LB_GETCURSEL, 0, 0); + + + MyWinHelp (hwnd, TRUE, HELP_PARTIALKEY, (DWORD) aFuncNames[funcIndex]); + } + + break; +*/ + case IDC_PREVCTRL: + { + HWND hwndPrev = GetNextWindow (GetFocus (), GW_HWNDPREV); + + if (!hwndPrev) + { + hwndPrev = ghwndList2; + } + + SetFocus (hwndPrev); + break; + } + case IDC_NEXTCTRL: + { + HWND hwndNext = GetNextWindow (GetFocus (), GW_HWNDNEXT); + + if (!hwndNext) + { + hwndNext = GetDlgItem (hwnd, IDC_BUTTON12); + } + + SetFocus (hwndNext); + break; + } + case IDC_ENTER: + { + if (GetFocus() != ghwndEdit) + { + GetCurrentSelections (); + FuncDriver( + (FUNC_INDEX)SendMessage( + ghwndList2, + LB_GETCURSEL, + 0, + 0 + )); + } + else + { + // Send the edit ctrl a cr/lf + } + + break; + } + case IDC_LIST1: + +#ifdef WIN32 + switch (HIWORD(wParam)) +#else + switch (HIWORD(lParam)) +#endif + { + case LBN_DBLCLK: + { + LONG lSel = SendMessage (ghwndList1, LB_GETCURSEL, 0, 0); + PMYWIDGET pWidget; + + + pWidget = (PMYWIDGET) SendMessage( + ghwndList1, + LB_GETITEMDATA, + (WPARAM) lSel, + 0 + ); + + if ((pWidget->dwType == WT_LINEAPP) + || (pWidget->dwType == WT_PHONEAPP) + ) + { + break; + } + + bShowParams = FALSE; + + UpdateResults (TRUE); + + switch (pWidget->dwType) + { + case WT_LINE: + { + DWORD dwDefLineDeviceIDSave = dwDefLineDeviceID; + PMYLINE pLine = (PMYLINE) pWidget; + + + dwDefLineDeviceID = pLine->dwDevID; + + pLineAppSel = GetLineApp (pLine->hLineApp); + pLineSel = pLine; + + FuncDriver (lGetDevCaps); + FuncDriver (lGetLineDevStatus); + + dwDefLineDeviceID = dwDefLineDeviceIDSave; + break; + } + case WT_CALL: + { + PMYCALL pCall = (PMYCALL) pWidget; + + + pCallSel = pCall; + + FuncDriver (lGetCallInfo); + FuncDriver (lGetCallStatus); + + break; + } + case WT_PHONE: + { + DWORD dwDefPhoneDeviceIDSave = dwDefPhoneDeviceID; + PMYPHONE pPhone = (PMYPHONE) pWidget; + + + dwDefPhoneDeviceID = pPhone->dwDevID; + + pPhoneAppSel = GetPhoneApp (pPhone->hPhoneApp); + pPhoneSel = pPhone; + + FuncDriver (pGetDevCaps); + FuncDriver (pGetStatus); + + dwDefPhoneDeviceID = dwDefPhoneDeviceIDSave; + break; + } + } + + UpdateResults (FALSE); + + bShowParams = bShowParamsSave; + + break; + } + } // switch + + break; + + case IDC_LIST2: + +#ifdef WIN32 + if (HIWORD(wParam) == LBN_DBLCLK) +#else + if (HIWORD(lParam) == LBN_DBLCLK) +#endif + { + GetCurrentSelections (); + FuncDriver( + (FUNC_INDEX)SendMessage( + ghwndList2, + LB_GETCURSEL, + 0, + 0 + )); + } + + break; + + case IDM_EXIT: + { + PostMessage (hwnd, WM_CLOSE, 0, 0); + break; + } + case IDM_DEFAULTVALUES: + { + char szTmpAppName[MAX_STRING_PARAM_SIZE]; + char szTmpUserUserInfo[MAX_STRING_PARAM_SIZE]; + char szTmpDestAddress[MAX_STRING_PARAM_SIZE]; + char szTmpLineDeviceClass[MAX_STRING_PARAM_SIZE]; + char szTmpPhoneDeviceClass[MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { "Buffer size", PT_DWORD, dwBigBufSize, NULL }, + { "lpszAppName", PT_STRING, (DWORD) lpszDefAppName, szTmpAppName }, + + { "line: dwAddressID", PT_DWORD, dwDefAddressID, NULL }, + { "line: dwAPIVersion", PT_DWORD, dwDefLineAPIVersion, NULL }, + { "line: dwBearerMode", PT_FLAGS, dwDefBearerMode, aBearerModes }, + { "line: dwCountryCode", PT_DWORD, dwDefCountryCode, NULL }, + { "line: dwDeviceID", PT_DWORD, dwDefLineDeviceID, NULL }, + { "line: dwExtVersion", PT_DWORD, dwDefLineExtVersion, NULL }, + { "line: dwMediaMode", PT_FLAGS, dwDefMediaMode, aMediaModes }, + { "line: dwPrivileges", PT_FLAGS, dwDefLinePrivilege, aLineOpenOptions }, + { "line: lpsUserUserInfo", PT_STRING, (DWORD) lpszDefUserUserInfo, szTmpUserUserInfo }, + { "line: lpszDestAddress", PT_STRING, (DWORD) lpszDefDestAddress, szTmpDestAddress }, + { "line: lpszDeviceClass", PT_STRING, (DWORD) lpszDefLineDeviceClass, szTmpLineDeviceClass }, + { "phone: dwAPIVersion", PT_DWORD, dwDefPhoneAPIVersion, NULL }, + { "phone: dwDeviceID", PT_DWORD, dwDefPhoneDeviceID, NULL }, + { "phone: dwExtVersion", PT_DWORD, dwDefPhoneExtVersion, NULL }, + { "phone: dwPrivilege", PT_FLAGS, dwDefPhonePrivilege, aPhonePrivileges }, + { "phone: lpszDeviceClass", PT_STRING, (DWORD) lpszDefPhoneDeviceClass, szTmpPhoneDeviceClass } + }; + FUNC_PARAM_HEADER paramsHeader = + { 18, DefValues, params, NULL }; + BOOL bShowParamsSave = bShowParams; + + bShowParams = TRUE; + + strcpy (szTmpAppName, szDefAppName); + strcpy (szTmpUserUserInfo, szDefUserUserInfo); + strcpy (szTmpDestAddress, szDefDestAddress); + strcpy (szTmpLineDeviceClass, szDefLineDeviceClass); + strcpy (szTmpPhoneDeviceClass, szDefPhoneDeviceClass); + + if (LetUserMungeParams (¶msHeader)) + { + if (params[0].dwValue != dwBigBufSize) + { + LPVOID pTmpBigBuf = malloc ((size_t) params[0].dwValue); + + if (pTmpBigBuf) + { + free (pBigBuf); + pBigBuf = pTmpBigBuf; + dwBigBufSize = params[0].dwValue; + } + } + + strcpy (szDefAppName, szTmpAppName); + + dwDefAddressID = params[2].dwValue; + dwDefLineAPIVersion = params[3].dwValue; + dwDefBearerMode = params[4].dwValue; + dwDefCountryCode = params[5].dwValue; + dwDefLineDeviceID = params[6].dwValue; + dwDefLineExtVersion = params[7].dwValue; + dwDefMediaMode = params[8].dwValue; + dwDefLinePrivilege = params[9].dwValue; + + strcpy (szDefUserUserInfo, szTmpUserUserInfo); + strcpy (szDefDestAddress, szTmpDestAddress); + strcpy (szDefLineDeviceClass, szTmpLineDeviceClass); + + dwDefPhoneAPIVersion = params[13].dwValue; + dwDefPhoneDeviceID = params[14].dwValue; + dwDefPhoneExtVersion = params[15].dwValue; + dwDefPhonePrivilege = params[16].dwValue; + + strcpy (szDefPhoneDeviceClass, szTmpPhoneDeviceClass); + + if (params[1].dwValue && (params[1].dwValue != 0xffffffff)) + { + lpszDefAppName = szDefAppName; + } + else + { + lpszDefAppName = (char far *) params[1].dwValue; + } + + if (params[10].dwValue && (params[10].dwValue != 0xffffffff)) + { + lpszDefUserUserInfo = szDefUserUserInfo; + } + else + { + lpszDefUserUserInfo = (char far *) params[10].dwValue; + } + + if (params[11].dwValue && (params[11].dwValue != 0xffffffff)) + { + lpszDefDestAddress = szDefDestAddress; + } + else + { + lpszDefDestAddress = (char far *) params[11].dwValue; + } + + if (params[12].dwValue && (params[12].dwValue != 0xffffffff)) + { + lpszDefLineDeviceClass = szDefLineDeviceClass; + } + else + { + lpszDefLineDeviceClass = (char far *) params[12].dwValue; + } + + if (params[17].dwValue && (params[17].dwValue != 0xffffffff)) + { + lpszDefPhoneDeviceClass = szDefPhoneDeviceClass; + } + else + { + lpszDefPhoneDeviceClass = (char far *) params[17].dwValue; + } + } + + bShowParams = bShowParamsSave; + + break; + } + case IDM_USERBUTTONS: + + DialogBoxParam( + ghInst, + (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3), + (HWND) hwnd, + (DLGPROC) UserButtonsDlgProc, + (LPARAM) NULL + ); + + break; + + case IDM_DUMPPARAMS: + + bDumpParams = (bDumpParams ? FALSE : TRUE); + + CheckMenuItem( + hMenu, + IDM_DUMPPARAMS, + MF_BYCOMMAND | (bDumpParams ? MF_CHECKED : MF_UNCHECKED) + ); + + break; + + case IDM_LOGSTRUCTDWORD: + case IDM_LOGSTRUCTALLFIELD: + case IDM_LOGSTRUCTNONZEROFIELD: + case IDM_LOGSTRUCTNONE: + + for (i = 0; aXxx[i].dwFlags != dwDumpStructsFlags; i++); + + CheckMenuItem( + hMenu, + aXxx[i].dwMenuID, + MF_BYCOMMAND | MF_UNCHECKED + ); + + for (i = 0; aXxx[i].dwMenuID != LOWORD((DWORD)wParam); i++); + + CheckMenuItem( + hMenu, + aXxx[i].dwMenuID, + MF_BYCOMMAND | MF_CHECKED + ); + + dwDumpStructsFlags = aXxx[i].dwFlags; + + break; + + case IDM_TIMESTAMP: + + bTimeStamp = (bTimeStamp ? FALSE : TRUE); + + CheckMenuItem( + hMenu, + IDM_TIMESTAMP, + MF_BYCOMMAND | (bTimeStamp ? MF_CHECKED : MF_UNCHECKED) + ); + + break; + + case IDM_LOGFILE: + { + if (hLogFile) + { + fclose (hLogFile); + hLogFile = (FILE *) NULL; + CheckMenuItem( + hMenu, + IDM_LOGFILE, + MF_BYCOMMAND | MF_UNCHECKED + ); + } + else + { + OPENFILENAME ofn; + char szDirName[256] = ".\\"; + char szFile[256] = "tb.log\0"; + char szFileTitle[256] = ""; + static char *szFilter = + "Log files (*.log)\0*.log\0All files (*.*)\0*.*\0\0"; + + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = szFilter; + ofn.lpstrCustomFilter = (LPSTR) NULL; + ofn.nMaxCustFilter = 0L; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = sizeof(szFileTitle); + ofn.lpstrInitialDir = szDirName; + ofn.lpstrTitle = (LPSTR) NULL; + ofn.Flags = 0L; + ofn.nFileOffset = 0; + ofn.nFileExtension = 0; + ofn.lpstrDefExt = "LOG"; + + if (!GetOpenFileName(&ofn)) + { + return 0L; + } + + if ((hLogFile = fopen (szFile, "at")) == (FILE *) NULL) + { + MessageBox( + hwnd, + "Error creating log file", +#ifdef WIN32 + "TB32.EXE", +#else + "TB.EXE", +#endif + MB_OK + ); + } + else + { + struct tm *newtime; + time_t aclock; + + + time (&aclock); + newtime = localtime (&aclock); + fprintf( + hLogFile, + "\n---Log opened: %s\n", + asctime (newtime) + ); + + CheckMenuItem( + hMenu, + IDM_LOGFILE, + MF_BYCOMMAND | MF_CHECKED + ); + } + } + break; + } + case IDM_USINGTB: + { + static char szUsingTB[] = + + "ABSTRACT:\r\n" \ + " TB (TAPI Browser) is an application that\r\n" \ + "allows a user to interactively call into the\r\n" \ + "Windows Telephony interface and inspect all\r\n" \ + "returned information. The following versions\r\n" \ + "of TB are available:\r\n\r\n" \ + " TB13.EXE: 16-bit app, TAPI v1.0\r\n" \ + " TB14.EXE: 32-bit app, <= TAPI v1.4\r\n" \ + " TB20.EXE: 32-bit app, <= TAPI v2.0\r\n" \ + + "\r\n" \ + "GETTING STARTED:\r\n" \ + "1. Press the 'LAp+' button to initialize TAPI \r\n" \ + "2. Press the 'Line+' button to open a line device\r\n" \ + "3. Press the 'Call+' button to make a call\r\n" \ + "* Pressing the 'LAp-' button will shutdown TAPI\r\n" \ + + "\r\n" \ + "MORE INFO:\r\n" \ + "* Double-clicking on one of the items in the\r\n" \ + "functions listbox (far left) will invoke that \r\n" \ + "function. Check the 'Params' checkbox to enable\r\n" \ + "parameter modification.\r\n" \ + "* Choose 'Options/Default values...' to modify\r\n" \ + "default parameter values (address,device ID, etc).\r\n"\ + "* Choose 'Options/Record log file' to save all\r\n" \ + "output to a file.\r\n" \ + "* All parameter values in hexadecimal unless\r\n" \ + "specified (strings displayed by contents, not \r\n" \ + "pointer value).\r\n" \ + "* All 'Xxx+' and 'Xxx-' buttons are essentially \r\n" \ + "hot-links to items in the functions listbox.\r\n" \ + "* Choose 'Options/User buttons...' or press\r\n" \ + "one of the buttons on right side of toolbar to\r\n" \ + "create a personal hot-link between a button and a\r\n" \ + "particular function.\r\n" \ + + "\r\n" \ + " * Note: Selecting a API version parameter value\r\n"\ + "which is newer than that for which TB application\r\n" \ + "is targeted will result in erroneous dumps of some\r\n"\ + "structures (e.g. specifying an API version of\r\n" \ + "0x10004 and calling lineGetTranslateCaps in TB13).\r\n"; + + DialogBoxParam( + ghInst, + (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG6), + (HWND)hwnd, + (DLGPROC) AboutDlgProc, + (LPARAM) szUsingTB + ); + + break; + } +// help case IDM_TAPIHLP: +// help +// help MyWinHelp (hwnd, TRUE, HELP_CONTENTS, 0); +// help break; + +// help case IDM_TSPIHLP: +// help +// help MyWinHelp (hwnd, FALSE, HELP_CONTENTS, 0); +// help break; + + case IDM_NUKEIDLEMONITORCALLS: + + bNukeIdleMonitorCalls = (bNukeIdleMonitorCalls ? 0 : 1); + + CheckMenuItem( + hMenu, + IDM_NUKEIDLEMONITORCALLS, + MF_BYCOMMAND | + (bNukeIdleMonitorCalls ? MF_CHECKED : MF_UNCHECKED) + ); + + break; + + case IDM_NUKEIDLEOWNEDCALLS: + + bNukeIdleOwnedCalls = (bNukeIdleOwnedCalls ? 0 : 1); + + CheckMenuItem( + hMenu, + IDM_NUKEIDLEOWNEDCALLS, + MF_BYCOMMAND | + (bNukeIdleOwnedCalls ? MF_CHECKED : MF_UNCHECKED) + ); + + break; + + case IDM_NOHANDLECHK: + + gbDisableHandleChecking = (gbDisableHandleChecking ? 0 : 1); + + CheckMenuItem( + hMenu, + IDM_NOHANDLECHK, + MF_BYCOMMAND | + (gbDisableHandleChecking ? MF_CHECKED : MF_UNCHECKED) + ); + + break; + + case IDM_ABOUT: + { + DialogBoxParam( + ghInst, + (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG4), + (HWND)hwnd, + (DLGPROC) AboutDlgProc, + 0 + ); + + break; + } + } // switch + + break; + } +#ifdef WIN32 + case WM_CTLCOLORBTN: + + SetBkColor ((HDC) wParam, RGB (192,192,192)); + return (BOOL) GetStockObject (LTGRAY_BRUSH); +#else + case WM_CTLCOLOR: + { + if (HIWORD(lParam) == CTLCOLOR_BTN) + { + SetBkColor ((HDC) wParam, RGB (192,192,192)); + return (BOOL) GetStockObject (LTGRAY_BRUSH); + } + break; + } +#endif + + case WM_MOUSEMOVE: + { + LONG x = (LONG)((short)LOWORD(lParam)); + int y = (int)((short)HIWORD(lParam)); + + + if ((y > icyButton) || lCaptureFlags) + { + SetCursor (LoadCursor (NULL, MAKEINTRESOURCE(IDC_SIZEWE))); + } + + if (lCaptureFlags == 1) + { + int cxList2New; + + + x = (x > (cxList1 + cxList2 - cxVScroll) ? + (cxList1 + cxList2 - cxVScroll) : x); + x = (x < cxVScroll ? cxVScroll : x); + + cxList2New = (int) (cxList2 + x - xCapture); + + SetWindowPos( + ghwndList2, + GetNextWindow (ghwndList2, GW_HWNDPREV), + 0, + icyButton, + cxList2New, + cyWnd, + SWP_SHOWWINDOW + ); + + SetWindowPos( + ghwndList1, + GetNextWindow (ghwndList1, GW_HWNDPREV), + cxList2New + icyBorder, + icyButton, + (int) (cxList1 - (x - xCapture)), + cyWnd, + SWP_SHOWWINDOW + ); + } + else if (lCaptureFlags == 2) + { + int cxList1New; + + + x = (x < (cxList2 + cxVScroll) ? (cxList2 + cxVScroll) : x); + x = (x > (cxWnd - cxVScroll) ? (cxWnd - cxVScroll) : x); + + cxList1New = (int) (cxList1 + x - xCapture); + + SetWindowPos( + ghwndList1, + GetNextWindow (ghwndList1, GW_HWNDPREV), + (int) cxList2 + icyBorder, + icyButton, + cxList1New, + cyWnd, + SWP_SHOWWINDOW + ); + + SetWindowPos( + ghwndEdit, + GetNextWindow (ghwndEdit, GW_HWNDPREV), + (int) (cxList1New + cxList2) + 2*icyBorder, + icyButton, + (int)cxWnd - (cxList1New + (int)cxList2 + 2*icyBorder), + cyWnd, + SWP_SHOWWINDOW + ); + } + + break; + } + case WM_LBUTTONDOWN: + { + if ((int)((short)HIWORD(lParam)) > icyButton) + { + xCapture = (LONG)LOWORD(lParam); + + SetCapture (hwnd); + + lCaptureFlags = ((xCapture < cxList1 + cxList2) ? 1 : 2); + } + + break; + } + case WM_LBUTTONUP: + { + if (lCaptureFlags) + { + POINT p; + LONG x; + RECT rect = { 0, icyButton, 2000, 2000 }; + + GetCursorPos (&p); + MapWindowPoints (HWND_DESKTOP, hwnd, &p, 1); + x = (LONG) p.x; + + ReleaseCapture(); + + if (lCaptureFlags == 1) + { + x = (x < cxVScroll ? cxVScroll : x); + x = (x > (cxList1 + cxList2 - cxVScroll) ? + (cxList1 + cxList2 - cxVScroll) : x); + + cxList2 = cxList2 + (x - xCapture); + cxList1 = cxList1 - (x - xCapture); + + rect.right = (int) (cxList1 + cxList2) + icyBorder; + } + else + { + x = (x < (cxList2 + cxVScroll) ? + (cxList2 + cxVScroll) : x); + x = (x > (cxWnd - cxVScroll) ? + (cxWnd - cxVScroll) : x); + + cxList1 = cxList1 + (x - xCapture); + + rect.left = (int)cxList2 + icyBorder; + } + + lCaptureFlags = 0; + + InvalidateRect (hwnd, &rect, TRUE); + } + + break; + } + case WM_SIZE: + { + if (wParam != SIZE_MINIMIZED) + { + LONG width = (LONG)LOWORD(lParam); + + + // + // Adjust globals based on new size + // + + cxWnd = (cxWnd ? cxWnd : 1); // avoid div by 0 + + cxList1 = (cxList1 * width) / cxWnd; + cxList2 = (cxList2 * width) / cxWnd; + cxWnd = width; + cyWnd = ((int)HIWORD(lParam)) - icyButton; + + + // + // Now reposition the child windows + // + + SetWindowPos( + ghwndList2, + GetNextWindow (ghwndList2, GW_HWNDPREV), + 0, + icyButton, + (int) cxList2, + cyWnd, + SWP_SHOWWINDOW + ); + + SetWindowPos( + ghwndList1, + GetNextWindow (ghwndList1, GW_HWNDPREV), + (int) cxList2 + icyBorder, + icyButton, + (int) cxList1, + cyWnd, + SWP_SHOWWINDOW + ); + + SetWindowPos( + ghwndEdit, + GetNextWindow (ghwndEdit, GW_HWNDPREV), + (int) (cxList1 + cxList2) + 2*icyBorder, + icyButton, + (int)width - ((int)(cxList1 + cxList2) + 2*icyBorder), + cyWnd, + SWP_SHOWWINDOW + ); + + InvalidateRect (hwnd, NULL, TRUE); + } + + break; + } + case WM_PAINT: + { + PAINTSTRUCT ps; + + + BeginPaint (hwnd, &ps); + + if (IsIconic (hwnd)) + { + DrawIcon (ps.hdc, 0, 0, hIcon); + } + else + { + FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH)); +#ifdef WIN32 + MoveToEx (ps.hdc, 0, 0, NULL); +#else + MoveTo (ps.hdc, 0, 0); +#endif + LineTo (ps.hdc, 5000, 0); + +#ifdef WIN32 + MoveToEx (ps.hdc, 0, icyButton - 4, NULL); +#else + MoveTo (ps.hdc, 0, icyButton - 4); +#endif + LineTo (ps.hdc, 5000, icyButton - 4); + } + + EndPaint (hwnd, &ps); + + break; + } + case WM_CLOSE: + { + BOOL bAutoShutdown = FALSE; + RECT rect; + + + // + // Save defaults in ini file + // + + { + char buf[32]; + typedef struct _DEF_VALUE2 + { + char far *lpszEntry; + DWORD dwValue; + + } DEF_VALUE2; + + DEF_VALUE2 aDefVals[] = + { + { "BufSize", dwBigBufSize }, + { "AddressID", dwDefAddressID }, +#if TAPI_2_0 + { "20LineAPIVersion", dwDefLineAPIVersion }, +#else +#if TAPI_1_1 + { "14LineAPIVersion", dwDefLineAPIVersion }, +#else + { "13LineAPIVersion", dwDefLineAPIVersion }, +#endif +#endif + { "BearerMode", dwDefBearerMode }, + { "CountryCode", dwDefCountryCode }, + { "LineDeviceID", dwDefLineDeviceID }, + { "LineExtVersion", dwDefLineExtVersion }, + { "MediaMode", dwDefMediaMode }, + { "LinePrivilege", dwDefLinePrivilege }, +#if TAPI_2_0 + { "20PhoneAPIVersion", dwDefPhoneAPIVersion }, +#else +#if TAPI_1_1 + { "14PhoneAPIVersion", dwDefPhoneAPIVersion }, +#else + { "13PhoneAPIVersion", dwDefPhoneAPIVersion }, +#endif +#endif + { "PhoneDeviceID", dwDefPhoneDeviceID }, + { "PhoneExtVersion", dwDefPhoneExtVersion }, + { "PhonePrivilege", dwDefPhonePrivilege }, +#if TAPI_2_0 + { "20UserButton1", aUserButtonFuncs[0] }, + { "20UserButton2", aUserButtonFuncs[1] }, + { "20UserButton3", aUserButtonFuncs[2] }, + { "20UserButton4", aUserButtonFuncs[3] }, + { "20UserButton5", aUserButtonFuncs[4] }, + { "20UserButton6", aUserButtonFuncs[5] }, +#else +#if TAPI_1_1 + { "14UserButton1", aUserButtonFuncs[0] }, + { "14UserButton2", aUserButtonFuncs[1] }, + { "14UserButton3", aUserButtonFuncs[2] }, + { "14UserButton4", aUserButtonFuncs[3] }, + { "14UserButton5", aUserButtonFuncs[4] }, + { "14UserButton6", aUserButtonFuncs[5] }, +#else + { "13UserButton1", aUserButtonFuncs[0] }, + { "13UserButton2", aUserButtonFuncs[1] }, + { "13UserButton3", aUserButtonFuncs[2] }, + { "13UserButton4", aUserButtonFuncs[3] }, + { "13UserButton5", aUserButtonFuncs[4] }, + { "13UserButton6", aUserButtonFuncs[5] }, +#endif +#endif + { "TimeStamp", bTimeStamp }, + { "NukeIdleMonitorCalls", bNukeIdleMonitorCalls }, + { "NukeIdleOwnedCalls", bNukeIdleOwnedCalls }, + { "DisableHandleChecking", gbDisableHandleChecking }, + { "DumpStructsFlags", dwDumpStructsFlags }, + { NULL, 0 }, + { "Version", (DWORD) szCurrVer }, + { "UserUserInfo", (DWORD) szDefUserUserInfo }, + { "DestAddress", (DWORD) szDefDestAddress }, + { "LineDeviceClass", (DWORD) szDefLineDeviceClass }, + { "PhoneDeviceClass", (DWORD) szDefPhoneDeviceClass }, + { "AppName", (DWORD) szDefAppName }, +#if TAPI_2_0 + { "20UserButton1Text", (DWORD) &aUserButtonsText[0] }, + { "20UserButton2Text", (DWORD) &aUserButtonsText[1] }, + { "20UserButton3Text", (DWORD) &aUserButtonsText[2] }, + { "20UserButton4Text", (DWORD) &aUserButtonsText[3] }, + { "20UserButton5Text", (DWORD) &aUserButtonsText[4] }, + { "20UserButton6Text", (DWORD) &aUserButtonsText[5] }, +#else +#if TAPI_1_1 + { "14UserButton1Text", (DWORD) &aUserButtonsText[0] }, + { "14UserButton2Text", (DWORD) &aUserButtonsText[1] }, + { "14UserButton3Text", (DWORD) &aUserButtonsText[2] }, + { "14UserButton4Text", (DWORD) &aUserButtonsText[3] }, + { "14UserButton5Text", (DWORD) &aUserButtonsText[4] }, + { "14UserButton6Text", (DWORD) &aUserButtonsText[5] }, +#else + { "13UserButton1Text", (DWORD) &aUserButtonsText[0] }, + { "13UserButton2Text", (DWORD) &aUserButtonsText[1] }, + { "13UserButton3Text", (DWORD) &aUserButtonsText[2] }, + { "13UserButton4Text", (DWORD) &aUserButtonsText[3] }, + { "13UserButton5Text", (DWORD) &aUserButtonsText[4] }, + { "13UserButton6Text", (DWORD) &aUserButtonsText[5] }, +#endif +#endif +// help { "TapiHlpPath", (DWORD) szTapiHlp }, +// help { "TspiHlpPath", (DWORD) szTspiHlp }, + { NULL, 0 } + }; + + int i; + + for (i = 0; aDefVals[i].lpszEntry; i++) + { + sprintf (buf, "%lx", aDefVals[i].dwValue); + + WriteProfileString( + MYSECTION, + aDefVals[i].lpszEntry, + buf + ); + } + + i++; + + for (; aDefVals[i].lpszEntry; i++) + { + WriteProfileString( + MYSECTION, + aDefVals[i].lpszEntry, + (LPCSTR) aDefVals[i].dwValue + ); + } + + + // + // Save the window dimensions (if iconic then don't bother) + // + + if (!IsIconic (hwnd)) + { + if (IsZoomed (hwnd)) + { + strcpy (buf, "max"); + } + else + { + GetWindowRect (hwnd, &rect); + + sprintf( + buf, + "%d,%d,%d,%d", + rect.left, + rect.top, + rect.right, + rect.bottom + ); + } + + WriteProfileString( + MYSECTION, + "Position", + (LPCSTR) buf + ); + + sprintf (buf, "%ld,%ld,%ld", cxList2, cxList1, cxWnd); + + WriteProfileString( + MYSECTION, + "ControlRatios", + (LPCSTR) buf + ); + } + } + + + + // + // Give user chance to auto-shutdown any active line/phone apps + // + + if (aWidgets) + { + if (MessageBox( + hwnd, + "Shutdown all hLineApps/hPhoneApps? (recommended)", + "Tapi Browser closing", + MB_YESNO + ) == IDNO) + { + goto WM_CLOSE_freeBigBuf; + } + + bShowParams = FALSE; + + while (aWidgets) + { + PMYWIDGET pWidgetToClose = aWidgets; + + + if (aWidgets->dwType == WT_LINEAPP) + { + pLineAppSel = (PMYLINEAPP) aWidgets; + FuncDriver (lShutdown); + } + else if (aWidgets->dwType == WT_PHONEAPP) + { + pPhoneAppSel = (PMYPHONEAPP) aWidgets; + FuncDriver (pShutdown); + } + + if (pWidgetToClose == aWidgets) + { + // + // The shutdown wasn't successful (or our list is + // messed up an it'd not a LINEAPP or PHONEAPP widget), + // so manually nuke this widget so we don't hang in + // this loop forever + // + + RemoveWidgetFromList (pWidgetToClose); + } + } + } + +WM_CLOSE_freeBigBuf: + + if (hLogFile) + { + fclose (hLogFile); + } + DestroyIcon (hIcon); + free (pBigBuf); + free (lpCallParams); +// if (aSelWidgets) +// { +// free (aSelWidgets); +// } +// if (aSelWidgetsPrev) +// { +// free (aSelWidgetsPrev); +// } + DeleteObject (hFont); + DeleteObject (hFont2); + PostQuitMessage (0); + break; + + } + } //switch + + return FALSE; +} + + +BOOL +CALLBACK +AboutDlgProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam + ) +{ + switch (msg) + { + case WM_INITDIALOG: + + if (lParam) + { + SetDlgItemText (hwnd, IDC_EDIT1, (LPCSTR) lParam); + } + + break; + + case WM_COMMAND: + + switch (LOWORD(wParam)) + { + case IDOK: + + EndDialog (hwnd, 0); + break; + } + break; + +#ifdef WIN32 + case WM_CTLCOLORSTATIC: + + SetBkColor ((HDC) wParam, RGB (192,192,192)); + return (BOOL) GetStockObject (LTGRAY_BRUSH); +#else + case WM_CTLCOLOR: + { + if (HIWORD(lParam) == CTLCOLOR_STATIC) + { + SetBkColor ((HDC) wParam, RGB (192,192,192)); + return (BOOL) GetStockObject (LTGRAY_BRUSH); + } + break; + } +#endif + case WM_PAINT: + { + PAINTSTRUCT ps; + + BeginPaint (hwnd, &ps); + FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH)); + EndPaint (hwnd, &ps); + + break; + } + } + + return FALSE; +} + + +void +FAR +ShowStr( + LPCSTR format, + ... + ) +{ + char buf[256]; + va_list ap; + + + va_start(ap, format); + wvsprintf (buf, format, ap); + + if (hLogFile) + { + fprintf (hLogFile, "%s\n", buf); + } + + strcat (buf, "\r\n"); + + + // + // Insert text at end + // + +#ifdef WIN32 + SendMessage (ghwndEdit, EM_SETSEL, (WPARAM)0xfffffffd, (LPARAM)0xfffffffe); +#else + SendMessage( + ghwndEdit, + EM_SETSEL, + (WPARAM)0, + (LPARAM) MAKELONG(0xfffd,0xfffe) + ); +#endif + + SendMessage (ghwndEdit, EM_REPLACESEL, 0, (LPARAM) buf); + + +#ifdef WIN32 + + // + // Scroll to end of text + // + + SendMessage (ghwndEdit, EM_SCROLLCARET, 0, 0); +#endif + + va_end(ap); +} + + +VOID +UpdateWidgetListCall( + PMYCALL pCall + ) +{ + LONG i, lSel; + char buf[64]; + + + for (i = 0; aCallStates[i].dwVal != 0xffffffff; i++) + { + if (pCall->dwCallState == aCallStates[i].dwVal) + { + break; + } + } + + sprintf( + buf, + " Call=x%lx %s %s", + pCall->hCall, + aCallStates[i].lpszVal, + (pCall->bMonitor ? "Monitor" : "Owner") + ); + + i = (LONG) GetWidgetIndex ((PMYWIDGET) pCall); + + lSel = SendMessage (ghwndList1, LB_GETCURSEL, 0, 0); + SendMessage (ghwndList1, LB_DELETESTRING, (WPARAM) i, 0); + SendMessage (ghwndList1, LB_INSERTSTRING, (WPARAM) i, (LPARAM) buf); + SendMessage (ghwndList1, LB_SETITEMDATA, (WPARAM) i, (LPARAM) pCall); + + if (lSel == i) + { + SendMessage (ghwndList1, LB_SETCURSEL, (WPARAM) i, 0); + } +} + + +VOID +CALLBACK +tapiCallback( + DWORD hDevice, + DWORD dwMsg, + DWORD dwCallbackInstance, + DWORD dwParam1, + DWORD dwParam2, + DWORD dwParam3 + ) +{ + typedef struct _MSG_PARAMS + { + char *lpszMsg; + + LPVOID aParamFlagTables[3]; + + } MSG_PARAMS, *PMSG_PARAMS; + + static MSG_PARAMS msgParams[] = + { + { "LINE_ADDRESSSTATE", { NULL, aAddressStates, NULL } }, + { "LINE_CALLINFO", { aCallInfoStates, NULL, NULL } }, + { "LINE_CALLSTATE", { aCallStates, NULL, aCallPrivileges } }, + { "LINE_CLOSE", { NULL, NULL, NULL } }, + { "LINE_DEVSPECIFIC", { NULL, NULL, NULL } }, + { "LINE_DEVSPECIFICFEATURE", { NULL, NULL, NULL } }, + { "LINE_GATHERDIGITS", { aGatherTerms, NULL, NULL } }, + { "LINE_GENERATE", { aGenerateTerms, NULL, NULL } }, + { "LINE_LINEDEVSTATE", { aLineStates, NULL, NULL } }, + { "LINE_MONITORDIGITS", { NULL, aDigitModes, NULL } }, + { "LINE_MONITORMEDIA", { aMediaModes, NULL, NULL } }, + { "LINE_MONITORTONE", { NULL, NULL, NULL } }, + { "LINE_REPLY", { NULL, NULL, NULL } }, + { "LINE_REQUEST", { aRequestModes, NULL, NULL } } + , + { "PHONE_BUTTON", { NULL, aButtonModes, aButtonStates } }, + { "PHONE_CLOSE", { NULL, NULL, NULL } }, + { "PHONE_DEVSPECIFIC", { NULL, NULL, NULL } }, + { "PHONE_REPLY", { NULL, NULL, NULL } }, + { "PHONE_STATE", { aPhoneStates, NULL, NULL } } + +#if TAPI_1_1 + , + { "LINE_CREATE", { NULL, NULL, NULL } }, + { "PHONE_CREATE", { NULL, NULL, NULL } } + +#if TAPI_2_0 + , + { "LINE_AGENTSPECIFIC", { NULL, NULL, NULL } }, + { "LINE_AGENTSTATUS", { NULL, NULL, NULL } }, + { "LINE_APPNEWCALL", { NULL, NULL, aCallPrivileges } }, + { "LINE_PROXYREQUEST", { NULL, NULL, NULL } }, + { "LINE_REMOVE", { NULL, NULL, NULL } }, + { "PHONE_REMOVE", { NULL, NULL, NULL } } + +#endif + +#endif + + }; + int i, j; + LONG lResult; + + + UpdateResults (TRUE); + +#if TAPI_1_1 +#if TAPI_2_0 + if (dwMsg <= PHONE_REMOVE) +#else + if (dwMsg <= PHONE_CREATE) +#endif +#else + if (dwMsg <= PHONE_STATE) +#endif + { + DWORD aParams[3] = { dwParam1, dwParam2, dwParam3 }; + + + { + char *pszTimeStamp = GetTimeStamp(); + + ShowStr( + "%sreceived %s", + pszTimeStamp, + msgParams[dwMsg].lpszMsg + ); + } + + ShowStr ("%sdevice=x%lx", szTab, hDevice); + ShowStr ("%scbInst=x%lx", szTab, dwCallbackInstance); + + if (dwMsg == LINE_CALLSTATE) + { + msgParams[2].aParamFlagTables[1] = NULL; + + switch (dwParam1) + { + case LINECALLSTATE_BUSY: + + msgParams[2].aParamFlagTables[1] = (LPVOID) aBusyModes; + break; + + case LINECALLSTATE_DIALTONE: + + msgParams[2].aParamFlagTables[1] = (LPVOID) aDialToneModes; + break; + + case LINECALLSTATE_SPECIALINFO: + + msgParams[2].aParamFlagTables[1] = (LPVOID) aSpecialInfo; + break; + + case LINECALLSTATE_DISCONNECTED: + + msgParams[2].aParamFlagTables[1] = (LPVOID) aDisconnectModes; + break; + +#if TAPI_1_1 + + case LINECALLSTATE_CONNECTED: + + msgParams[2].aParamFlagTables[1] = (LPVOID) aConnectedModes; + break; + + case LINECALLSTATE_OFFERING: + + msgParams[2].aParamFlagTables[1] = (LPVOID) aOfferingModes; + break; + +#endif // TAPI_1_1 + + } // switch + } + + else if (dwMsg == PHONE_STATE) + { + msgParams[18].aParamFlagTables[1] = NULL; + + switch (dwParam1) + { + case PHONESTATE_HANDSETHOOKSWITCH: + case PHONESTATE_SPEAKERHOOKSWITCH: + case PHONESTATE_HEADSETHOOKSWITCH: + + msgParams[18].aParamFlagTables[1] = aHookSwitchModes; + break; + + } // switch + } + + for (i = 0; i < 3; i++) + { + char buf[80]; + + + sprintf (buf, "%sparam%d=x%lx, ", szTab, i+1, aParams[i]); + + if (msgParams[dwMsg].aParamFlagTables[i]) + { + PLOOKUP pLookup = (PLOOKUP) + msgParams[dwMsg].aParamFlagTables[i]; + + + for (j = 0; aParams[i], pLookup[j].dwVal != 0xffffffff; j++) + { + if (aParams[i] & pLookup[j].dwVal) + { + if (buf[0] == 0) + { + sprintf (buf, "%s%s", szTab, szTab); + } + + strcat (buf, pLookup[j].lpszVal); + strcat (buf, " "); + aParams[i] = aParams[i] & ~pLookup[j].dwVal; + + if (strlen (buf) > 50) + { + // + // We don't want strings getting so long that + // they're going offscreen, so break them up. + // + + ShowStr (buf); + buf[0] = 0; + } + } + } + + if (aParams[i]) + { + strcat (buf, "<unknown flag(s)>"); + } + + } + + if (buf[0]) + { + ShowStr (buf); + } + } + } + else + { + ShowStr ("ERROR! callback received unknown msg=x%lx", dwMsg); + ShowStr ("%shDev=x%lx, cbInst=x%lx, p1=x%lx, p2=x%lx, p3=x%lx", + szTab, + hDevice, + dwCallbackInstance, + dwParam1, + dwParam2, + dwParam3 + ); + + return; + } + + UpdateResults (FALSE); + + switch (dwMsg) + { + case LINE_CALLSTATE: + { + PMYLINE pLine; + PMYCALL pCall = GetCall ((HCALL) hDevice); + + + // + // If the call state is idle & we're in "nuke idle xxx calls" + // mode then determine the privilege of this callto see if we + // need to nuke it + // + + if ((dwParam1 == LINECALLSTATE_IDLE) && + (bNukeIdleMonitorCalls || bNukeIdleOwnedCalls)) + { + BOOL bNukeCall = FALSE; + LINECALLSTATUS callStatus; + + + callStatus.dwTotalSize = (DWORD) sizeof(LINECALLSTATUS); + + lResult = lineGetCallStatus ((HCALL) hDevice, &callStatus); + + ShowLineFuncResult ("lineGetCallStatus", lResult); + + if (lResult == 0) + { + if ((callStatus.dwCallPrivilege & LINECALLPRIVILEGE_OWNER)) + { + if (bNukeIdleOwnedCalls) + { + bNukeCall = TRUE; + } + } + else + { + if (bNukeIdleMonitorCalls) + { + bNukeCall = TRUE; + } + } + } + + if (bNukeCall) + { + if ((lResult = lineDeallocateCall ((HCALL) hDevice)) == 0) + { + ShowStr ("Call x%lx deallocated on IDLE", hDevice); + + if (pCall) + { + FreeCall (pCall); + } + + break; + } + else + { + ShowLineFuncResult ("lineDeallocateCall", lResult); + } + } + } + + + // + // Find call in the widget list, save the call state, & + // update it's text in the widget list. + // + + if (pCall) + { + // + // If dwNumPendingDrops is non-zero, then user previously + // pressed "Call-" button and we're waiting for a call to + // go IDLE so we can deallocate it. Check to see if this + // is the call we want to nuke. (Note: we used to nuke the + // call when we got a successful REPLY msg back from the + // drop request; the problem with that is some SPs complete + // the drop request *before* they set the call state to + // IDLE, and our call to lineDeallocateCall would fail + // since TAPI won't let a call owner deallocate a call if + // it's not IDLE.) + // + + if (dwNumPendingDrops && + (dwParam1 == LINECALLSTATE_IDLE) && + pCall->lDropReqID) + { + dwNumPendingDrops--; + + ShowStr( + "Deallocating hCall x%lx " \ + "(REPLY for requestID x%lx might be filtered)", + pCall->hCall, + pCall->lDropReqID + ); + + lResult = lineDeallocateCall (pCall->hCall); + + ShowLineFuncResult ("lineDeallocateCall", lResult); + + if (lResult == 0) + { + FreeCall (pCall); + break; + } + else + { + pCall->lDropReqID = 0; + } + } + + pCall->dwCallState = dwParam1; + UpdateWidgetListCall (pCall); + } + + + // + // If here this is the first we've heard of this this call, + // so find out which line it's on & create a call widget + // for it + // + + else if (dwParam3 != 0) + { + LINECALLINFO callInfo; + + + memset (&callInfo, 0, sizeof(LINECALLINFO)); + callInfo.dwTotalSize = sizeof(LINECALLINFO); + lResult = lineGetCallInfo ((HCALL)hDevice, &callInfo); + + ShowStr( + "%slineGetCallInfo returned x%lx, hLine=x%lx", + szTab, + lResult, + callInfo.hLine + ); + + if (lResult == 0) + { + if ((pLine = GetLine (callInfo.hLine))) + { + if ((pCall = AllocCall (pLine))) + { + pCall->hCall = (HCALL) hDevice; + pCall->dwCallState = dwParam1; + pCall->bMonitor = (dwParam3 == + LINECALLPRIVILEGE_MONITOR ? TRUE : FALSE); + UpdateWidgetListCall (pCall); + } + } + } + } + + break; + } + case LINE_GATHERDIGITS: + { + PMYCALL pCall; + + + if ((pCall = GetCall ((HCALL) hDevice)) && pCall->lpsGatheredDigits) + { + ShowStr ("%sGathered digits:", szTab); + ShowBytes (pCall->dwNumGatheredDigits, pCall->lpsGatheredDigits, 2); + free (pCall->lpsGatheredDigits); + pCall->lpsGatheredDigits = NULL; + } + + break; + } + case LINE_REPLY: + + if (dwNumPendingMakeCalls) + { + // + // Check to see if this is a reply for a lineMakeCall request + // + + PMYWIDGET pWidget = aWidgets; + + + while (pWidget && (pWidget->dwType != WT_PHONEAPP)) + { + if (pWidget->dwType == WT_CALL) + { + PMYCALL pCall = (PMYCALL) pWidget; + + if ((DWORD)pCall->lMakeCallReqID == dwParam1) + { + // + // The reply id matches the make call req id + // + + dwNumPendingMakeCalls--; + + if (dwParam2 || !pCall->hCall) + { + // + // Request error or no call created, so free + // up the struct & update the hCalls listbox + // + + if (dwParam2 == 0) + { + ShowStr( + " NOTE: *lphCall==NULL, "\ + "freeing call data structure" + ); + } + + pWidget = pWidget->pNext; + + FreeCall (pCall); + + continue; + } + else + { + // + // Reset this field so we don't run into + // problems later with another of the same + // request id + // + + pCall->lMakeCallReqID = 0; + + UpdateWidgetListCall (pCall); + } + } + } + + pWidget = pWidget->pNext; + } + } + + if (dwParam2) + { + // + // Dump the error in a readable format + // + + MessageBeep ((UINT) -1); + + if (dwParam2 > LAST_LINEERR) + { + ShowStr ("inval err code (x%lx)", dwParam2); + } + else + { + ShowStr( + " %s%s", + "LINEERR_", // ...to shrink the aszLineErrs array + aszLineErrs[LOWORD(dwParam2)] + ); + } + } + + break; + + case PHONE_REPLY: + + if (dwParam2) + { + // + // Dump the error in a readable format + // + + MessageBeep ((UINT) -1); + + if (dwParam2 > PHONEERR_REINIT) + { + ShowStr ("inval err code (x%lx)", dwParam2); + } + else + { + ShowStr( + " %s%s", + "PHONEERR_", // ...to shrink the aszPhoneErrs array + aszPhoneErrs[LOWORD(dwParam2)] + ); + } + } + + break; + + case LINE_CLOSE: + + FreeLine (GetLine ((HLINE) hDevice)); + break; + + case PHONE_CLOSE: + + FreePhone (GetPhone ((HPHONE) hDevice)); + break; + +#if TAPI_2_0 + + case LINE_APPNEWCALL: + { + PMYLINE pLine; + PMYCALL pCall; + + + if ((pLine = GetLine ((HLINE) hDevice))) + { + if ((pCall = AllocCall (pLine))) + { + pCall->hCall = (HCALL) dwParam2; + pCall->dwCallState = LINECALLSTATE_UNKNOWN; + pCall->bMonitor = (dwParam3 == + LINECALLPRIVILEGE_MONITOR ? TRUE : FALSE); + UpdateWidgetListCall (pCall); + } + } + + break; + } + case LINE_PROXYREQUEST: + { + LPLINEPROXYREQUEST pRequest = (LPLINEPROXYREQUEST) dwParam1; + STRUCT_FIELD fields[] = + { + { szdwSize, FT_DWORD, pRequest->dwSize, NULL }, + { "dwClientMachineNameSize", FT_SIZE, pRequest->dwClientMachineNameSize, NULL }, + { "dwClientMachineNameOffset", FT_OFFSET, pRequest->dwClientMachineNameOffset, NULL }, + { "dwClientUserNameSize", FT_SIZE, pRequest->dwClientUserNameSize, NULL }, + { "dwClientUserNameOffset", FT_OFFSET, pRequest->dwClientUserNameOffset, NULL }, + { "dwClientAppAPIVersion", FT_DWORD, pRequest->dwClientAppAPIVersion, NULL }, + { "dwRequestType", FT_ORD, pRequest->dwRequestType, aProxyRequests } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + pRequest, + "LINEPROXYREQUEST", + 7, + fields + }; + + + ShowStructByField (&fieldHeader, TRUE); + + switch (pRequest->dwRequestType) + { + case LINEPROXYREQUEST_SETAGENTGROUP: + { + STRUCT_FIELD fields[] = + { + { szdwAddressID, FT_DWORD, pRequest->SetAgentGroup.dwAddressID, NULL } + +// BUGBUG LINE_PROXYREQUEST: dump agent grp list + + }; + STRUCT_FIELD_HEADER fieldHeader = + { + pRequest, + "SetAgentGroup", + 1, + fields + }; + + + ShowStructByField (&fieldHeader, TRUE); + + break; + } + case LINEPROXYREQUEST_SETAGENTSTATE: + { + STRUCT_FIELD fields[] = + { + { szdwAddressID, FT_DWORD, pRequest->SetAgentState.dwAddressID, NULL }, + { "dwAgentState", FT_ORD, pRequest->SetAgentState.dwAgentState, aAgentStates }, + { "dwNextAgentState", FT_ORD, pRequest->SetAgentState.dwNextAgentState, aAgentStates } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + pRequest, + "SetAgentState", + 3, + fields + }; + + + ShowStructByField (&fieldHeader, TRUE); + + break; + } + case LINEPROXYREQUEST_SETAGENTACTIVITY: + { + STRUCT_FIELD fields[] = + { + { szdwAddressID, FT_DWORD, pRequest->SetAgentActivity.dwAddressID, NULL }, + { "dwActivityID", FT_DWORD, pRequest->SetAgentActivity.dwActivityID, NULL } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + pRequest, + "SetAgentActivity", + 2, + fields + }; + + + ShowStructByField (&fieldHeader, TRUE); + + break; + } + case LINEPROXYREQUEST_GETAGENTCAPS: + { + STRUCT_FIELD fields[] = + { + { szdwAddressID, FT_DWORD, pRequest->GetAgentCaps.dwAddressID, NULL } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + pRequest, + "GetAgentCaps", + 1, + fields + }; + + +// BUGBUG LINE_PROXYREQUEST: fill in agent caps? + + ShowStructByField (&fieldHeader, TRUE); + + break; + } + case LINEPROXYREQUEST_GETAGENTSTATUS: + { + STRUCT_FIELD fields[] = + { + { szdwAddressID, FT_DWORD, pRequest->GetAgentStatus.dwAddressID, NULL } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + pRequest, + "GetAgentStatus", + 1, + fields + }; + + + ShowStructByField (&fieldHeader, TRUE); + + break; + } + case LINEPROXYREQUEST_AGENTSPECIFIC: + { + STRUCT_FIELD fields[] = + { + { szdwAddressID, FT_DWORD, pRequest->AgentSpecific.dwAddressID, NULL }, + { "dwAgentExtensionIDIndex", FT_DWORD, pRequest->AgentSpecific.dwAgentExtensionIDIndex, NULL }, + { szdwSize, FT_SIZE, pRequest->AgentSpecific.dwSize, NULL }, + { "Params", FT_OFFSET, (DWORD) (pRequest->AgentSpecific.Params - (LPBYTE) pRequest), NULL } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + pRequest, + "AgentSpecific", + 4, + fields + }; + + + ShowStructByField (&fieldHeader, TRUE); + + break; + } + case LINEPROXYREQUEST_GETAGENTACTIVITYLIST: + { + STRUCT_FIELD fields[] = + { + { szdwAddressID, FT_DWORD, pRequest->GetAgentActivityList.dwAddressID, NULL } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + pRequest, + "GetAgentActivityList", + 1, + fields + }; + + +// BUGBUG LINE_PROXYREQUEST: fill in agent activity list? + + ShowStructByField (&fieldHeader, TRUE); + + break; + } + case LINEPROXYREQUEST_GETAGENTGROUPLIST: + { + STRUCT_FIELD fields[] = + { + { szdwAddressID, FT_DWORD, pRequest->GetAgentGroupList.dwAddressID, NULL } + }; + STRUCT_FIELD_HEADER fieldHeader = + { + pRequest, + "GetAgentGroupList", + 1, + fields + }; + + +// BUGBUG LINE_PROXYREQUEST: fill in agent grp list? + + ShowStructByField (&fieldHeader, TRUE); + + break; + } + } // switch (pRequest->dwRequestType) + + break; + } + +#endif + + } +} + + +BOOL +CALLBACK +ParamsDlgProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam + ) +{ + DWORD i; + + typedef struct _DLG_INST_DATA + { + PFUNC_PARAM_HEADER pParamsHeader; + + LONG lLastSel; + + char szComboText[MAX_STRING_PARAM_SIZE]; + + } DLG_INST_DATA, *PDLG_INST_DATA; + + PDLG_INST_DATA pDlgInstData = (PDLG_INST_DATA) + GetWindowLong (hwnd, DWL_USER); + + + switch (msg) + { + case WM_INITDIALOG: + { + // + // Alloc a dlg instance data struct, init it, & save a ptr to it + // + + pDlgInstData = (PDLG_INST_DATA) malloc (sizeof(DLG_INST_DATA)); + + // BUGBUG if (!pDlgInstData) + + pDlgInstData->pParamsHeader = (PFUNC_PARAM_HEADER) lParam; + pDlgInstData->lLastSel = -1; + + SetWindowLong (hwnd, DWL_USER, (LONG) pDlgInstData); + + + // + // Stick all the param names in the listbox, & for each PT_DWORD + // param save it's default value + // + + for (i = 0; i < pDlgInstData->pParamsHeader->dwNumParams; i++) + { + SendDlgItemMessage( + hwnd, + IDC_LIST1, + LB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) pDlgInstData->pParamsHeader->aParams[i].szName + ); + + if (pDlgInstData->pParamsHeader->aParams[i].dwType == PT_DWORD) + { + pDlgInstData->pParamsHeader->aParams[i].u.dwDefValue = + pDlgInstData->pParamsHeader->aParams[i].dwValue; + } + } + + + // + // Set the dlg title as appropriate + // + +// help if (pDlgInstData->pParamsHeader->FuncIndex == DefValues) +// help { +// help EnableWindow (GetDlgItem (hwnd, IDC_TB_HELP), FALSE); +// help } + + SetWindowText( + hwnd, + aFuncNames[pDlgInstData->pParamsHeader->FuncIndex] + ); + + + // + // Limit the max text length for the combobox's edit field + // (NOTE: A combobox ctrl actually has two child windows: a + // edit ctrl & a listbox. We need to get the hwnd of the + // child edit ctrl & send it the LIMITTEXT msg.) + // + + { + HWND hwndChild = + GetWindow (GetDlgItem (hwnd, IDC_COMBO1), GW_CHILD); + + + while (hwndChild) + { + char buf[8]; + + + GetClassName (hwndChild, buf, 7); + + if (_stricmp (buf, "edit") == 0) + { + break; + } + + hwndChild = GetWindow (hwndChild, GW_HWNDNEXT); + } + + SendMessage( + hwndChild, + EM_LIMITTEXT, + (WPARAM) (gbWideStringParams ? + (MAX_STRING_PARAM_SIZE/2 - 1) : MAX_STRING_PARAM_SIZE - 1), + 0 + ); + } + + break; + } + case WM_COMMAND: + { + LONG lLastSel = pDlgInstData->lLastSel; + char far *lpszComboText = pDlgInstData->szComboText; + PFUNC_PARAM_HEADER pParamsHeader = pDlgInstData->pParamsHeader; + + + switch (LOWORD(wParam)) + { + case IDOK: + + if (lLastSel != -1) + { + // + // Save val of currently selected param + // + + char buf[MAX_STRING_PARAM_SIZE]; + + + i = GetDlgItemText (hwnd, IDC_COMBO1, buf, MAX_STRING_PARAM_SIZE-1); + + switch (pParamsHeader->aParams[lLastSel].dwType) + { + case PT_STRING: + { + LONG lComboSel; + + + lComboSel = SendDlgItemMessage( + hwnd, + IDC_COMBO1, + CB_GETCURSEL, + 0, + 0 + ); + + if (lComboSel == 0) // "NULL pointer" + { + pParamsHeader->aParams[lLastSel].dwValue = (DWORD) 0; + } + else if (lComboSel == 2) // "Invalid string pointer" + { + pParamsHeader->aParams[lLastSel].dwValue = (DWORD) + 0xffffffff; + } + else // "Valid string pointer" + { + strncpy( + pParamsHeader->aParams[lLastSel].u.buf, + buf, + MAX_STRING_PARAM_SIZE - 1 + ); + + pParamsHeader->aParams[lLastSel].u.buf[MAX_STRING_PARAM_SIZE-1] = 0; + + pParamsHeader->aParams[lLastSel].dwValue = (DWORD) + pParamsHeader->aParams[lLastSel].u.buf; + } + + break; + } + case PT_POINTER: + case PT_DWORD: + case PT_FLAGS: + case PT_CALLPARAMS: // ??? BUGBUG + case PT_FORWARDLIST: // ??? BUGBUG + case PT_ORDINAL: + { + if (!sscanf( + buf, + "%08lx", + &pParamsHeader->aParams[lLastSel].dwValue + )) + { + // + // Default to 0 + // + + pParamsHeader->aParams[lLastSel].dwValue = 0; + } + + break; + } + } // switch + } + + free (pDlgInstData); + EndDialog (hwnd, TRUE); + break; + + case IDCANCEL: + + free (pDlgInstData); + EndDialog (hwnd, FALSE); + break; + +// help case IDC_TB_HELP: +// help +// help MyWinHelp( +// help hwnd, +// help TRUE, +// help HELP_PARTIALKEY, +// help (DWORD) aFuncNames[pParamsHeader->FuncIndex] +// help ); +// help +// help break; + + case IDC_LIST1: + +#ifdef WIN32 + if (HIWORD(wParam) == LBN_SELCHANGE) +#else + if (HIWORD(lParam) == LBN_SELCHANGE) +#endif + { + char buf[MAX_STRING_PARAM_SIZE] = ""; + LPCSTR lpstr = buf; + LONG lSel = + SendDlgItemMessage (hwnd, IDC_LIST1, LB_GETCURSEL, 0, 0); + + + if (lLastSel != -1) + { + // + // Save the old param value + // + + i = GetDlgItemText( + hwnd, + IDC_COMBO1, + buf, + MAX_STRING_PARAM_SIZE - 1 + ); + + switch (pParamsHeader->aParams[lLastSel].dwType) + { + case PT_STRING: + { + LONG lComboSel; + + + lComboSel = SendDlgItemMessage( + hwnd, + IDC_COMBO1, + CB_GETCURSEL, + 0, + 0 + ); + + if (lComboSel == 0) // "NULL pointer" + { + pParamsHeader->aParams[lLastSel].dwValue = (DWORD)0; + } + else if (lComboSel == 2) // "Invalid string pointer" + { + pParamsHeader->aParams[lLastSel].dwValue = (DWORD) + 0xffffffff; + } + else // "Valid string pointer" or no sel + { + strncpy( + pParamsHeader->aParams[lLastSel].u.buf, + buf, + MAX_STRING_PARAM_SIZE - 1 + ); + + pParamsHeader->aParams[lLastSel].u.buf[MAX_STRING_PARAM_SIZE - 1] = 0; + + pParamsHeader->aParams[lLastSel].dwValue = (DWORD) + pParamsHeader->aParams[lLastSel].u.buf; + } + + break; + } + case PT_POINTER: + case PT_DWORD: + case PT_FLAGS: + case PT_CALLPARAMS: // ??? BUGBUG + case PT_FORWARDLIST: // ??? BUGBUG + case PT_ORDINAL: + { + if (!sscanf( + buf, + "%08lx", + &pParamsHeader->aParams[lLastSel].dwValue + )) + { + // + // Default to 0 + // + + pParamsHeader->aParams[lLastSel].dwValue = 0; + } + + break; + } + } // switch + } + + + SendDlgItemMessage (hwnd, IDC_LIST2, LB_RESETCONTENT, 0, 0); + SendDlgItemMessage (hwnd, IDC_COMBO1, CB_RESETCONTENT, 0, 0); + + switch (pParamsHeader->aParams[lSel].dwType) + { + case PT_STRING: + { + char * aszOptions[] = + { + "NULL pointer", + "Valid string pointer", + "Invalid string pointer" + }; + + + for (i = 0; i < 3; i++) + { + SendDlgItemMessage( + hwnd, + IDC_COMBO1, + CB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) aszOptions[i] + ); + } + + if (pParamsHeader->aParams[lSel].dwValue == 0) + { + i = 0; + buf[0] = 0; + } + else if (pParamsHeader->aParams[lSel].dwValue != 0xffffffff) + { + i = 1; + lpstr = (LPCSTR) pParamsHeader->aParams[lSel].dwValue; + } + else + { + i = 2; + buf[0] = 0; + } + + SendDlgItemMessage( + hwnd, + IDC_COMBO1, + CB_SETCURSEL, + (WPARAM) i, + 0 + ); + + break; + } + case PT_POINTER: + case PT_CALLPARAMS: // ??? BUGBUG + case PT_FORWARDLIST: // ??? BUGBUG + { + SendDlgItemMessage( + hwnd, + IDC_COMBO1, + CB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) "00000000" + ); + + sprintf( + buf, + "%08lx (valid pointer)", + pParamsHeader->aParams[lSel].u.dwDefValue + ); + + SendDlgItemMessage( + hwnd, + IDC_COMBO1, + CB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) buf + ); + + SendDlgItemMessage( + hwnd, + IDC_COMBO1, + CB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) "ffffffff" + ); + + sprintf( + buf, + "%08lx", + pParamsHeader->aParams[lSel].dwValue + ); + + break; + } + case PT_DWORD: + { + SendDlgItemMessage( + hwnd, + IDC_COMBO1, + CB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) "0000000" + ); + + if (pParamsHeader->aParams[lSel].u.dwDefValue) + { + // + // Add the default val string to the combo + // + + sprintf( + buf, + "%08lx", + pParamsHeader->aParams[lSel].u.dwDefValue + ); + + SendDlgItemMessage( + hwnd, + IDC_COMBO1, + CB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) buf + ); + } + + SendDlgItemMessage( + hwnd, + IDC_COMBO1, + CB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) "ffffffff" + ); + + sprintf( + buf, + "%08lx", + pParamsHeader->aParams[lSel].dwValue + ); + + break; + } + case PT_FLAGS: + { + // + // Stick the bit flag strings in the list box + // + + PLOOKUP pLookup = (PLOOKUP) + pParamsHeader->aParams[lSel].u.pLookup; + + for (i = 0; pLookup[i].dwVal != 0xffffffff; i++) + { + SendDlgItemMessage( + hwnd, + IDC_LIST2, + LB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) pLookup[i].lpszVal + ); + + if (pParamsHeader->aParams[lSel].dwValue & + pLookup[i].dwVal) + { + SendDlgItemMessage( + hwnd, + IDC_LIST2, + LB_SETSEL, + (WPARAM) TRUE, + (LPARAM) MAKELPARAM((WORD)i,0) + ); + } + } + + SendDlgItemMessage( + hwnd, + IDC_COMBO1, + CB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) "select none" + ); + + SendDlgItemMessage( + hwnd, + IDC_COMBO1, + CB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) "select all" + ); + + sprintf( + buf, + "%08lx", + pParamsHeader->aParams[lSel].dwValue + ); + + break; + } + case PT_ORDINAL: + { + // + // Stick the bit flag strings in the list box + // + + HWND hwndList2 = GetDlgItem (hwnd, IDC_LIST2); + PLOOKUP pLookup = (PLOOKUP) + pParamsHeader->aParams[lSel].u.pLookup; + + for (i = 0; pLookup[i].dwVal != 0xffffffff; i++) + { + SendMessage( + hwndList2, + LB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) pLookup[i].lpszVal + ); + + if (pParamsHeader->aParams[lSel].dwValue == + pLookup[i].dwVal) + { + SendMessage( + hwndList2, + LB_SETSEL, + (WPARAM) TRUE, + (LPARAM) MAKELPARAM((WORD)i,0) + ); + } + } + + SendDlgItemMessage( + hwnd, + IDC_COMBO1, + CB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) (char far *) "select none" + ); + + wsprintf( + buf, + "%08lx", + pParamsHeader->aParams[lSel].dwValue + ); + + break; + } + } //switch + + SetDlgItemText (hwnd, IDC_COMBO1, lpstr); + + pDlgInstData->lLastSel = lSel; + } + break; + + case IDC_LIST2: + +#ifdef WIN32 + if (HIWORD(wParam) == LBN_SELCHANGE) +#else + if (HIWORD(lParam) == LBN_SELCHANGE) +#endif + { + PLOOKUP pLookup = (PLOOKUP) + pParamsHeader->aParams[lLastSel].u.pLookup; + char buf[16]; + DWORD dwValue = 0; + int far *ai; + LONG i, lSelCount = + SendDlgItemMessage (hwnd, IDC_LIST2, LB_GETSELCOUNT, 0, 0); + + + if (lSelCount) + { + ai = (int far *) malloc ((size_t)lSelCount * sizeof(int)); + + SendDlgItemMessage( + hwnd, + IDC_LIST2, + LB_GETSELITEMS, + (WPARAM) lSelCount, + (LPARAM) ai + ); + + if (pParamsHeader->aParams[lLastSel].dwType == PT_FLAGS) + { + for (i = 0; i < lSelCount; i++) + { + dwValue |= pLookup[ai[i]].dwVal; + } + } + else // if (.dwType == PT_ORDINAL) + { + if (lSelCount == 1) + { + dwValue = pLookup[ai[0]].dwVal; + } + else if (lSelCount == 2) + { + // + // Figure out which item we need to de-select, + // since we're doing ords & only want 1 item + // selected at a time + // + + GetDlgItemText (hwnd, IDC_COMBO1, buf, 16); + + if (sscanf (buf, "%lx", &dwValue)) + { + if (pLookup[ai[0]].dwVal == dwValue) + { + SendDlgItemMessage( + hwnd, + IDC_LIST2, + LB_SETSEL, + 0, + (LPARAM) ai[0] + ); + + dwValue = pLookup[ai[1]].dwVal; + } + else + { + SendDlgItemMessage( + hwnd, + IDC_LIST2, + LB_SETSEL, + 0, + (LPARAM) ai[1] + ); + + dwValue = pLookup[ai[0]].dwVal; + } + } + else + { + // BUGBUG de-select items??? + + dwValue = 0; + } + } + } + + free (ai); + } + + sprintf (buf, "%08lx", dwValue); + SetDlgItemText (hwnd, IDC_COMBO1, buf); + } + break; + + case IDC_COMBO1: + +#ifdef WIN32 + switch (HIWORD(wParam)) +#else + switch (HIWORD(lParam)) +#endif + { + case CBN_SELCHANGE: + { + LONG lSel = + SendDlgItemMessage (hwnd, IDC_COMBO1, CB_GETCURSEL, 0, 0); + + + switch (pParamsHeader->aParams[lLastSel].dwType) + { + case PT_POINTER: + { + if (lSel == 1) + { + // + // Strip off the "(valid pointer)" in the edit ctrl + // + + sprintf( + lpszComboText, + "%08lx", + pParamsHeader->aParams[lLastSel].u.ptr + ); + + PostMessage (hwnd, WM_USER+55, 0, 0); + } + + break; + } + case PT_FLAGS: + { + BOOL bSelect = (lSel ? TRUE : FALSE); + + SendDlgItemMessage( + hwnd, + IDC_LIST2, + LB_SETSEL, + (WPARAM) bSelect, + (LPARAM) -1 + ); + + if (bSelect) + { + PLOOKUP pLookup = (PLOOKUP) + pParamsHeader->aParams[lLastSel].u.pLookup; + DWORD dwValue = 0; + int far *ai; + LONG i, lSelCount = + SendDlgItemMessage (hwnd, IDC_LIST2, LB_GETSELCOUNT, 0, 0); + + + if (lSelCount) + { + ai = (int far *) malloc ((size_t)lSelCount * sizeof(int)); + + SendDlgItemMessage( + hwnd, + IDC_LIST2, + LB_GETSELITEMS, + (WPARAM) lSelCount, + (LPARAM) ai + ); + + for (i = 0; i < lSelCount; i++) + { + dwValue |= pLookup[ai[i]].dwVal; + } + + free (ai); + } + + sprintf (lpszComboText, "%08lx", dwValue); + + } + else + { + strcpy (lpszComboText, "00000000"); + } + + PostMessage (hwnd, WM_USER+55, 0, 0); + + break; + } + case PT_STRING: + + if (lSel == 1) + { + strncpy( + lpszComboText, + pParamsHeader->aParams[lLastSel].u.buf, + MAX_STRING_PARAM_SIZE + ); + + lpszComboText[MAX_STRING_PARAM_SIZE-1] = 0; + } + else + { + lpszComboText[0] = 0; + } + + PostMessage (hwnd, WM_USER+55, 0, 0); + + break; + + case PT_DWORD: + + break; + + case PT_CALLPARAMS: + { + if (lSel == 1) + { +#if TAPI_2_0 + LPLINECALLPARAMS lpCP = (gbWideStringParams ? + lpCallParamsW : lpCallParams); +#else + LPLINECALLPARAMS lpCP = lpCallParams; +#endif + char *p = (char *) lpCP; + +#if TAPI_2_0 + char asz[14][MAX_STRING_PARAM_SIZE]; + LPDWORD pdwProxyRequests = (LPDWORD) (((LPBYTE) lpCP) + + lpCP->dwDevSpecificOffset); +#else + char asz[7][MAX_STRING_PARAM_SIZE]; +#endif + FUNC_PARAM params[] = + { + { "dwBearerMode", PT_FLAGS, lpCP->dwBearerMode, aBearerModes }, + { "dwMinRate", PT_DWORD, lpCP->dwMinRate, NULL }, + { "dwMaxRate", PT_DWORD, lpCP->dwMaxRate, NULL }, + { "dwMediaMode", PT_FLAGS, lpCP->dwMediaMode, aMediaModes }, + { "dwCallParamFlags", PT_FLAGS, lpCP->dwCallParamFlags, aCallParamFlags }, + { "dwAddressMode", PT_ORDINAL,lpCP->dwAddressMode, aAddressModes }, + { "dwAddressID", PT_DWORD, lpCP->dwAddressID, NULL }, + { "DIALPARAMS.dwDialPause", PT_DWORD, lpCP->DialParams.dwDialPause, NULL }, + { "DIALPARAMS.dwDialSpeed", PT_DWORD, lpCP->DialParams.dwDialSpeed, NULL }, + { "DIALPARAMS.dwDigitDuration", PT_DWORD, lpCP->DialParams.dwDigitDuration, NULL }, + { "DIALPARAMS.dwWaitForDialtone", PT_DWORD, lpCP->DialParams.dwWaitForDialtone, NULL }, + { "szOrigAddress", PT_STRING, (DWORD) asz[0], asz[0] }, + { "szDisplayableAddress", PT_STRING, (DWORD) asz[1], asz[1] }, + { "szCalledParty", PT_STRING, (DWORD) asz[2], asz[2] }, + { "szComment", PT_STRING, (DWORD) asz[3], asz[3] }, + { "szUserUserInfo", PT_STRING, (DWORD) asz[4], asz[4] }, + { "szHighLevelComp", PT_STRING, (DWORD) asz[5], asz[5] }, + { "szLowLevelComp", PT_STRING, (DWORD) asz[6], asz[6] } +#if TAPI_2_0 + , + { "dwPredictiveAutoTransferStates", PT_FLAGS, lpCP->dwPredictiveAutoTransferStates, aCallStates }, + { "szTargetAddress", PT_STRING, (DWORD) asz[7], asz[7] }, + { "szSendingFlowspec", PT_STRING, (DWORD) asz[8], asz[8] }, + { "szReceivingFlowspec", PT_STRING, (DWORD) asz[9], asz[9] }, + { "szDeviceClass", PT_STRING, (DWORD) asz[10], asz[10] }, + { "szDeviceConfig", PT_STRING, (DWORD) asz[11], asz[11] }, + { "szCallData", PT_STRING, (DWORD) asz[12], asz[12] }, + { "dwNoAnswerTimeout", PT_DWORD, lpCP->dwNoAnswerTimeout, NULL }, + { "szCallingPartyID", PT_STRING, (DWORD) asz[13], asz[13] }, + + { "NumProxyRequests", PT_DWORD, lpCP->dwDevSpecificSize / 4, NULL }, + { " ProxyRequest1", PT_ORDINAL,*pdwProxyRequests, aProxyRequests }, + { " ProxyRequest2", PT_ORDINAL,*(pdwProxyRequests + 1), aProxyRequests }, + { " ProxyRequest3", PT_ORDINAL,*(pdwProxyRequests + 2), aProxyRequests }, + { " ProxyRequest4", PT_ORDINAL,*(pdwProxyRequests + 3), aProxyRequests }, + { " ProxyRequest5", PT_ORDINAL,*(pdwProxyRequests + 4), aProxyRequests }, + { " ProxyRequest6", PT_ORDINAL,*(pdwProxyRequests + 5), aProxyRequests }, + { " ProxyRequest7", PT_ORDINAL,*(pdwProxyRequests + 6), aProxyRequests }, + { " ProxyRequest8", PT_ORDINAL,*(pdwProxyRequests + 7), aProxyRequests } +#endif + }; + FUNC_PARAM_HEADER paramsHeader = + { 0, lCallParams, params, NULL }; + int i; + + LPDWORD apXxxSize[] = + { + &lpCP->dwOrigAddressSize, + &lpCP->dwDisplayableAddressSize, + &lpCP->dwCalledPartySize, + &lpCP->dwCommentSize, + &lpCP->dwUserUserInfoSize, + &lpCP->dwHighLevelCompSize, + &lpCP->dwLowLevelCompSize, +#if TAPI_2_0 + &lpCP->dwTargetAddressSize, + &lpCP->dwSendingFlowspecSize, + &lpCP->dwReceivingFlowspecSize, + &lpCP->dwDeviceClassSize, + &lpCP->dwDeviceConfigSize, + &lpCP->dwCallDataSize, + &lpCP->dwCallingPartyIDSize, +#endif + NULL + }; + static DWORD dwAPIVersion, adwStrParamIndices[] = + { + 11, 12, 13, 14, 15, 16, 17, +#if TAPI_2_0 + 19, 20, 21, 22, 23, 24, 26, +#endif + 0 + }; + + + + // + // Init the tmp string params + // + + for (i = 0; apXxxSize[i]; i++) + { + if (*apXxxSize[i]) + { +#if TAPI_2_0 + if (gbWideStringParams) + { + WideCharToMultiByte( + CP_ACP, + 0, + (LPCWSTR) (p + *(apXxxSize[i] + 1)), + -1, + asz[i], + MAX_STRING_PARAM_SIZE, + NULL, + NULL + ); + } + else + { + strcpy (asz[i], p + *(apXxxSize[i] + 1)); + } +#else + strcpy (asz[i], p + *(apXxxSize[i] + 1)); +#endif + } + else + { + asz[i][0] = 0; + } + } + + if (pDlgInstData->pParamsHeader->FuncIndex == lOpen) + { + dwAPIVersion = pDlgInstData->pParamsHeader-> + aParams[3].dwValue; + } + else + { +#if TAPI_2_0 + dwAPIVersion = 0x00020000; +#else + dwAPIVersion = 0x00010004; +#endif + } + + if (dwAPIVersion < 0x00020000) + { + paramsHeader.dwNumParams = 18; + apXxxSize[8] = NULL; + } +#if TAPI_2_0 + else if (pDlgInstData->pParamsHeader->FuncIndex == + lOpen) + { + paramsHeader.dwNumParams = 36; + } + else + { + paramsHeader.dwNumParams = 27; + } +#endif + if (DialogBoxParam( + ghInst, + (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG2), + hwnd, + (DLGPROC) ParamsDlgProc, + (LPARAM) ¶msHeader + )) + { + LPDWORD lpdwXxx = &lpCP->dwBearerMode; + + + // + // Save the DWORD params + // + + for (i = 0; i < 11; i++) + { + *(lpdwXxx + i) = params[i].dwValue; + } +#if TAPI_2_0 + if (paramsHeader.dwNumParams > 18) + { + lpCP->dwPredictiveAutoTransferStates = + params[18].dwValue; + lpCP->dwNoAnswerTimeout = params[25].dwValue; + + if (paramsHeader.dwNumParams > 27) + { + lpCP->dwDevSpecificSize = + 4 * params[27].dwValue; + + for (i = 0; i < 8; i++) + { + *(pdwProxyRequests + i) = + params[28+i].dwValue; + } + } + } +#endif + + // + // Save the string params + // + + for (i = 0; apXxxSize[i]; i++) + { + DWORD length, index = adwStrParamIndices[i]; + + + if (params[index].dwValue && + (params[index].dwValue != 0xffffffff)) + { +#if TAPI_2_0 + if (gbWideStringParams) + { + length = MultiByteToWideChar( + CP_ACP, + MB_PRECOMPOSED, + (LPCSTR) asz[i], + -1, + (LPWSTR) (p + *(apXxxSize[i] + 1)), + // offset + MAX_STRING_PARAM_SIZE/2 + ); + + length *= sizeof (WCHAR); + } + else + { + strcpy( + p + *(apXxxSize[i] + 1), // offset + asz[i] + ); + + length = (DWORD) strlen (asz[i]) + 1; + } +#else + strcpy( + p + *(apXxxSize[i] + 1), // offset + asz[i] + ); + + length = (DWORD) strlen (asz[i]) + 1; +#endif + } + else + { + length = 0; + } + + *apXxxSize[i] = length; + } + } + + // + // Strip off the "(valid pointer)" in the edit ctrl + // + + sprintf (lpszComboText, "%08lx", lpCP); + PostMessage (hwnd, WM_USER+55, 0, 0); + + pParamsHeader->aParams[lLastSel].dwValue = + (DWORD) lpCP; + } + + break; + } + case PT_FORWARDLIST: + { + if (lSel == 1) + { + char asz[MAX_LINEFORWARD_ENTRIES][2][MAX_STRING_PARAM_SIZE]; + FUNC_PARAM params[] = + { + { "dwNumEntries", PT_DWORD, 0, 0 }, + { "[0].dwFowardMode", PT_FLAGS, 0, aForwardModes }, + { "[0].lpszCallerAddress", PT_STRING, 0, asz[0][0] }, + { "[0].dwDestCountryCode", PT_DWORD, 0, 0 }, + { "[0].lpszDestAddress", PT_STRING, 0, asz[0][1] }, + { "[1].dwFowardMode", PT_FLAGS, 0, aForwardModes }, + { "[1].lpszCallerAddress", PT_STRING, 0, asz[1][0] }, + { "[1].dwDestCountryCode", PT_DWORD, 0, 0 }, + { "[1].lpszDestAddress", PT_STRING, 0, asz[1][1] }, + { "[2].dwFowardMode", PT_FLAGS, 0, aForwardModes }, + { "[2].lpszCallerAddress", PT_STRING, 0, asz[2][0] }, + { "[2].dwDestCountryCode", PT_DWORD, 0, 0 }, + { "[2].lpszDestAddress", PT_STRING, 0, asz[2][1] }, + { "[3].dwFowardMode", PT_FLAGS, 0, aForwardModes }, + { "[3].lpszCallerAddress", PT_STRING, 0, asz[3][0] }, + { "[3].dwDestCountryCode", PT_DWORD, 0, 0 }, + { "[3].lpszDestAddress", PT_STRING, 0, asz[3][1] }, + { "[4].dwFowardMode", PT_FLAGS, 0, aForwardModes }, + { "[4].lpszCallerAddress", PT_STRING, 0, asz[4][0] }, + { "[4].dwDestCountryCode", PT_DWORD, 0, 0 }, + { "[4].lpszDestAddress", PT_STRING, 0, asz[4][1] }, + + }; + FUNC_PARAM_HEADER paramsHeader = + { 21, lForwardList, params, NULL }; + + + memset( + asz, + 0, + MAX_LINEFORWARD_ENTRIES*2*MAX_STRING_PARAM_SIZE + ); + + if (DialogBoxParam( + ghInst, + (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG2), + hwnd, + (DLGPROC) ParamsDlgProc, + (LPARAM) ¶msHeader + )) + { + + LPLINEFORWARDLIST lpForwardList = + (LPLINEFORWARDLIST) + pParamsHeader->aParams[lLastSel].u.ptr; + LPLINEFORWARD lpEntry = lpForwardList->ForwardList; + DWORD dwNumEntriesToInit = + (params[0].dwValue > MAX_LINEFORWARD_ENTRIES ? + MAX_LINEFORWARD_ENTRIES : params[0].dwValue); + DWORD i, dwFixedSize = sizeof(LINEFORWARDLIST) + + (MAX_LINEFORWARD_ENTRIES-1)*sizeof(LINEFORWARD); + + + lpForwardList->dwNumEntries = params[0].dwValue; + + for (i = 0; i < dwNumEntriesToInit; i++) + { + lpEntry->dwForwardMode = + params[1 + 4*i].dwValue; + + if (params[2 + 4*i].dwValue && + params[2 + 4*i].dwValue != 0xffffffff) + { + lpEntry->dwCallerAddressSize = + strlen (asz[i][0]) + 1; + + lpEntry->dwCallerAddressOffset = + dwFixedSize + + 2*i*MAX_STRING_PARAM_SIZE; +#if TAPI_2_0 + if (gbWideStringParams) + { + lpEntry->dwCallerAddressSize *= + sizeof (WCHAR); + + MultiByteToWideChar( + CP_ACP, + MB_PRECOMPOSED, + (LPCSTR) asz[i][0], + -1, + (LPWSTR) ((char *) lpForwardList + + lpEntry->dwCallerAddressOffset), + MAX_STRING_PARAM_SIZE / 2 + ); + } + else + { + strcpy( + (char *) lpForwardList + + lpEntry->dwCallerAddressOffset, + asz[i][0] + ); + } +#else + strcpy( + (char *) lpForwardList + + lpEntry->dwCallerAddressOffset, + asz[i][0] + ); +#endif + } + + lpEntry->dwDestCountryCode = + params[3 + 4*i].dwValue; + + if (params[4 + 4*i].dwValue && + params[4 + 4*i].dwValue != 0xffffffff) + { + lpEntry->dwDestAddressSize = + strlen (asz[i][1]) + 1; + + lpEntry->dwDestAddressOffset = + dwFixedSize + + (2*i + 1)*MAX_STRING_PARAM_SIZE; + +#if TAPI_2_0 + if (gbWideStringParams) + { + lpEntry->dwDestAddressSize *= + sizeof (WCHAR); + + MultiByteToWideChar( + CP_ACP, + MB_PRECOMPOSED, + (LPCSTR) asz[i][1], + -1, + (LPWSTR) ((char *) lpForwardList + + lpEntry->dwDestAddressOffset), + MAX_STRING_PARAM_SIZE / 2 + ); + } + else + { + strcpy( + (char *) lpForwardList + + lpEntry->dwDestAddressOffset, + asz[i][1] + ); + } +#else + strcpy( + (char *) lpForwardList + + lpEntry->dwDestAddressOffset, + asz[i][1] + ); +#endif + } + + lpEntry++; + } + } + + // + // Strip off the "(valid pointer)" in the edit ctrl + // + + sprintf( + lpszComboText, + "%08lx", + pParamsHeader->aParams[lLastSel].u.ptr + ); + + PostMessage (hwnd, WM_USER+55, 0, 0); + } + + break; + } + case PT_ORDINAL: + + // + // The only option here is "select none" + // + + strcpy (lpszComboText, "00000000"); + PostMessage (hwnd, WM_USER+55, 0, 0); + break; + + } // switch + + break; + } + case CBN_EDITCHANGE: + { + // + // If user entered text in the edit field then copy the + // text to our buffer + // + + if (pParamsHeader->aParams[lLastSel].dwType == PT_STRING) + { + char buf[MAX_STRING_PARAM_SIZE]; + + + GetDlgItemText( + hwnd, + IDC_COMBO1, + buf, + MAX_STRING_PARAM_SIZE + ); + + strncpy( + pParamsHeader->aParams[lLastSel].u.buf, + buf, + MAX_STRING_PARAM_SIZE + ); + + pParamsHeader->aParams[lLastSel].u.buf + [MAX_STRING_PARAM_SIZE-1] = 0; + } + break; + } + } // switch + + } // switch + + break; + } + case WM_USER+55: + + SetDlgItemText (hwnd, IDC_COMBO1, pDlgInstData->szComboText); + break; + +#ifdef WIN32 + case WM_CTLCOLORSTATIC: + + SetBkColor ((HDC) wParam, RGB (192,192,192)); + return (BOOL) GetStockObject (LTGRAY_BRUSH); +#else + case WM_CTLCOLOR: + { + if (HIWORD(lParam) == CTLCOLOR_STATIC) + { + SetBkColor ((HDC) wParam, RGB (192,192,192)); + return (BOOL) GetStockObject (LTGRAY_BRUSH); + } + break; + } +#endif + case WM_PAINT: + { + PAINTSTRUCT ps; + + BeginPaint (hwnd, &ps); + FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH)); + EndPaint (hwnd, &ps); + + break; + } + } // switch + + return FALSE; +} + + +BOOL +CALLBACK +IconDlgProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam + ) +{ + static HICON hIcon; + + switch (msg) + { + case WM_INITDIALOG: + + hIcon = (HICON) lParam; + + break; + + case WM_COMMAND: + + switch (LOWORD(wParam)) + { + case IDOK: + + EndDialog (hwnd, 0); + break; + } + break; + + case WM_PAINT: + { + PAINTSTRUCT ps; + + BeginPaint (hwnd, &ps); + FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH)); +#ifdef WIN32 + MoveToEx (ps.hdc, 6, 6, (LPPOINT) NULL); +#else + MoveTo (ps.hdc, 6, 6); +#endif + LineTo (ps.hdc, 42, 6); + LineTo (ps.hdc, 42, 42); + LineTo (ps.hdc, 6, 42); + LineTo (ps.hdc, 6, 6); + DrawIcon (ps.hdc, 8, 8, hIcon); + EndPaint (hwnd, &ps); + + break; + } + } + + return FALSE; +} + + +BOOL +CALLBACK +UserButtonsDlgProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam + ) +{ + static int iButtonIndex; + + switch (msg) + { + case WM_INITDIALOG: + { + int i; + char buf[32]; + + if (lParam) + { + // + // The dlg was invoked because someone pressed a user button + // that was uninitialized, so only allow chgs on this button + // + + iButtonIndex = *((int *) lParam); + + _itoa (iButtonIndex + 1, buf, 10); + + SendDlgItemMessage( + hwnd, + IDC_LIST1, + LB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) buf + ); + } + else + { + // + // The dlg was invoked because the user chose a menuitem, + // so allow chgs on all buttons + // + + iButtonIndex = MAX_USER_BUTTONS; + + for (i = 1; i <= MAX_USER_BUTTONS; i++) + { + _itoa (i, buf, 10); + + SendDlgItemMessage( + hwnd, + IDC_LIST1, + LB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) buf + ); + } + + } + + SendDlgItemMessage( + hwnd, + IDC_LIST1, + LB_SETCURSEL, + (WPARAM) 0, + 0 + ); + + for (i = 0; aFuncNames[i]; i++) + { + SendDlgItemMessage( + hwnd, + IDC_LIST2, + LB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) aFuncNames[i] + ); + } + + SendDlgItemMessage( + hwnd, + IDC_LIST2, + LB_INSERTSTRING, + (WPARAM) -1, + (LPARAM) "<none>" + ); + + if (!lParam) + { +#ifdef WIN32 + wParam = (WPARAM) MAKELONG (0, LBN_SELCHANGE); +#else + lParam = (LPARAM) MAKELONG (0, LBN_SELCHANGE); +#endif + goto IDC_LIST1_selchange; + } + + break; + } + case WM_COMMAND: + + switch (LOWORD(wParam)) + { + case IDOK: + { + LONG lFuncSel; + + + lFuncSel = SendDlgItemMessage(hwnd, IDC_LIST2, LB_GETCURSEL, 0, 0); + + if (lFuncSel == LB_ERR) + { + MessageBox (hwnd, "Select a function", "", MB_OK); + break; + } + + if (iButtonIndex == MAX_USER_BUTTONS) + { + iButtonIndex = (int) SendDlgItemMessage( + hwnd, + IDC_LIST1, + LB_GETCURSEL, + 0, + 0 + ); + } + + aUserButtonFuncs[iButtonIndex] = (DWORD) lFuncSel; + + if (lFuncSel == MiscBegin) + { + // + // User selected "<none>" option so nullify string + // + + aUserButtonsText[iButtonIndex][0] = 0; + } + else + { + GetDlgItemText( + hwnd, + IDC_EDIT1, + (LPSTR) &aUserButtonsText[iButtonIndex], + MAX_USER_BUTTON_TEXT_SIZE - 1 + ); + + aUserButtonsText[iButtonIndex][MAX_USER_BUTTON_TEXT_SIZE - 1] = + 0; + } + + SetDlgItemText( + ghwndMain, + IDC_BUTTON13 + iButtonIndex, + (LPSTR) &aUserButtonsText[iButtonIndex] + ); + + // Fall thru to IDCANCEL code + } + case IDCANCEL: + + EndDialog (hwnd, FALSE); + break; + + case IDC_LIST1: + +IDC_LIST1_selchange: + +#ifdef WIN32 + if (HIWORD(wParam) == LBN_SELCHANGE) +#else + if (HIWORD(lParam) == LBN_SELCHANGE) +#endif + { + LONG lButtonSel = + SendDlgItemMessage(hwnd, IDC_LIST1, LB_GETCURSEL, 0, 0); + + + SendDlgItemMessage( + hwnd, + IDC_LIST2, + LB_SETCURSEL, + (WPARAM) aUserButtonFuncs[lButtonSel], + 0 + ); + + SetDlgItemText( + hwnd, + IDC_EDIT1, + aUserButtonsText[lButtonSel] + ); + } + break; + + } // switch + + break; + +#ifdef WIN32 + case WM_CTLCOLORSTATIC: + + SetBkColor ((HDC) wParam, RGB (192,192,192)); + return (BOOL) GetStockObject (LTGRAY_BRUSH); +#else + case WM_CTLCOLOR: + { + if (HIWORD(lParam) == CTLCOLOR_STATIC) + { + SetBkColor ((HDC) wParam, RGB (192,192,192)); + return (BOOL) GetStockObject (LTGRAY_BRUSH); + } + break; + } +#endif + case WM_PAINT: + { + PAINTSTRUCT ps; + + BeginPaint (hwnd, &ps); + FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH)); + EndPaint (hwnd, &ps); + + break; + } + } // switch + + return FALSE; +} diff --git a/private/tapi/dev/apps/tb/vars.c b/private/tapi/dev/apps/tb/vars.c new file mode 100644 index 000000000..4df8db092 --- /dev/null +++ b/private/tapi/dev/apps/tb/vars.c @@ -0,0 +1,1591 @@ +/*++ BUILD Version: 0000 // Increment this if a change has global effects + +Copyright (c) 1994-96 Microsoft Corporation + +Module Name: + + vars.c + +Abstract: + + Globals for TAPI Browser util. + +Author: + + Dan Knudson (DanKn) 23-Oct-1994 + +Revision History: + +--*/ + + +#include <stdio.h> +#include "tb.h" + +#ifdef WIN32 +#define my_far +#else +#define my_far _far +#endif + + +PMYWIDGET aWidgets = (PMYWIDGET) NULL; + +FILE *hLogFile = (FILE *) NULL; +HANDLE ghInst; +HWND ghwndMain, ghwndEdit, ghwndList1, ghwndList2; +BOOL bShowParams = FALSE; +BOOL gbDeallocateCall = FALSE; +BOOL gbDisableHandleChecking; +LPVOID pBigBuf; +DWORD dwBigBufSize; +DWORD dwNumPendingMakeCalls = 0; +DWORD dwNumPendingDrops = 0; +DWORD gdwNumLineDevs = 0; +DWORD gdwNumPhoneDevs = 0; +BOOL bDumpParams = FALSE; +BOOL bTimeStamp; +DWORD bNukeIdleMonitorCalls; +DWORD bNukeIdleOwnedCalls; +DWORD dwDumpStructsFlags; + +LPLINECALLPARAMS lpCallParams; + +#if TAPI_2_0 +BOOL gbWideStringParams = FALSE; +LPLINECALLPARAMS lpCallParamsW; +#endif + +DWORD aUserButtonFuncs[MAX_USER_BUTTONS]; +char aUserButtonsText[MAX_USER_BUTTONS][MAX_USER_BUTTON_TEXT_SIZE]; + +PMYLINEAPP pLineAppSel; +PMYLINE pLineSel; +PMYCALL pCallSel, pCallSel2; +PMYPHONEAPP pPhoneAppSel; +PMYPHONE pPhoneSel; + +char my_far szDefAppName[MAX_STRING_PARAM_SIZE]; +char my_far szDefUserUserInfo[MAX_STRING_PARAM_SIZE]; +char my_far szDefDestAddress[MAX_STRING_PARAM_SIZE]; +char my_far szDefLineDeviceClass[MAX_STRING_PARAM_SIZE]; +char my_far szDefPhoneDeviceClass[MAX_STRING_PARAM_SIZE]; + +char far *lpszDefAppName; +char far *lpszDefUserUserInfo; +char far *lpszDefDestAddress; +char far *lpszDefLineDeviceClass; +char far *lpszDefPhoneDeviceClass; + +char my_far szTab[] = " "; +char my_far szCurrVer[] = "1.1"; + + +// help char my_far szTapiHlp[256] = ""; +// help char my_far szTspiHlp[256] = ""; + +DWORD dwDefAddressID; +DWORD dwDefLineAPIVersion; +DWORD dwDefBearerMode; +DWORD dwDefCountryCode; +DWORD dwDefLineDeviceID; +DWORD dwDefLineExtVersion; +DWORD dwDefMediaMode; +DWORD dwDefLinePrivilege; +DWORD dwDefPhoneAPIVersion; +DWORD dwDefPhoneDeviceID; +DWORD dwDefPhoneExtVersion; +DWORD dwDefPhonePrivilege; + +#if TAPI_2_0 +HANDLE ghCompletionPort; +#endif + +char aAscii[] = +{ + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126, 46, + + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46 +}; + + + +LOOKUP my_far aAddressCapFlags[] = +{ + { LINEADDRCAPFLAGS_FWDNUMRINGS ,"FWDNUMRINGS" }, + { LINEADDRCAPFLAGS_PICKUPGROUPID ,"PICKUPGROUPID" }, + { LINEADDRCAPFLAGS_SECURE ,"SECURE" }, + { LINEADDRCAPFLAGS_BLOCKIDDEFAULT ,"BLOCKIDDEFAULT" }, + { LINEADDRCAPFLAGS_BLOCKIDOVERRIDE ,"BLOCKIDOVERRIDE" }, + { LINEADDRCAPFLAGS_DIALED ,"DIALED" }, + { LINEADDRCAPFLAGS_ORIGOFFHOOK ,"ORIGOFFHOOK" }, + { LINEADDRCAPFLAGS_DESTOFFHOOK ,"DESTOFFHOOK" }, + { LINEADDRCAPFLAGS_FWDCONSULT ,"FWDCONSULT" }, + { LINEADDRCAPFLAGS_SETUPCONFNULL ,"SETUPCONFNULL" }, + { LINEADDRCAPFLAGS_AUTORECONNECT ,"AUTORECONNECT" }, + { LINEADDRCAPFLAGS_COMPLETIONID ,"COMPLETIONID" }, + { LINEADDRCAPFLAGS_TRANSFERHELD ,"TRANSFERHELD" }, + { LINEADDRCAPFLAGS_TRANSFERMAKE ,"TRANSFERMAKE" }, + { LINEADDRCAPFLAGS_CONFERENCEHELD ,"CONFERENCEHELD" }, + { LINEADDRCAPFLAGS_CONFERENCEMAKE ,"CONFERENCEMAKE" }, + { LINEADDRCAPFLAGS_PARTIALDIAL ,"PARTIALDIAL" }, + { LINEADDRCAPFLAGS_FWDSTATUSVALID ,"FWDSTATUSVALID" }, + { LINEADDRCAPFLAGS_FWDINTEXTADDR ,"FWDINTEXTADDR" }, + { LINEADDRCAPFLAGS_FWDBUSYNAADDR ,"FWDBUSYNAADDR" }, + { LINEADDRCAPFLAGS_ACCEPTTOALERT ,"ACCEPTTOALERT" }, + { LINEADDRCAPFLAGS_CONFDROP ,"CONFDROP" }, + { LINEADDRCAPFLAGS_PICKUPCALLWAIT ,"PICKUPCALLWAIT" }, +#if TAPI_2_0 + { LINEADDRCAPFLAGS_PREDICTIVEDIALER ,"PREDICTIVEDIALER" }, + { LINEADDRCAPFLAGS_QUEUE ,"QUEUE" }, + { LINEADDRCAPFLAGS_ROUTEPOINT ,"ROUTEPOINT" }, + { LINEADDRCAPFLAGS_HOLDMAKESNEW ,"HOLDMAKESNEW" }, + { LINEADDRCAPFLAGS_NOINTERNALCALLS ,"NOINTERNALCALLS" }, + { LINEADDRCAPFLAGS_NOEXTERNALCALLS ,"NOEXTERNALCALLS" }, + { LINEADDRCAPFLAGS_SETCALLINGID ,"SETCALLINGID" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aAddressModes[] = +{ + { LINEADDRESSMODE_ADDRESSID ,"ADDRESSID" }, + { LINEADDRESSMODE_DIALABLEADDR ,"DIALABLEADDR" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aAddressSharing[] = +{ + { LINEADDRESSSHARING_PRIVATE ,"PRIVATE" }, + { LINEADDRESSSHARING_BRIDGEDEXCL ,"BRIDGEDEXCL" }, + { LINEADDRESSSHARING_BRIDGEDNEW ,"BRIDGEDNEW" }, + { LINEADDRESSSHARING_BRIDGEDSHARED ,"BRIDGEDSHARED" }, + { LINEADDRESSSHARING_MONITORED ,"MONITORED" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aAddressStates[] = +{ + { LINEADDRESSSTATE_OTHER ,"OTHER" }, + { LINEADDRESSSTATE_DEVSPECIFIC ,"DEVSPECIFIC" }, + { LINEADDRESSSTATE_INUSEZERO ,"INUSEZERO" }, + { LINEADDRESSSTATE_INUSEONE ,"INUSEONE" }, + { LINEADDRESSSTATE_INUSEMANY ,"INUSEMANY" }, + { LINEADDRESSSTATE_NUMCALLS ,"NUMCALLS" }, + { LINEADDRESSSTATE_FORWARD ,"FORWARD" }, + { LINEADDRESSSTATE_TERMINALS ,"TERMINALS" }, +#if TAPI_1_1 + { LINEADDRESSSTATE_CAPSCHANGE ,"CAPSCHANGE" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aAddressFeatures[] = +{ + { LINEADDRFEATURE_FORWARD ,"FORWARD" }, + { LINEADDRFEATURE_MAKECALL ,"MAKECALL" }, + { LINEADDRFEATURE_PICKUP ,"PICKUP" }, + { LINEADDRFEATURE_SETMEDIACONTROL ,"SETMEDIACONTROL" }, + { LINEADDRFEATURE_SETTERMINAL ,"SETTERMINAL" }, + { LINEADDRFEATURE_SETUPCONF ,"SETUPCONF" }, + { LINEADDRFEATURE_UNCOMPLETECALL ,"UNCOMPLETECALL" }, + { LINEADDRFEATURE_UNPARK ,"UNPARK" }, +#if TAPI_2_0 + { LINEADDRFEATURE_PICKUPHELD ,"PICKUPHELD " }, + { LINEADDRFEATURE_PICKUPGROUP ,"PICKUPGROUP " }, + { LINEADDRFEATURE_PICKUPDIRECT ,"PICKUPDIRECT " }, + { LINEADDRFEATURE_PICKUPWAITING ,"PICKUPWAITING" }, + { LINEADDRFEATURE_FORWARDFWD ,"FORWARDFWD " }, + { LINEADDRFEATURE_FORWARDDND ,"FORWARDDND " }, +#endif + { 0xffffffff ,"" } +}; + +#ifdef TAPI_2_0 +LOOKUP my_far aAgentStates[] = +{ + { LINEAGENTSTATE_LOGGEDOFF ,"LOGGEDOFF" }, + { LINEAGENTSTATE_NOTREADY ,"NOTREADY" }, + { LINEAGENTSTATE_READY ,"READY" }, + { LINEAGENTSTATE_BUSYACD ,"BUSYACD" }, + { LINEAGENTSTATE_BUSYINCOMING ,"BUSYINCOMING" }, + { LINEAGENTSTATE_BUSYOUTBOUND ,"BUSYOUTBOUND" }, + { LINEAGENTSTATE_BUSYOTHER ,"BUSYOTHER" }, + { LINEAGENTSTATE_WORKINGAFTERCALL ,"WORKINGAFTERCALL" }, + { LINEAGENTSTATE_UNKNOWN ,"UNKNOWN" }, + { LINEAGENTSTATE_UNAVAIL ,"UNAVAIL" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aAgentStatus[] = +{ + { LINEAGENTSTATUS_GROUP ,"GROUP" }, + { LINEAGENTSTATUS_STATE ,"STATE" }, + { LINEAGENTSTATUS_NEXTSTATE ,"NEXTSTATE" }, + { LINEAGENTSTATUS_ACTIVITY ,"ACTIVITY" }, + { LINEAGENTSTATUS_ACTIVITYLIST ,"ACTIVITYLIST" }, + { LINEAGENTSTATUS_GROUPLIST ,"GROUPLIST" }, + { LINEAGENTSTATUS_CAPSCHANGE ,"CAPSCHANGE" }, + { LINEAGENTSTATUS_VALIDSTATES ,"VALIDSTATES" }, + { LINEAGENTSTATUS_VALIDNEXTSTATES ,"VALIDNEXTSTATES" }, + { 0xffffffff ,"" } +}; +#endif + +LOOKUP my_far aAnswerModes[] = +{ + { LINEANSWERMODE_NONE ,"NONE" }, + { LINEANSWERMODE_DROP ,"DROP" }, + { LINEANSWERMODE_HOLD ,"HOLD" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aAPIVersions[] = +{ + { 0x00010003 ,"TAPI 1.0" }, +#if TAPI_1_1 + { 0x00010004 ,"TAPI 1.4" }, +#if TAPI_2_0 + { 0x00020000 ,"TAPI 2.0" }, +#endif +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aBearerModes[] = +{ + { LINEBEARERMODE_VOICE ,"VOICE" }, + { LINEBEARERMODE_SPEECH ,"SPEECH" }, + { LINEBEARERMODE_MULTIUSE ,"MULTIUSE" }, + { LINEBEARERMODE_DATA ,"DATA" }, + { LINEBEARERMODE_ALTSPEECHDATA ,"ALTSPEECHDATA" }, + { LINEBEARERMODE_NONCALLSIGNALING ,"NONCALLSIGNALING" }, +#if TAPI_1_1 + { LINEBEARERMODE_PASSTHROUGH ,"PASSTHROUGH" }, +#if TAPI_2_0 + { LINEBEARERMODE_RESTRICTEDDATA ,"RESTRICTEDDATA" }, +#endif +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aBusyModes[] = +{ + { LINEBUSYMODE_STATION ,"STATION" }, + { LINEBUSYMODE_TRUNK ,"TRUNK" }, + { LINEBUSYMODE_UNKNOWN ,"UNKNOWN" }, + { LINEBUSYMODE_UNAVAIL ,"UNAVAIL" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aCallComplConds[] = +{ + { LINECALLCOMPLCOND_BUSY ,"BUSY" }, + { LINECALLCOMPLCOND_NOANSWER ,"NOANSWER" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aCallComplModes[] = +{ + { LINECALLCOMPLMODE_CAMPON ,"CAMPON" }, + { LINECALLCOMPLMODE_CALLBACK ,"CALLBACK" }, + { LINECALLCOMPLMODE_INTRUDE ,"INTRUDE" }, + { LINECALLCOMPLMODE_MESSAGE ,"MESSAGE" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aCallFeatures[] = +{ + { LINECALLFEATURE_ACCEPT ,"ACCEPT" }, + { LINECALLFEATURE_ADDTOCONF ,"ADDTOCONF" }, + { LINECALLFEATURE_ANSWER ,"ANSWER" }, + { LINECALLFEATURE_BLINDTRANSFER ,"BLINDTRANSFER" }, + { LINECALLFEATURE_COMPLETECALL ,"COMPLETECALL" }, + { LINECALLFEATURE_COMPLETETRANSF ,"COMPLETETRANSF" }, + { LINECALLFEATURE_DIAL ,"DIAL" }, + { LINECALLFEATURE_DROP ,"DROP" }, + { LINECALLFEATURE_GATHERDIGITS ,"GATHERDIGITS" }, + { LINECALLFEATURE_GENERATEDIGITS ,"GENERATEDIGITS" }, + { LINECALLFEATURE_GENERATETONE ,"GENERATETONE" }, + { LINECALLFEATURE_HOLD ,"HOLD" }, + { LINECALLFEATURE_MONITORDIGITS ,"MONITORDIGITS" }, + { LINECALLFEATURE_MONITORMEDIA ,"MONITORMEDIA" }, + { LINECALLFEATURE_MONITORTONES ,"MONITORTONES" }, + { LINECALLFEATURE_PARK ,"PARK" }, + { LINECALLFEATURE_PREPAREADDCONF ,"PREPAREADDCONF" }, + { LINECALLFEATURE_REDIRECT ,"REDIRECT" }, + { LINECALLFEATURE_REMOVEFROMCONF ,"REMOVEFROMCONF" }, + { LINECALLFEATURE_SECURECALL ,"SECURECALL" }, + { LINECALLFEATURE_SENDUSERUSER ,"SENDUSERUSER" }, + { LINECALLFEATURE_SETCALLPARAMS ,"SETCALLPARAMS" }, + { LINECALLFEATURE_SETMEDIACONTROL ,"SETMEDIACONTROL" }, + { LINECALLFEATURE_SETTERMINAL ,"SETTERMINAL" }, + { LINECALLFEATURE_SETUPCONF ,"SETUPCONF" }, + { LINECALLFEATURE_SETUPTRANSFER ,"SETUPTRANSFER" }, + { LINECALLFEATURE_SWAPHOLD ,"SWAPHOLD" }, + { LINECALLFEATURE_UNHOLD ,"UNHOLD" }, +#if TAPI_1_1 + { LINECALLFEATURE_RELEASEUSERUSERINFO ,"RELEASEUSERUSERINFO" }, +#if TAPI_2_0 + { LINECALLFEATURE_SETTREATMENT ,"SETTREATMENT" }, + { LINECALLFEATURE_SETQOS ,"SETQOS" }, + { LINECALLFEATURE_SETCALLDATA ,"SETCALLDATA" }, +#endif +#endif + { 0xffffffff ,"" } +}; + +#if TAPI_2_0 +LOOKUP my_far aCallFeatures2[] = +{ + { LINECALLFEATURE2_NOHOLDCONFERENCE ,"NOHOLDCONFERENCE" }, + { LINECALLFEATURE2_ONESTEPTRANSFER ,"ONESTEPTRANSFER " }, + { LINECALLFEATURE2_COMPLCAMPON ,"COMPLCAMPON" }, + { LINECALLFEATURE2_COMPLCALLBACK ,"COMPLCALLBACK" }, + { LINECALLFEATURE2_COMPLINTRUDE ,"COMPLINTRUDE" }, + { LINECALLFEATURE2_COMPLMESSAGE ,"COMPLMESSAGE" }, + { LINECALLFEATURE2_TRANSFERNORM ,"TRANSFERNORM" }, + { LINECALLFEATURE2_TRANSFERCONF ,"TRANSFERCONF" }, + { LINECALLFEATURE2_PARKDIRECT ,"PARKDIRECT" }, + { LINECALLFEATURE2_PARKNONDIRECT ,"PARKNONDIRECT" }, + + { 0xffffffff ,"" } +}; +#endif + +LOOKUP my_far aCallInfoStates[] = +{ + { LINECALLINFOSTATE_OTHER ,"OTHER" }, + { LINECALLINFOSTATE_DEVSPECIFIC ,"DEVSPECIFIC" }, + { LINECALLINFOSTATE_BEARERMODE ,"BEARERMODE" }, + { LINECALLINFOSTATE_RATE ,"RATE" }, + { LINECALLINFOSTATE_MEDIAMODE ,"MEDIAMODE" }, + { LINECALLINFOSTATE_APPSPECIFIC ,"APPSPECIFIC" }, + { LINECALLINFOSTATE_CALLID ,"CALLID" }, + { LINECALLINFOSTATE_RELATEDCALLID ,"RELATEDCALLID" }, + { LINECALLINFOSTATE_ORIGIN ,"ORIGIN" }, + { LINECALLINFOSTATE_REASON ,"REASON" }, + { LINECALLINFOSTATE_COMPLETIONID ,"COMPLETIONID" }, + { LINECALLINFOSTATE_NUMOWNERINCR ,"NUMOWNERINCR" }, + { LINECALLINFOSTATE_NUMOWNERDECR ,"NUMOWNERDECR" }, + { LINECALLINFOSTATE_NUMMONITORS ,"NUMMONITORS" }, + { LINECALLINFOSTATE_TRUNK ,"TRUNK" }, + { LINECALLINFOSTATE_CALLERID ,"CALLERID" }, + { LINECALLINFOSTATE_CALLEDID ,"CALLEDID" }, + { LINECALLINFOSTATE_CONNECTEDID ,"CONNECTEDID" }, + { LINECALLINFOSTATE_REDIRECTIONID ,"REDIRECTIONID" }, + { LINECALLINFOSTATE_REDIRECTINGID ,"REDIRECTINGID" }, + { LINECALLINFOSTATE_DISPLAY ,"DISPLAY" }, + { LINECALLINFOSTATE_USERUSERINFO ,"USERUSERINFO" }, + { LINECALLINFOSTATE_HIGHLEVELCOMP ,"HIGHLEVELCOMP" }, + { LINECALLINFOSTATE_LOWLEVELCOMP ,"LOWLEVELCOMP" }, + { LINECALLINFOSTATE_CHARGINGINFO ,"CHARGINGINFO" }, + { LINECALLINFOSTATE_TERMINAL ,"TERMINAL" }, + { LINECALLINFOSTATE_DIALPARAMS ,"DIALPARAMS" }, + { LINECALLINFOSTATE_MONITORMODES ,"MONITORMODES" }, +#if TAPI_2_0 + { LINECALLINFOSTATE_TREATMENT ,"TREATMENT" }, + { LINECALLINFOSTATE_QOS ,"QOS" }, + { LINECALLINFOSTATE_CALLDATA ,"CALLDATA" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aCallOrigins[] = +{ + { LINECALLORIGIN_OUTBOUND ,"OUTBOUND" }, + { LINECALLORIGIN_INTERNAL ,"INTERNAL" }, + { LINECALLORIGIN_EXTERNAL ,"EXTERNAL" }, + { LINECALLORIGIN_UNKNOWN ,"UNKNOWN" }, + { LINECALLORIGIN_UNAVAIL ,"UNAVAIL" }, + { LINECALLORIGIN_CONFERENCE ,"CONFERENCE" }, +#if TAPI_1_1 + { LINECALLORIGIN_INBOUND ,"INBOUND" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aCallParamFlags[] = +{ + { LINECALLPARAMFLAGS_SECURE ,"SECURE" }, + { LINECALLPARAMFLAGS_IDLE ,"IDLE" }, + { LINECALLPARAMFLAGS_BLOCKID ,"BLOCKID" }, + { LINECALLPARAMFLAGS_ORIGOFFHOOK ,"ORIGOFFHOOK" }, + { LINECALLPARAMFLAGS_DESTOFFHOOK ,"DESTOFFHOOK" }, +#if TAPI_2_0 + { LINECALLPARAMFLAGS_NOHOLDCONFERENCE ,"NOHOLDCONFERENCE" }, + { LINECALLPARAMFLAGS_PREDICTIVEDIAL ,"PREDICTIVEDIAL" }, + { LINECALLPARAMFLAGS_ONESTEPTRANSFER,"ONESTEPTRANSFER" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aCallerIDFlags[] = +{ + { LINECALLPARTYID_BLOCKED ,"BLOCKED" }, + { LINECALLPARTYID_OUTOFAREA ,"OUTOFAREA" }, + { LINECALLPARTYID_NAME ,"NAME" }, + { LINECALLPARTYID_ADDRESS ,"ADDRESS" }, + { LINECALLPARTYID_PARTIAL ,"PARTIAL" }, + { LINECALLPARTYID_UNKNOWN ,"UNKNOWN" }, + { LINECALLPARTYID_UNAVAIL ,"UNAVAIL" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aCallPrivileges[] = +{ + { LINECALLPRIVILEGE_NONE ,"NONE" }, + { LINECALLPRIVILEGE_MONITOR ,"MONITOR" }, + { LINECALLPRIVILEGE_OWNER ,"OWNER" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aCallReasons[] = +{ + { LINECALLREASON_DIRECT ,"DIRECT" }, + { LINECALLREASON_FWDBUSY ,"FWDBUSY" }, + { LINECALLREASON_FWDNOANSWER ,"FWDNOANSWER" }, + { LINECALLREASON_FWDUNCOND ,"FWDUNCOND" }, + { LINECALLREASON_PICKUP ,"PICKUP" }, + { LINECALLREASON_UNPARK ,"UNPARK" }, + { LINECALLREASON_REDIRECT ,"REDIRECT" }, + { LINECALLREASON_CALLCOMPLETION ,"CALLCOMPLETION" }, + { LINECALLREASON_TRANSFER ,"TRANSFER" }, + { LINECALLREASON_REMINDER ,"REMINDER" }, + { LINECALLREASON_UNKNOWN ,"UNKNOWN" }, + { LINECALLREASON_UNAVAIL ,"UNAVAIL" }, +#if TAPI_1_1 + { LINECALLREASON_INTRUDE ,"INTRUDE" }, + { LINECALLREASON_PARKED ,"PARKED" }, +#if TAPI_2_0 + { LINECALLREASON_CAMPEDON ,"CAMPEDON" }, + { LINECALLREASON_ROUTEREQUEST ,"ROUTEREQUEST" }, +#endif +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aCallSelects[] = +{ + { LINECALLSELECT_LINE ,"LINE" }, + { LINECALLSELECT_ADDRESS ,"ADDRESS" }, + { LINECALLSELECT_CALL ,"CALL" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aCallStates[] = +{ + { LINECALLSTATE_IDLE ,"IDLE" }, + { LINECALLSTATE_OFFERING ,"OFFERING" }, + { LINECALLSTATE_ACCEPTED ,"ACCEPTED" }, + { LINECALLSTATE_DIALTONE ,"DIALTONE" }, + { LINECALLSTATE_DIALING ,"DIALING" }, + { LINECALLSTATE_RINGBACK ,"RINGBACK" }, + { LINECALLSTATE_BUSY ,"BUSY" }, + { LINECALLSTATE_SPECIALINFO ,"SPECIALINFO" }, + { LINECALLSTATE_CONNECTED ,"CONNECTED" }, + { LINECALLSTATE_PROCEEDING ,"PROCEEDING" }, + { LINECALLSTATE_ONHOLD ,"ONHOLD" }, + { LINECALLSTATE_CONFERENCED ,"CONFERENCED" }, + { LINECALLSTATE_ONHOLDPENDCONF ,"ONHOLDPENDCONF" }, + { LINECALLSTATE_ONHOLDPENDTRANSFER ,"ONHOLDPENDTRANSFER" }, + { LINECALLSTATE_DISCONNECTED ,"DISCONNECTED" }, + { LINECALLSTATE_UNKNOWN ,"UNKNOWN" }, + { 0xffffffff ,"" } +}; + +#if TAPI_2_0 +LOOKUP my_far aCallTreatments[] = +{ + { LINECALLTREATMENT_SILENCE ,"SILENCE" }, + { LINECALLTREATMENT_RINGBACK ,"RINGBACK" }, + { LINECALLTREATMENT_BUSY ,"BUSY" }, + { LINECALLTREATMENT_MUSIC ,"MUSIC" }, + { 0xffffffff ,"" } +}; +#endif + +LOOKUP my_far aCardOptions[] = +{ +#if TAPI_1_1 + { LINECARDOPTION_PREDEFINED ,"PREDEFINED" }, + { LINECARDOPTION_HIDDEN ,"HIDDEN" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aConnectedModes[] = +{ +#if TAPI_1_1 + { LINECONNECTEDMODE_ACTIVE ,"ACTIVE" }, + { LINECONNECTEDMODE_INACTIVE ,"INACTIVE" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aDevCapsFlags[] = +{ + { LINEDEVCAPFLAGS_CROSSADDRCONF ,"CROSSADDRCONF" }, + { LINEDEVCAPFLAGS_HIGHLEVCOMP ,"HIGHLEVCOMP" }, + { LINEDEVCAPFLAGS_LOWLEVCOMP ,"LOWLEVCOMP" }, + { LINEDEVCAPFLAGS_MEDIACONTROL ,"MEDIACONTROL" }, + { LINEDEVCAPFLAGS_MULTIPLEADDR ,"MULTIPLEADDR" }, + { LINEDEVCAPFLAGS_CLOSEDROP ,"CLOSEDROP" }, + { LINEDEVCAPFLAGS_DIALBILLING ,"DIALBILLING" }, + { LINEDEVCAPFLAGS_DIALQUIET ,"DIALQUIET" }, + { LINEDEVCAPFLAGS_DIALDIALTONE ,"DIALDIALTONE" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aLineDevStatusFlags[] = +{ + { LINEDEVSTATUSFLAGS_CONNECTED ,"CONNECTED" }, + { LINEDEVSTATUSFLAGS_MSGWAIT ,"MSGWAIT" }, + { LINEDEVSTATUSFLAGS_INSERVICE ,"INSERVICE" }, + { LINEDEVSTATUSFLAGS_LOCKED ,"LOCKED" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aDialToneModes[] = +{ + { LINEDIALTONEMODE_NORMAL ,"NORMAL" }, + { LINEDIALTONEMODE_SPECIAL ,"SPECIAL" }, + { LINEDIALTONEMODE_INTERNAL ,"INTERNAL" }, + { LINEDIALTONEMODE_EXTERNAL ,"EXTERNAL" }, + { LINEDIALTONEMODE_UNKNOWN ,"UNKNOWN" }, + { LINEDIALTONEMODE_UNAVAIL ,"UNAVAIL" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aDigitModes[] = +{ + { LINEDIGITMODE_PULSE ,"PULSE" }, + { LINEDIGITMODE_DTMF ,"DTMF" }, + { LINEDIGITMODE_DTMFEND ,"DTMFEND" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aDisconnectModes[] = +{ + { LINEDISCONNECTMODE_NORMAL ,"NORMAL" }, + { LINEDISCONNECTMODE_UNKNOWN ,"UNKNOWN" }, + { LINEDISCONNECTMODE_REJECT ,"REJECT" }, + { LINEDISCONNECTMODE_PICKUP ,"PICKUP" }, + { LINEDISCONNECTMODE_FORWARDED ,"FORWARDED" }, + { LINEDISCONNECTMODE_BUSY ,"BUSY" }, + { LINEDISCONNECTMODE_NOANSWER ,"NOANSWER" }, + { LINEDISCONNECTMODE_BADADDRESS ,"BADADDRESS" }, + { LINEDISCONNECTMODE_UNREACHABLE ,"UNREACHABLE" }, + { LINEDISCONNECTMODE_CONGESTION ,"CONGESTION" }, + { LINEDISCONNECTMODE_INCOMPATIBLE ,"INCOMPATIBLE" }, + { LINEDISCONNECTMODE_UNAVAIL ,"UNAVAIL" }, +#if TAPI_1_1 + { LINEDISCONNECTMODE_NODIALTONE ,"NODIALTONE" }, +#if TAPI_2_0 + { LINEDISCONNECTMODE_NUMBERCHANGED ,"NUMBERCHANGED" }, + { LINEDISCONNECTMODE_OUTOFORDER ,"OUTOFORDER" }, + { LINEDISCONNECTMODE_TEMPFAILURE ,"TEMPFAILURE" }, + { LINEDISCONNECTMODE_QOSUNAVAIL ,"QOSUNAVAIL" }, + { LINEDISCONNECTMODE_BLOCKED ,"BLOCKED" }, + { LINEDISCONNECTMODE_DONOTDISTURB ,"DONOTDISTURB" }, +#endif +#endif + { 0xffffffff ,"" } +}; + +#if TAPI_2_0 +LOOKUP my_far aInitExOptions[] = +{ + { LINEINITIALIZEEXOPTION_USEHIDDENWINDOW + ,"USEHIDDENWINDOW" }, + { LINEINITIALIZEEXOPTION_USEEVENT ,"USEEVENT" }, + { LINEINITIALIZEEXOPTION_USECOMPLETIONPORT + ,"USECOMPLETIONPORT"}, + { 0xffffffff ,"" } +}; +#endif + +LOOKUP my_far aLineFeatures[] = +{ + { LINEFEATURE_DEVSPECIFIC ,"DEVSPECIFIC" }, + { LINEFEATURE_DEVSPECIFICFEAT ,"DEVSPECIFICFEAT" }, + { LINEFEATURE_FORWARD ,"FORWARD" }, + { LINEFEATURE_MAKECALL ,"MAKECALL" }, + { LINEFEATURE_SETMEDIACONTROL ,"SETMEDIACONTROL" }, + { LINEFEATURE_SETTERMINAL ,"SETTERMINAL" }, +#if TAPI_2_0 + { LINEFEATURE_SETDEVSTATUS ,"SETDEVSTATUS" }, + { LINEFEATURE_FORWARDFWD ,"FORWARDFWD" }, + { LINEFEATURE_FORWARDDND ,"FORWARDDND" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aForwardModes[] = +{ + { LINEFORWARDMODE_UNCOND ,"UNCOND" }, + { LINEFORWARDMODE_UNCONDINTERNAL ,"UNCONDINTERNAL" }, + { LINEFORWARDMODE_UNCONDEXTERNAL ,"UNCONDEXTERNAL" }, + { LINEFORWARDMODE_UNCONDSPECIFIC ,"UNCONDSPECIFIC" }, + { LINEFORWARDMODE_BUSY ,"BUSY" }, + { LINEFORWARDMODE_BUSYINTERNAL ,"BUSYINTERNAL" }, + { LINEFORWARDMODE_BUSYEXTERNAL ,"BUSYEXTERNAL" }, + { LINEFORWARDMODE_BUSYSPECIFIC ,"BUSYSPECIFIC" }, + { LINEFORWARDMODE_NOANSW ,"NOANSW" }, + { LINEFORWARDMODE_NOANSWINTERNAL ,"NOANSWINTERNAL" }, + { LINEFORWARDMODE_NOANSWEXTERNAL ,"NOANSWEXTERNAL" }, + { LINEFORWARDMODE_NOANSWSPECIFIC ,"NOANSWSPECIFIC" }, + { LINEFORWARDMODE_BUSYNA ,"BUSYNA" }, + { LINEFORWARDMODE_BUSYNAINTERNAL ,"BUSYNAINTERNAL" }, + { LINEFORWARDMODE_BUSYNAEXTERNAL ,"BUSYNAEXTERNAL" }, + { LINEFORWARDMODE_BUSYNASPECIFIC ,"BUSYNASPECIFIC" }, +#if TAPI_1_1 + { LINEFORWARDMODE_UNKNOWN ,"UNKNOWN" }, + { LINEFORWARDMODE_UNAVAIL ,"UNAVAIL" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aGatherTerms[] = +{ + { LINEGATHERTERM_BUFFERFULL ,"BUFFERFULL" }, + { LINEGATHERTERM_TERMDIGIT ,"TERMDIGIT" }, + { LINEGATHERTERM_FIRSTTIMEOUT ,"FIRSTTIMEOUT" }, + { LINEGATHERTERM_INTERTIMEOUT ,"INTERTIMEOUT" }, + { LINEGATHERTERM_CANCEL ,"CANCEL" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aGenerateTerms[] = +{ + { LINEGENERATETERM_DONE ,"DONE" }, + { LINEGENERATETERM_CANCEL ,"CANCEL" }, + { 0xffffffff ,"" } +}; + +LOOKUP aLineOpenOptions[] = +{ + { LINECALLPRIVILEGE_NONE ,"NONE" }, + { LINECALLPRIVILEGE_MONITOR ,"MONITOR" }, + { LINECALLPRIVILEGE_OWNER ,"OWNER" }, + { LINEOPENOPTION_PROXY ,"PROXY" }, + { LINEOPENOPTION_SINGLEADDRESS ,"SINGLEADDRESS" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aLineRoamModes[] = +{ + { LINEROAMMODE_UNKNOWN ,"UNKNOWN" }, + { LINEROAMMODE_UNAVAIL ,"UNAVAIL" }, + { LINEROAMMODE_HOME ,"HOME" }, + { LINEROAMMODE_ROAMA ,"ROAMA" }, + { LINEROAMMODE_ROAMB ,"ROAMB" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aLineStates[] = +{ + { LINEDEVSTATE_OTHER ,"OTHER" }, + { LINEDEVSTATE_RINGING ,"RINGING" }, + { LINEDEVSTATE_CONNECTED ,"CONNECTED" }, + { LINEDEVSTATE_DISCONNECTED ,"DISCONNECTED" }, + { LINEDEVSTATE_MSGWAITON ,"MSGWAITON" }, + { LINEDEVSTATE_MSGWAITOFF ,"MSGWAITOFF" }, + { LINEDEVSTATE_INSERVICE ,"INSERVICE" }, + { LINEDEVSTATE_OUTOFSERVICE ,"OUTOFSERVICE" }, + { LINEDEVSTATE_MAINTENANCE ,"MAINTENANCE" }, + { LINEDEVSTATE_OPEN ,"OPEN" }, + { LINEDEVSTATE_CLOSE ,"CLOSE" }, + { LINEDEVSTATE_NUMCALLS ,"NUMCALLS" }, + { LINEDEVSTATE_NUMCOMPLETIONS ,"NUMCOMPLETIONS" }, + { LINEDEVSTATE_TERMINALS ,"TERMINALS" }, + { LINEDEVSTATE_ROAMMODE ,"ROAMMODE" }, + { LINEDEVSTATE_BATTERY ,"BATTERY" }, + { LINEDEVSTATE_SIGNAL ,"SIGNAL" }, + { LINEDEVSTATE_DEVSPECIFIC ,"DEVSPECIFIC" }, + { LINEDEVSTATE_REINIT ,"REINIT" }, + { LINEDEVSTATE_LOCK ,"LOCK" }, +#if TAPI_1_1 + { LINEDEVSTATE_CAPSCHANGE ,"CAPSCHANGE" }, + { LINEDEVSTATE_CONFIGCHANGE ,"CONFIGCHANGE" }, + { LINEDEVSTATE_TRANSLATECHANGE ,"TRANSLATECHANGE" }, + { LINEDEVSTATE_COMPLCANCEL ,"COMPLCANCEL" }, + { LINEDEVSTATE_REMOVED ,"REMOVED" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aLocationOptions[] = +{ +#if TAPI_1_1 + { LINELOCATIONOPTION_PULSEDIAL ,"PULSEDIAL" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aMediaModes[] = +{ + { LINEMEDIAMODE_UNKNOWN ,"UNKNOWN" }, + { LINEMEDIAMODE_INTERACTIVEVOICE ,"INTERACTIVEVOICE" }, + { LINEMEDIAMODE_AUTOMATEDVOICE ,"AUTOMATEDVOICE" }, + { LINEMEDIAMODE_DATAMODEM ,"DATAMODEM" }, + { LINEMEDIAMODE_G3FAX ,"G3FAX" }, + { LINEMEDIAMODE_TDD ,"TDD" }, + { LINEMEDIAMODE_G4FAX ,"G4FAX" }, + { LINEMEDIAMODE_DIGITALDATA ,"DIGITALDATA" }, + { LINEMEDIAMODE_TELETEX ,"TELETEX" }, + { LINEMEDIAMODE_VIDEOTEX ,"VIDEOTEX" }, + { LINEMEDIAMODE_TELEX ,"TELEX" }, + { LINEMEDIAMODE_MIXED ,"MIXED" }, + { LINEMEDIAMODE_ADSI ,"ADSI" }, +#if TAPI_1_1 + { LINEMEDIAMODE_VOICEVIEW ,"VOICEVIEW" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aMediaControls[] = +{ + { LINEMEDIACONTROL_NONE ,"NONE" }, + { LINEMEDIACONTROL_START ,"START" }, + { LINEMEDIACONTROL_RESET ,"RESET" }, + { LINEMEDIACONTROL_PAUSE ,"PAUSE" }, + { LINEMEDIACONTROL_RESUME ,"RESUME" }, + { LINEMEDIACONTROL_RATEUP ,"RATEUP" }, + { LINEMEDIACONTROL_RATEDOWN ,"RATEDOWN" }, + { LINEMEDIACONTROL_RATENORMAL ,"RATENORMAL" }, + { LINEMEDIACONTROL_VOLUMEUP ,"VOLUMEUP" }, + { LINEMEDIACONTROL_VOLUMEDOWN ,"VOLUMEDOWN" }, + { LINEMEDIACONTROL_VOLUMENORMAL ,"VOLUMENORMAL" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aOfferingModes[] = +{ +#if TAPI_1_1 + { LINEOFFERINGMODE_ACTIVE ,"ACTIVE" }, + { LINEOFFERINGMODE_INACTIVE ,"INACTIVE" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aParkModes[] = +{ + { LINEPARKMODE_DIRECTED ,"DIRECTED" }, + { LINEPARKMODE_NONDIRECTED ,"NONDIRECTED" }, + { 0xffffffff ,"" } +}; + +#if TAPI_2_0 +LOOKUP my_far aProxyRequests[] = +{ + { LINEPROXYREQUEST_SETAGENTGROUP ,"SETAGENTGROUP" }, + { LINEPROXYREQUEST_SETAGENTSTATE ,"SETAGENTSTATE" }, + { LINEPROXYREQUEST_SETAGENTACTIVITY ,"SETAGENTACTIVITY" }, + { LINEPROXYREQUEST_GETAGENTCAPS ,"GETAGENTCAPS" }, + { LINEPROXYREQUEST_GETAGENTSTATUS ,"GETAGENTSTATUS" }, + { LINEPROXYREQUEST_AGENTSPECIFIC ,"AGENTSPECIFIC" }, + { LINEPROXYREQUEST_GETAGENTACTIVITYLIST ,"GETAGENTACTIVITYLIST" }, + { LINEPROXYREQUEST_GETAGENTGROUPLIST ,"GETAGENTGROUPLIST" }, + { 0xffffffff ,"" } +}; +#endif + +LOOKUP my_far aRemoveFromConfCaps[] = +{ + { LINEREMOVEFROMCONF_NONE ,"NONE" }, + { LINEREMOVEFROMCONF_LAST ,"LAST" }, + { LINEREMOVEFROMCONF_ANY ,"ANY" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aRequestModes[] = +{ + { LINEREQUESTMODE_MAKECALL ,"MAKECALL" }, + { LINEREQUESTMODE_MEDIACALL ,"MEDIACALL" }, + { LINEREQUESTMODE_DROP ,"DROP" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aRequestModes2[] = +{ + { LINEREQUESTMODE_MAKECALL ,"MAKECALL" }, + { LINEREQUESTMODE_MEDIACALL ,"MEDIACALL" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aSpecialInfo[] = +{ + { LINESPECIALINFO_NOCIRCUIT ,"NOCIRCUIT" }, + { LINESPECIALINFO_CUSTIRREG ,"CUSTIRREG" }, + { LINESPECIALINFO_REORDER ,"REORDER" }, + { LINESPECIALINFO_UNKNOWN ,"UNKNOWN" }, + { LINESPECIALINFO_UNAVAIL ,"UNAVAIL" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aTerminalModes[] = +{ + { LINETERMMODE_BUTTONS ,"BUTTONS" }, + { LINETERMMODE_LAMPS ,"LAMPS" }, + { LINETERMMODE_DISPLAY ,"DISPLAY" }, + { LINETERMMODE_RINGER ,"RINGER" }, + { LINETERMMODE_HOOKSWITCH ,"HOOKSWITCH" }, + { LINETERMMODE_MEDIATOLINE ,"MEDIATOLINE" }, + { LINETERMMODE_MEDIAFROMLINE ,"MEDIAFROMLINE" }, + { LINETERMMODE_MEDIABIDIRECT ,"MEDIABIDIRECT" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aTollListOptions[] = +{ + { LINETOLLLISTOPTION_ADD ,"ADD" }, + { LINETOLLLISTOPTION_REMOVE ,"REMOVE" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aToneModes[] = +{ + { LINETONEMODE_CUSTOM ,"CUSTOM" }, + { LINETONEMODE_RINGBACK ,"RINGBACK" }, + { LINETONEMODE_BUSY ,"BUSY" }, + { LINETONEMODE_BEEP ,"BEEP" }, + { LINETONEMODE_BILLING ,"BILLING" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aTransferModes[] = +{ + { LINETRANSFERMODE_TRANSFER ,"TRANSFER" }, + { LINETRANSFERMODE_CONFERENCE ,"CONFERENCE" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aTranslateOptions[] = +{ + { LINETRANSLATEOPTION_CARDOVERRIDE ,"CARDOVERRIDE" }, +#if TAPI_1_1 + { LINETRANSLATEOPTION_CANCELCALLWAITING ,"CANCELCALLWAITING" }, + { LINETRANSLATEOPTION_FORCELOCAL ,"FORCELOCAL" }, + { LINETRANSLATEOPTION_FORCELD ,"FORCELD" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aTranslateResults[] = +{ + { LINETRANSLATERESULT_CANONICAL ,"CANONICAL" }, + { LINETRANSLATERESULT_INTERNATIONAL ,"INTERNATIONAL" }, + { LINETRANSLATERESULT_LONGDISTANCE ,"LONGDISTANCE" }, + { LINETRANSLATERESULT_LOCAL ,"LOCAL" }, + { LINETRANSLATERESULT_INTOLLLIST ,"INTOLLLIST" }, + { LINETRANSLATERESULT_NOTINTOLLLIST ,"NOTINTOLLLIST" }, + { LINETRANSLATERESULT_DIALBILLING ,"DIALBILLING" }, + { LINETRANSLATERESULT_DIALQUIET ,"DIALQUIET" }, + { LINETRANSLATERESULT_DIALDIALTONE ,"DIALDIALTONE" }, + { LINETRANSLATERESULT_DIALPROMPT ,"DIALPROMPT" }, +#if TAPI_2_0 + { LINETRANSLATERESULT_VOICEDETECT ,"VOICEDETECT" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aButtonFunctions[] = +{ + { PHONEBUTTONFUNCTION_UNKNOWN ,"UNKNOWN" }, + { PHONEBUTTONFUNCTION_CONFERENCE ,"CONFERENCE" }, + { PHONEBUTTONFUNCTION_TRANSFER ,"TRANSFER" }, + { PHONEBUTTONFUNCTION_DROP ,"DROP" }, + { PHONEBUTTONFUNCTION_HOLD ,"HOLD" }, + { PHONEBUTTONFUNCTION_RECALL ,"RECALL" }, + { PHONEBUTTONFUNCTION_DISCONNECT ,"DISCONNECT" }, + { PHONEBUTTONFUNCTION_CONNECT ,"CONNECT" }, + { PHONEBUTTONFUNCTION_MSGWAITON ,"MSGWAITON" }, + { PHONEBUTTONFUNCTION_MSGWAITOFF ,"MSGWAITOFF" }, + { PHONEBUTTONFUNCTION_SELECTRING ,"SELECTRING" }, + { PHONEBUTTONFUNCTION_ABBREVDIAL ,"ABBREVDIAL" }, + { PHONEBUTTONFUNCTION_FORWARD ,"FORWARD" }, + { PHONEBUTTONFUNCTION_PICKUP ,"PICKUP" }, + { PHONEBUTTONFUNCTION_RINGAGAIN ,"RINGAGAIN" }, + { PHONEBUTTONFUNCTION_PARK ,"PARK" }, + { PHONEBUTTONFUNCTION_REJECT ,"REJECT" }, + { PHONEBUTTONFUNCTION_REDIRECT ,"REDIRECT" }, + { PHONEBUTTONFUNCTION_MUTE ,"MUTE" }, + { PHONEBUTTONFUNCTION_VOLUMEUP ,"VOLUMEUP" }, + { PHONEBUTTONFUNCTION_VOLUMEDOWN ,"VOLUMEDOWN" }, + { PHONEBUTTONFUNCTION_SPEAKERON ,"SPEAKERON" }, + { PHONEBUTTONFUNCTION_SPEAKEROFF ,"SPEAKEROFF" }, + { PHONEBUTTONFUNCTION_FLASH ,"FLASH" }, + { PHONEBUTTONFUNCTION_DATAON ,"DATAON" }, + { PHONEBUTTONFUNCTION_DATAOFF ,"DATAOFF" }, + { PHONEBUTTONFUNCTION_DONOTDISTURB ,"DONOTDISTURB" }, + { PHONEBUTTONFUNCTION_INTERCOM ,"INTERCOM" }, + { PHONEBUTTONFUNCTION_BRIDGEDAPP ,"BRIDGEDAPP" }, + { PHONEBUTTONFUNCTION_BUSY ,"BUSY" }, + { PHONEBUTTONFUNCTION_CALLAPP ,"CALLAPP" }, + { PHONEBUTTONFUNCTION_DATETIME ,"DATETIME" }, + { PHONEBUTTONFUNCTION_DIRECTORY ,"DIRECTORY" }, + { PHONEBUTTONFUNCTION_COVER ,"COVER" }, + { PHONEBUTTONFUNCTION_CALLID ,"CALLID" }, + { PHONEBUTTONFUNCTION_LASTNUM ,"LASTNUM" }, + { PHONEBUTTONFUNCTION_NIGHTSRV ,"NIGHTSRV" }, + { PHONEBUTTONFUNCTION_SENDCALLS ,"SENDCALLS" }, + { PHONEBUTTONFUNCTION_MSGINDICATOR ,"MSGINDICATOR" }, + { PHONEBUTTONFUNCTION_REPDIAL ,"REPDIAL" }, + { PHONEBUTTONFUNCTION_SETREPDIAL ,"SETREPDIAL" }, + { PHONEBUTTONFUNCTION_SYSTEMSPEED ,"SYSTEMSPEED" }, + { PHONEBUTTONFUNCTION_STATIONSPEED ,"STATIONSPEED" }, + { PHONEBUTTONFUNCTION_CAMPON ,"CAMPON" }, + { PHONEBUTTONFUNCTION_SAVEREPEAT ,"SAVEREPEAT" }, + { PHONEBUTTONFUNCTION_QUEUECALL ,"QUEUECALL" }, + { PHONEBUTTONFUNCTION_NONE ,"NONE" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aButtonModes[] = +{ + { PHONEBUTTONMODE_DUMMY ,"DUMMY" }, + { PHONEBUTTONMODE_CALL ,"CALL" }, + { PHONEBUTTONMODE_FEATURE ,"FEATURE" }, + { PHONEBUTTONMODE_KEYPAD ,"KEYPAD" }, + { PHONEBUTTONMODE_LOCAL ,"LOCAL" }, + { PHONEBUTTONMODE_DISPLAY ,"DISPLAY" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aButtonStates[] = +{ + { PHONEBUTTONSTATE_UP ,"UP" }, + { PHONEBUTTONSTATE_DOWN ,"DOWN" }, +#if TAPI_1_1 + { PHONEBUTTONSTATE_UNKNOWN ,"UNKNOWN" }, + { PHONEBUTTONSTATE_UNAVAIL ,"UNAVAIL" }, +#endif + { 0xffffffff ,"" } +}; + +#if TAPI_2_0 +LOOKUP my_far aPhoneFeatures[] = +{ + { PHONEFEATURE_GETBUTTONINFO ,"GETBUTTONINFO" }, + { PHONEFEATURE_GETDATA ,"GETDATA" }, + { PHONEFEATURE_GETDISPLAY ,"GETDISPLAY" }, + { PHONEFEATURE_GETGAINHANDSET ,"GETGAINHANDSET" }, + { PHONEFEATURE_GETGAINSPEAKER ,"GETGAINSPEAKER" }, + { PHONEFEATURE_GETGAINHEADSET ,"GETGAINHEADSET" }, + { PHONEFEATURE_GETHOOKSWITCHHANDSET ,"GETHOOKSWITCHHANDSET" }, + { PHONEFEATURE_GETHOOKSWITCHSPEAKER ,"GETHOOKSWITCHSPEAKER" }, + { PHONEFEATURE_GETHOOKSWITCHHEADSET ,"GETHOOKSWITCHHEADSET" }, + { PHONEFEATURE_GETLAMP ,"GETLAMP" }, + { PHONEFEATURE_GETRING ,"GETRING" }, + { PHONEFEATURE_GETVOLUMEHANDSET ,"GETVOLUMEHANDSET" }, + { PHONEFEATURE_GETVOLUMESPEAKER ,"GETVOLUMESPEAKER" }, + { PHONEFEATURE_GETVOLUMEHEADSET ,"GETVOLUMEHEADSET" }, + { PHONEFEATURE_SETBUTTONINFO ,"SETBUTTONINFO" }, + { PHONEFEATURE_SETDATA ,"SETDATA" }, + { PHONEFEATURE_SETDISPLAY ,"SETDISPLAY" }, + { PHONEFEATURE_SETGAINHANDSET ,"SETGAINHANDSET" }, + { PHONEFEATURE_SETGAINSPEAKER ,"SETGAINSPEAKER" }, + { PHONEFEATURE_SETGAINHEADSET ,"SETGAINHEADSET" }, + { PHONEFEATURE_SETHOOKSWITCHHANDSET ,"SETHOOKSWITCHHANDSET" }, + { PHONEFEATURE_SETHOOKSWITCHSPEAKER ,"SETHOOKSWITCHSPEAKER" }, + { PHONEFEATURE_SETHOOKSWITCHHEADSET ,"SETHOOKSWITCHHEADSET" }, + { PHONEFEATURE_SETLAMP ,"SETLAMP" }, + { PHONEFEATURE_SETRING ,"SETRING" }, + { PHONEFEATURE_SETVOLUMEHANDSET ,"SETVOLUMEHANDSET" }, + { PHONEFEATURE_SETVOLUMESPEAKER ,"SETVOLUMESPEAKER" }, + { PHONEFEATURE_SETVOLUMEHEADSET ,"SETVOLUMEHEADSET" }, + { 0xffffffff ,"" } +}; +#endif + +LOOKUP my_far aHookSwitchDevs[] = +{ + { PHONEHOOKSWITCHDEV_HANDSET ,"HANDSET" }, + { PHONEHOOKSWITCHDEV_SPEAKER ,"SPEAKER" }, + { PHONEHOOKSWITCHDEV_HEADSET ,"HEADSET" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aHookSwitchModes[] = +{ + { PHONEHOOKSWITCHMODE_ONHOOK ,"ONHOOK" }, + { PHONEHOOKSWITCHMODE_MIC ,"MIC" }, + { PHONEHOOKSWITCHMODE_SPEAKER ,"SPEAKER" }, + { PHONEHOOKSWITCHMODE_MICSPEAKER ,"MICSPEAKER" }, + { PHONEHOOKSWITCHMODE_UNKNOWN ,"UNKNOWN" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aLampModes[] = +{ + { PHONELAMPMODE_DUMMY ,"DUMMY" }, + { PHONELAMPMODE_OFF ,"OFF" }, + { PHONELAMPMODE_STEADY ,"STEADY" }, + { PHONELAMPMODE_WINK ,"WINK" }, + { PHONELAMPMODE_FLASH ,"FLASH" }, + { PHONELAMPMODE_FLUTTER ,"FLUTTER" }, + { PHONELAMPMODE_BROKENFLUTTER ,"BROKENFLUTTER" }, + { PHONELAMPMODE_UNKNOWN ,"UNKNOWN" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aPhonePrivileges[] = +{ + { PHONEPRIVILEGE_MONITOR ,"MONITOR" }, + { PHONEPRIVILEGE_OWNER ,"OWNER" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aPhoneStates[] = +{ + { PHONESTATE_OTHER ,"OTHER" }, + { PHONESTATE_CONNECTED ,"CONNECTED" }, + { PHONESTATE_DISCONNECTED ,"DISCONNECTED" }, + { PHONESTATE_OWNER ,"OWNER" }, + { PHONESTATE_MONITORS ,"MONITORS" }, + { PHONESTATE_DISPLAY ,"DISPLAY" }, + { PHONESTATE_LAMP ,"LAMP" }, + { PHONESTATE_RINGMODE ,"RINGMODE" }, + { PHONESTATE_RINGVOLUME ,"RINGVOLUME" }, + { PHONESTATE_HANDSETHOOKSWITCH ,"HANDSETHOOKSWITCH"}, + { PHONESTATE_HANDSETVOLUME ,"HANDSETVOLUME" }, + { PHONESTATE_HANDSETGAIN ,"HANDSETGAIN" }, + { PHONESTATE_SPEAKERHOOKSWITCH ,"SPEAKERHOOKSWITCH"}, + { PHONESTATE_SPEAKERVOLUME ,"SPEAKERVOLUME" }, + { PHONESTATE_SPEAKERGAIN ,"SPEAKERGAIN" }, + { PHONESTATE_HEADSETHOOKSWITCH ,"HEADSETHOOKSWITCH"}, + { PHONESTATE_HEADSETVOLUME ,"HEADSETVOLUME" }, + { PHONESTATE_HEADSETGAIN ,"HEADSETGAIN" }, + { PHONESTATE_SUSPEND ,"SUSPEND" }, + { PHONESTATE_RESUME ,"RESUME" }, + { PHONESTATE_DEVSPECIFIC ,"DEVSPECIFIC" }, + { PHONESTATE_REINIT ,"REINIT" }, +#if TAPI_1_1 + { PHONESTATE_CAPSCHANGE ,"CAPSCHANGE" }, + { PHONESTATE_REMOVED ,"REMOVED" }, +#endif + { 0xffffffff ,"" } +}; + +LOOKUP my_far aPhoneStatusFlags[] = +{ + { PHONESTATUSFLAGS_CONNECTED ,"CONNECTED" }, + { PHONESTATUSFLAGS_SUSPENDED ,"SUSPENDED" }, + { 0xffffffff ,"" } +}; + +LOOKUP my_far aStringFormats[] = +{ + { STRINGFORMAT_ASCII ,"ASCII" }, + { STRINGFORMAT_DBCS ,"DBCS" }, + { STRINGFORMAT_UNICODE ,"UNICODE" }, + { STRINGFORMAT_BINARY ,"BINARY" }, + { 0xffffffff ,"" } +}; + + +char *aszLineErrs[] = +{ + "SUCCESS", + "ALLOCATED", + "BADDEVICEID", + "BEARERMODEUNAVAIL", + "inval err code (0x80000004)", // 0x80000004 isn't valid err code + "CALLUNAVAIL", + "COMPLETIONOVERRUN", + "CONFERENCEFULL", + "DIALBILLING", + "DIALDIALTONE", + "DIALPROMPT", + "DIALQUIET", + "INCOMPATIBLEAPIVERSION", + "INCOMPATIBLEEXTVERSION", + "INIFILECORRUPT", + "INUSE", + "INVALADDRESS", // 0x80000010 + "INVALADDRESSID", + "INVALADDRESSMODE", + "INVALADDRESSSTATE", + "INVALAPPHANDLE", + "INVALAPPNAME", + "INVALBEARERMODE", + "INVALCALLCOMPLMODE", + "INVALCALLHANDLE", + "INVALCALLPARAMS", + "INVALCALLPRIVILEGE", + "INVALCALLSELECT", + "INVALCALLSTATE", + "INVALCALLSTATELIST", + "INVALCARD", + "INVALCOMPLETIONID", + "INVALCONFCALLHANDLE", // 0x80000020 + "INVALCONSULTCALLHANDLE", + "INVALCOUNTRYCODE", + "INVALDEVICECLASS", + "INVALDEVICEHANDLE", + "INVALDIALPARAMS", + "INVALDIGITLIST", + "INVALDIGITMODE", + "INVALDIGITS", + "INVALEXTVERSION", + "INVALGROUPID", + "INVALLINEHANDLE", + "INVALLINESTATE", + "INVALLOCATION", + "INVALMEDIALIST", + "INVALMEDIAMODE", + "INVALMESSAGEID", // 0x80000030 + "inval err code (0x80000031)", // 0x80000031 isn't valid err code + "INVALPARAM", + "INVALPARKID", + "INVALPARKMODE", + "INVALPOINTER", + "INVALPRIVSELECT", + "INVALRATE", + "INVALREQUESTMODE", + "INVALTERMINALID", + "INVALTERMINALMODE", + "INVALTIMEOUT", + "INVALTONE", + "INVALTONELIST", + "INVALTONEMODE", + "INVALTRANSFERMODE", + "LINEMAPPERFAILED", // 0x80000040 + "NOCONFERENCE", + "NODEVICE", + "NODRIVER", + "NOMEM", + "NOREQUEST", + "NOTOWNER", + "NOTREGISTERED", + "OPERATIONFAILED", + "OPERATIONUNAVAIL", + "RATEUNAVAIL", + "RESOURCEUNAVAIL", + "REQUESTOVERRUN", + "STRUCTURETOOSMALL", + "TARGETNOTFOUND", + "TARGETSELF", + "UNINITIALIZED", // 0x80000050 + "USERUSERINFOTOOBIG", + "REINIT", + "ADDRESSBLOCKED", + "BILLINGREJECTED", + "INVALFEATURE", + "NOMULTIPLEINSTANCE" + +#if TAPI_2_0 + , + "INVALAGENTID", + "INVALAGENTGROUP", + "INVALPASSWORD", + "INVALAGENTSTATE", + "INVALAGENTACTIVITY", + "DIALVOICEDETECT" +#endif +}; + +char *aszPhoneErrs[] = +{ + "SUCCESS", + "ALLOCATED", + "BADDEVICEID", + "INCOMPATIBLEAPIVERSION", + "INCOMPATIBLEEXTVERSION", + "INIFILECORRUPT", + "INUSE", + "INVALAPPHANDLE", + "INVALAPPNAME", + "INVALBUTTONLAMPID", + "INVALBUTTONMODE", + "INVALBUTTONSTATE", + "INVALDATAID", + "INVALDEVICECLASS", + "INVALEXTVERSION", + "INVALHOOKSWITCHDEV", + "INVALHOOKSWITCHMODE", // 0x90000010 + "INVALLAMPMODE", + "INVALPARAM", + "INVALPHONEHANDLE", + "INVALPHONESTATE", + "INVALPOINTER", + "INVALPRIVILEGE", + "INVALRINGMODE", + "NODEVICE", + "NODRIVER", + "NOMEM", + "NOTOWNER", + "OPERATIONFAILED", + "OPERATIONUNAVAIL", + "inval err code (0x9000001E)", // 0x9000001e isn't valid err code + "RESOURCEUNAVAIL", + "REQUESTOVERRUN", // 0x90000020 + "STRUCTURETOOSMALL", + "UNINITIALIZED", + "REINIT" +}; + +char *aszTapiErrs[] = +{ + "SUCCESS", + "DROPPED", + "NOREQUESTRECIPIENT", + "REQUESTQUEUEFULL", + "INVALDESTADDRESS", + "INVALWINDOWHANDLE", + "INVALDEVICECLASS", + "INVALDEVICEID", + "DEVICECLASSUNAVAIL", + "DEVICEIDUNAVAIL", + "DEVICEINUSE", + "DESTBUSY", + "DESTNOANSWER", + "DESTUNAVAIL", + "UNKNOWNWINHANDLE", + "UNKNOWNREQUESTID", + "REQUESTFAILED", + "REQUESTCANCELLED", + "INVALPOINTER" +}; + +char *aFuncNames[] = +{ + "lineAccept", +#if TAPI_1_1 + "lineAddProvider", +#if TAPI_2_0 + "lineAddProviderW", +#endif +#endif + "lineAddToConference", +#if TAPI_2_0 + "lineAgentSpecific", +#endif + "lineAnswer", + "lineBlindTransfer", +#if TAPI_2_0 + "lineBlindTransferW", +#endif + "lineClose", + "lineCompleteCall", + "lineCompleteTransfer", + "lineConfigDialog", +#if TAPI_2_0 + "lineConfigDialogW", +#endif +#if TAPI_1_1 + "lineConfigDialogEdit", +#if TAPI_2_0 + "lineConfigDialogEditW", +#endif + "lineConfigProvider", +#endif + "lineDeallocateCall", + "lineDevSpecific", + "lineDevSpecificFeature", + "lineDial", +#if TAPI_2_0 + "lineDialW", +#endif + "lineDrop", + "lineForward", +#if TAPI_2_0 + "lineForwardW", +#endif + "lineGatherDigits", +#if TAPI_2_0 + "lineGatherDigitsW", +#endif + "lineGenerateDigits", +#if TAPI_2_0 + "lineGenerateDigitsW", +#endif + "lineGenerateTone", + "lineGetAddressCaps", +#if TAPI_2_0 + "lineGetAddressCapsW", +#endif + "lineGetAddressID", +#if TAPI_2_0 + "lineGetAddressIDW", +#endif + "lineGetAddressStatus", +#if TAPI_2_0 + "lineGetAddressStatusW", +#endif +#if TAPI_2_0 + "lineGetAgentActivityList", + "lineGetAgentActivityListW", + "lineGetAgentCaps", + "lineGetAgentGroupList", + "lineGetAgentStatus", +#endif +#if TAPI_1_1 + "lineGetAppPriority", +#if TAPI_2_0 + "lineGetAppPriorityW", +#endif +#endif + "lineGetCallInfo", +#if TAPI_2_0 + "lineGetCallInfoW", +#endif + "lineGetCallStatus", + "lineGetConfRelatedCalls", +#if TAPI_1_1 + "lineGetCountry", +#if TAPI_2_0 + "lineGetCountryW", +#endif +#endif + "lineGetDevCaps", +#if TAPI_2_0 + "lineGetDevCapsW", +#endif + "lineGetDevConfig", +#if TAPI_2_0 + "lineGetDevConfigW", +#endif + "lineGetIcon", +#if TAPI_2_0 + "lineGetIconW", +#endif + "lineGetID", +#if TAPI_2_0 + "lineGetIDW", +#endif + "lineGetLineDevStatus", +#if TAPI_2_0 + "lineGetLineDevStatusW", + "lineGetMessage", +#endif + "lineGetNewCalls", + "lineGetNumRings", +#if TAPI_1_1 + "lineGetProviderList", +#if TAPI_2_0 + "lineGetProviderListW", +#endif +#endif + "lineGetRequest", +#if TAPI_2_0 + "lineGetRequestW", +#endif + "lineGetStatusMessages", + "lineGetTranslateCaps", +#if TAPI_2_0 + "lineGetTranslateCapsW", +#endif + "lineHandoff", +#if TAPI_2_0 + "lineHandoffW", +#endif + "lineHold", + "lineInitialize", +#if TAPI_2_0 + "lineInitializeEx", + "lineInitializeExW", +#endif + "lineMakeCall", +#if TAPI_2_0 + "lineMakeCallW", +#endif + "lineMonitorDigits", + "lineMonitorMedia", + "lineMonitorTones", + "lineNegotiateAPIVersion", + "lineNegotiateExtVersion", + "lineOpen", +#if TAPI_2_0 + "lineOpenW", +#endif + "linePark", +#if TAPI_2_0 + "lineParkW", +#endif + "linePickup", +#if TAPI_2_0 + "linePickupW", +#endif + "linePrepareAddToConference", +#if TAPI_2_0 + "linePrepareAddToConferenceW", + "lineProxyMessage", + "lineProxyResponse", +#endif + "lineRedirect", +#if TAPI_2_0 + "lineRedirectW", +#endif + "lineRegisterRequestRecipient", +#if TAPI_1_1 + "lineReleaseUserUserInfo", +#endif + "lineRemoveFromConference", +#if TAPI_1_1 + "lineRemoveProvider", +#endif + "lineSecureCall", + "lineSendUserUserInfo", +#if TAPI_2_0 + "lineSetAgentActivity", + "lineSetAgentGroup", + "lineSetAgentState", +#endif +#if TAPI_1_1 + "lineSetAppPriority", +#if TAPI_2_0 + "lineSetAppPriorityW", +#endif +#endif + "lineSetAppSpecific", +#if TAPI_2_0 + "lineSetCallData", +#endif + "lineSetCallParams", + "lineSetCallPrivilege", +#if TAPI_2_0 + "lineSetCallQualityOfService", + "lineSetCallTreatment", +#endif + "lineSetCurrentLocation", + "lineSetDevConfig", +#if TAPI_2_0 + "lineSetDevConfigW", + "lineSetLineDevStatus", +#endif + "lineSetMediaControl", + "lineSetMediaMode", + "lineSetNumRings", + "lineSetStatusMessages", + "lineSetTerminal", + "lineSetTollList", +#if TAPI_2_0 + "lineSetTollListW", +#endif + "lineSetupConference", +#if TAPI_2_0 + "lineSetupConferenceW", +#endif + "lineSetupTransfer", +#if TAPI_2_0 + "lineSetupTransferW", +#endif + "lineShutdown", + "lineSwapHold", + "lineTranslateAddress", +#if TAPI_2_0 + "lineTranslateAddressW", +#endif +#if TAPI_1_1 + "lineTranslateDialog", +#if TAPI_2_0 + "lineTranslateDialogW", +#endif +#endif + "lineUncompleteCall", + "lineUnhold", + "lineUnpark", +#if TAPI_2_0 + "lineUnparkW", +#endif + + "phoneClose", + "phoneConfigDialog", +#if TAPI_2_0 + "phoneConfigDialogW", +#endif + "phoneDevSpecific", + "phoneGetButtonInfo", +#if TAPI_2_0 + "phoneGetButtonInfoW", +#endif + "phoneGetData", + "phoneGetDevCaps", +#if TAPI_2_0 + "phoneGetDevCapsW", +#endif + "phoneGetDisplay", + "phoneGetGain", + "phoneGetHookSwitch", + "phoneGetIcon", +#if TAPI_2_0 + "phoneGetIconW", +#endif + "phoneGetID", +#if TAPI_2_0 + "phoneGetIDW", +#endif + "phoneGetLamp", +#if TAPI_2_0 + "phoneGetMessage", +#endif + "phoneGetRing", + "phoneGetStatus", +#if TAPI_2_0 + "phoneGetStatusW", +#endif + "phoneGetStatusMessages", + "phoneGetVolume", + "phoneInitialize", +#if TAPI_2_0 + "phoneInitializeEx", + "phoneInitializeExW", +#endif + "phoneOpen", + "phoneNegotiateAPIVersion", + "phoneNegotiateExtVersion", + "phoneSetButtonInfo", +#if TAPI_2_0 + "phoneSetButtonInfoW", +#endif + "phoneSetData", + "phoneSetDisplay", + "phoneSetGain", + "phoneSetHookSwitch", + "phoneSetLamp", + "phoneSetRing", + "phoneSetStatusMessages", + "phoneSetVolume", + "phoneShutdown", + + "tapiGetLocationInfo", +#if TAPI_2_0 + "tapiGetLocationInfoW", +#endif + "tapiRequestDrop", + "tapiRequestMakeCall", +#if TAPI_2_0 + "tapiRequestMakeCallW", +#endif + "tapiRequestMediaCall", +#if TAPI_2_0 + "tapiRequestMediaCallW", +#endif + + "Open all lines", + "Open all phones", + "Close handle (comm, etc)", + "Dump buffer contents", + + NULL, + "Default values", + "LINECALLPARAMS", + "LINEFORWARDLIST", + NULL +}; diff --git a/private/tapi/dev/apps/tb/vars.h b/private/tapi/dev/apps/tb/vars.h new file mode 100644 index 000000000..33a072132 --- /dev/null +++ b/private/tapi/dev/apps/tb/vars.h @@ -0,0 +1,177 @@ +/*++ BUILD Version: 0000 // Increment this if a change has global effects + +Copyright (c) 1994-96 Microsoft Corporation + +Module Name: + + vars.h + +Abstract: + + Header file for the TAPI Browser util globals + +Author: + + Dan Knudson (DanKn) 23-Oct-1994 + +Revision History: + +--*/ + + +#ifdef WIN32 +#define my_far +#else +#define my_far _far +#endif + +extern PMYWIDGET aWidgets; + +extern FILE *hLogFile; +extern HANDLE ghInst; +extern HWND ghwndMain, ghwndEdit, ghwndList1, ghwndList2; +extern BOOL bShowParams; +extern BOOL gbDeallocateCall; +extern BOOL gbDisableHandleChecking; +extern LPVOID pBigBuf; +extern DWORD dwBigBufSize; +extern DWORD dwNumPendingMakeCalls; +extern DWORD dwNumPendingDrops; +extern DWORD gdwNumLineDevs; +extern DWORD gdwNumPhoneDevs; +extern BOOL bDumpParams; +extern BOOL bTimeStamp; +extern DWORD bNukeIdleMonitorCalls; +extern DWORD bNukeIdleOwnedCalls; +extern DWORD dwDumpStructsFlags; + +extern LPLINECALLPARAMS lpCallParams; + +#if TAPI_2_0 +extern BOOL gbWideStringParams; +extern LPLINECALLPARAMS lpCallParamsW; +#endif + +extern DWORD aUserButtonFuncs[MAX_USER_BUTTONS]; +extern char aUserButtonsText[MAX_USER_BUTTONS][MAX_USER_BUTTON_TEXT_SIZE]; + +extern PMYLINEAPP pLineAppSel; +extern PMYLINE pLineSel; +extern PMYCALL pCallSel, pCallSel2; +extern PMYPHONEAPP pPhoneAppSel; +extern PMYPHONE pPhoneSel; + +extern char my_far szDefAppName[]; +extern char my_far szDefUserUserInfo[]; +extern char my_far szDefDestAddress[]; +extern char my_far szDefLineDeviceClass[]; +extern char my_far szDefPhoneDeviceClass[]; + +extern char far *lpszDefAppName; +extern char far *lpszDefUserUserInfo; +extern char far *lpszDefDestAddress; +extern char far *lpszDefLineDeviceClass; +extern char far *lpszDefPhoneDeviceClass; + +extern char my_far szTab[]; +extern char my_far szCurrVer[]; + +// help extern char my_far szTapiHlp[]; +// help extern char my_far szTspiHlp[]; + +extern DWORD dwDefAddressID; +extern DWORD dwDefLineAPIVersion; +extern DWORD dwDefBearerMode; +extern DWORD dwDefCountryCode; +extern DWORD dwDefLineDeviceID; +extern DWORD dwDefLineExtVersion; +extern DWORD dwDefMediaMode; +extern DWORD dwDefLinePrivilege; +extern DWORD dwDefPhoneAPIVersion; +extern DWORD dwDefPhoneDeviceID; +extern DWORD dwDefPhoneExtVersion; +extern DWORD dwDefPhonePrivilege; + +#if TAPI_2_0 +extern HANDLE ghCompletionPort; +#endif + +extern char aAscii[]; + +extern LOOKUP my_far aButtonFunctions[]; +extern LOOKUP my_far aButtonModes[]; +extern LOOKUP my_far aButtonStates[]; +extern LOOKUP my_far aHookSwitchDevs[]; +extern LOOKUP my_far aHookSwitchModes[]; +extern LOOKUP my_far aLampModes[]; +extern LOOKUP my_far aPhonePrivileges[]; +extern LOOKUP my_far aPhoneStatusFlags[]; +extern LOOKUP my_far aPhoneStates[]; + +extern LOOKUP my_far aStringFormats[]; +extern LOOKUP my_far aAddressCapFlags[]; +extern LOOKUP my_far aAddressFeatures[]; +extern LOOKUP my_far aAgentStates[]; +extern LOOKUP my_far aAgentStatus[]; +extern LOOKUP my_far aAddressModes[]; +extern LOOKUP my_far aAddressSharing[]; +extern LOOKUP my_far aAddressStates[]; +extern LOOKUP my_far aAnswerModes[]; +extern LOOKUP my_far aAPIVersions[]; +extern LOOKUP my_far aBearerModes[]; +extern LOOKUP my_far aBusyModes[]; +extern LOOKUP my_far aCallComplConds[]; +extern LOOKUP my_far aCallComplModes[]; +extern LOOKUP my_far aCallerIDFlags[]; +extern LOOKUP my_far aCallFeatures[]; +extern LOOKUP my_far aCallFeatures2[]; +extern LOOKUP my_far aCallInfoStates[]; +extern LOOKUP my_far aCallOrigins[]; +extern LOOKUP my_far aCallParamFlags[]; +extern LOOKUP my_far aCallPrivileges[]; +extern LOOKUP my_far aCallReasons[]; +extern LOOKUP my_far aCallSelects[]; +extern LOOKUP my_far aCallStates[]; +extern LOOKUP my_far aCallTreatments[]; +extern LOOKUP my_far aCardOptions[]; +extern LOOKUP my_far aConnectedModes[]; +extern LOOKUP my_far aDevCapsFlags[]; +extern LOOKUP my_far aDialToneModes[]; +extern LOOKUP my_far aDigitModes[]; +extern LOOKUP my_far aDisconnectModes[]; +extern LOOKUP my_far aForwardModes[]; +extern LOOKUP my_far aGatherTerms[]; +extern LOOKUP my_far aGenerateTerms[]; +extern LOOKUP my_far aInitExOptions[]; +extern LOOKUP my_far aLineDevStatusFlags[]; +extern LOOKUP my_far aLineFeatures[]; +extern LOOKUP my_far aLineOpenOptions[]; +extern LOOKUP my_far aLineRoamModes[]; +extern LOOKUP my_far aLineStates[]; +extern LOOKUP my_far aLocationOptions[]; +extern LOOKUP my_far aMediaControls[]; +extern LOOKUP my_far aMediaModes[]; +extern LOOKUP my_far aOfferingModes[]; +extern LOOKUP my_far aParkModes[]; +extern LOOKUP my_far aProxyRequests[]; +extern LOOKUP my_far aRemoveFromConfCaps[]; +extern LOOKUP my_far aRequestModes[]; +extern LOOKUP my_far aRequestModes2[]; +extern LOOKUP my_far aSpecialInfo[]; +extern LOOKUP my_far aTerminalModes[]; +extern LOOKUP my_far aTollListOptions[]; +extern LOOKUP my_far aToneModes[]; +extern LOOKUP my_far aTransferModes[]; +extern LOOKUP my_far aTranslateOptions[]; +extern LOOKUP my_far aTranslateResults[]; + +#if TAPI_2_0 +extern LOOKUP my_far aPhoneFeatures[]; +#endif + +extern char *aszLineErrs[]; + +extern char *aszPhoneErrs[]; +extern char *aszTapiErrs[]; + +extern char *aFuncNames[]; diff --git a/private/tapi/dev/apps/tb/widget.c b/private/tapi/dev/apps/tb/widget.c new file mode 100644 index 000000000..1405c3e72 --- /dev/null +++ b/private/tapi/dev/apps/tb/widget.c @@ -0,0 +1,742 @@ +/*++ BUILD Version: 0000 // Increment this if a change has global effects + +Copyright (c) 1994-95 Microsoft Corporation + +Module Name: + + widget.c + +Abstract: + + Widget creation/management/deletion support for TAPI Browser util. + +Author: + + Dan Knudson (DanKn) 23-Aug-1994 + +Revision History: + +--*/ + + +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <ctype.h> +#include <malloc.h> +#include "tb.h" +#include "vars.h" + + + +void +UpdateWidgetList( + void + ) +{ + int i; + LONG lSel = SendMessage (ghwndList1, LB_GETCURSEL, 0, 0); + PMYWIDGET pWidget = aWidgets, pSelWidget = (PMYWIDGET) NULL; + + + if (lSel != LB_ERR) + { + pSelWidget = (PMYWIDGET) SendMessage( + ghwndList1, + LB_GETITEMDATA, + (WPARAM) lSel, + 0 + ); + } + + SendMessage (ghwndList1, LB_RESETCONTENT, 0, 0); + + for (i = 0; pWidget; i++) + { + char buf[64]; + + + switch (pWidget->dwType) + { + case WT_LINEAPP: + + sprintf (buf, "LineApp=x%lx", ((PMYLINEAPP) pWidget)->hLineApp); + break; + + case WT_LINE: + { + PMYLINE pLine = (PMYLINE) pWidget; + + + sprintf( + buf, + " Line=x%lx id=%ld ", + pLine->hLine, + pLine->dwDevID + ); + + if (pLine->dwPrivileges & LINECALLPRIVILEGE_NONE) + { + strcat (buf, "DialOut"); + } + else + { + if (pLine->dwPrivileges & LINECALLPRIVILEGE_OWNER) + { + strcat (buf, "DialInOut"); + } + + if (pLine->dwPrivileges & LINECALLPRIVILEGE_MONITOR) + { + strcat (buf, " Monitor"); + } + } + + if (pLine->dwPrivileges & LINEOPENOPTION_PROXY) + { + strcat (buf, " Proxy"); + } + + break; + } + case WT_CALL: + { + PMYCALL pCall = (PMYCALL) pWidget; + + + if (pCall->hCall) + { + int i; + + for (i = 0; aCallStates[i].dwVal != 0xffffffff; i++) + { + if (pCall->dwCallState == aCallStates[i].dwVal) + { + break; + } + } + + sprintf( + buf, + " Call=x%lx %s %s", + pCall->hCall, + aCallStates[i].lpszVal, + (pCall->bMonitor ? "Monitor" : "Owner") + ); + } + else + { + strcpy (buf, " <MakeCall reply pending>"); + } + + break; + } + case WT_PHONEAPP: + + sprintf (buf, "PhoneApp=x%lx", ((PMYPHONEAPP) pWidget)->hPhoneApp); + break; + + case WT_PHONE: + + sprintf( + buf, + " Phone=x%lx id=%ld", + ((PMYPHONE) pWidget)->hPhone, + ((PMYPHONE) pWidget)->dwDevID + ); + + break; + } + + SendMessage (ghwndList1, LB_INSERTSTRING, (WPARAM) -1, (LPARAM) buf); + SendMessage (ghwndList1, LB_SETITEMDATA, (WPARAM) i, (LPARAM) pWidget); + + pWidget = pWidget->pNext; + } + + + // + // Restore selection if appropriate + // + + if ((lSel != LB_ERR) && ((lSel = (LONG) GetWidgetIndex (pSelWidget)) >= 0)) + { + SendMessage (ghwndList1, LB_SETCURSEL, (WPARAM) lSel, 0); + } +} + + +void +InsertWidgetInList( + PMYWIDGET pNewWidget, + PMYWIDGET pWidgetInsertBefore + ) +{ + pNewWidget->pNext = pWidgetInsertBefore; + + if ((aWidgets == NULL) || (pWidgetInsertBefore == aWidgets)) + { + aWidgets = pNewWidget; + } + else + { + PMYWIDGET pPrevWidget = aWidgets; + + + while (pPrevWidget->pNext && + (pPrevWidget->pNext != pWidgetInsertBefore)) + { + pPrevWidget = pPrevWidget->pNext; + } + + pPrevWidget->pNext = pNewWidget; + } + + UpdateWidgetList(); +} + + +BOOL +RemoveWidgetFromList( + PMYWIDGET pWidgetToRemove + ) +{ + if (aWidgets == NULL) + { + goto RemoveWidgetFromList_error; + } + + if (pWidgetToRemove == aWidgets) + { + aWidgets = pWidgetToRemove->pNext; + } + else + { + PMYWIDGET pPrevWidget = aWidgets; + + + while (pPrevWidget->pNext && (pPrevWidget->pNext != pWidgetToRemove)) + { + pPrevWidget = pPrevWidget->pNext; + } + + if (pPrevWidget->pNext == NULL) + { + goto RemoveWidgetFromList_error; + } + + pPrevWidget->pNext = pWidgetToRemove->pNext; + } + + free (pWidgetToRemove); + + UpdateWidgetList(); + + return TRUE; + +RemoveWidgetFromList_error: + + ShowStr ("Error: pWidget x%lx not found in list", pWidgetToRemove); + + return FALSE; +} + + +PMYLINEAPP +AllocLineApp( + void + ) +{ + PMYLINEAPP pNewLineApp = (PMYLINEAPP) malloc (sizeof(MYLINEAPP)); + + + if (pNewLineApp) + { + PMYWIDGET pWidget = aWidgets; + + + memset (pNewLineApp, 0, sizeof(MYLINEAPP)); + pNewLineApp->Widget.dwType = WT_LINEAPP; + + + // + // Insert new line app after all existing line apps, lines, & calls, + // and before any existing phone apps + // + + while (pWidget && (pWidget->dwType != WT_PHONEAPP)) + { + // assert (pWidget->dwType != WT_PHONE) + + pWidget = pWidget->pNext; + } + + InsertWidgetInList ((PMYWIDGET) pNewLineApp, pWidget); + } + + return pNewLineApp; +} + + +PMYLINEAPP +GetLineApp( + HLINEAPP hLineApp + ) +{ + PMYWIDGET pWidget = aWidgets; + + + while (pWidget) + { + if (pWidget->dwType == WT_LINEAPP) + { + PMYLINEAPP pLineApp = (PMYLINEAPP) pWidget; + + + if (pLineApp->hLineApp == hLineApp) + { + break; + } + } + + pWidget = pWidget->pNext; + } + + return ((PMYLINEAPP) pWidget); +} + + +VOID +FreeLineApp( + PMYLINEAPP pLineApp + ) +{ + PMYWIDGET pWidget = pLineApp->Widget.pNext; + + + // BUGBUG chk validity of pLineApp + + if (RemoveWidgetFromList ((PMYWIDGET) pLineApp)) + { + while (pWidget && + (pWidget->dwType != WT_LINEAPP) && + (pWidget->dwType != WT_PHONEAPP)) + { + PMYWIDGET pWidget2 = pWidget->pNext; + + + // assert (pWidget->dwType != WT_PHONE) + + RemoveWidgetFromList (pWidget); + pWidget = pWidget2; + } + } +} + + +PMYLINE +AllocLine( + PMYLINEAPP pLineApp + ) +{ + PMYLINE pNewLine = (PMYLINE) malloc (sizeof(MYLINE)); + + + if (pNewLine) + { + PMYWIDGET pWidget = (PMYWIDGET) pLineApp->Widget.pNext; + + + memset (pNewLine, 0, sizeof(MYLINE)); + pNewLine->Widget.dwType = WT_LINE; + pNewLine->pLineApp = pLineApp; + + + // + // Insert new line after all existing lines & calls on specfied + // line app, but before the next line app or phone app + // + + while (pWidget && + (pWidget->dwType != WT_LINEAPP) && + (pWidget->dwType != WT_PHONEAPP)) + { + pWidget = pWidget->pNext; + } + + InsertWidgetInList ((PMYWIDGET) pNewLine, pWidget); + } + + return pNewLine; +} + + +PMYLINE +GetLine( + HLINE hLine + ) +{ + PMYWIDGET pWidget = aWidgets; + + + while (pWidget) + { + if (pWidget->dwType == WT_LINE) + { + PMYLINE pLine = (PMYLINE) pWidget; + + + if (pLine->hLine == hLine) + { + break; + } + } + + pWidget = pWidget->pNext; + } + + return ((PMYLINE) pWidget); +} + + +VOID +FreeLine( + PMYLINE pLine + ) +{ + PMYWIDGET pWidget = pLine->Widget.pNext; + + + if (RemoveWidgetFromList ((PMYWIDGET) pLine)) + { + while (pWidget && + (pWidget->dwType == WT_CALL)) + { + PMYWIDGET pWidget2 = pWidget->pNext; + + + RemoveWidgetFromList (pWidget); + pWidget = pWidget2; + } + } +} + + +PMYCALL +AllocCall( + PMYLINE pLine + ) +{ + PMYCALL pNewCall = (PMYCALL) malloc (sizeof(MYCALL)); + + + if (pNewCall) + { + PMYWIDGET pWidget = (PMYWIDGET) pLine->Widget.pNext; + + + memset (pNewCall, 0, sizeof(MYCALL)); + pNewCall->Widget.dwType = WT_CALL; + pNewCall->pLine = pLine; + + // + // Insert new call after all existing calls on specified line, + // and before the next line, line app, or phone app + // + + while (pWidget && (pWidget->dwType == WT_CALL)) + { + pWidget = pWidget->pNext; + } + + InsertWidgetInList ((PMYWIDGET) pNewCall, pWidget); + } + + return pNewCall; +} + + +PMYCALL +GetCall( + HCALL hCall + ) +{ + PMYWIDGET pWidget = aWidgets; + + + while (pWidget) + { + if (pWidget->dwType == WT_CALL) + { + PMYCALL pCall = (PMYCALL) pWidget; + + + if (pCall->hCall == hCall) + { + break; + } + } + + pWidget = pWidget->pNext; + } + + return ((PMYCALL) pWidget); +} + + +VOID +FreeCall( + PMYCALL pCall + ) +{ + // BUGBUG chk validity of pCall + + RemoveWidgetFromList ((PMYWIDGET) pCall); +} + + +VOID +MoveCallToLine( + PMYCALL pCall, + HLINE hLine + ) +{ + // + // This func gets called when a user has invoked an op that requires + // creating a call, and we did an AllocCall() based on the currently + // selected line/calls, but in the call params dlg the user overrode + // the default hLine/hCall, and so we need to move the call widget + // in the global list from under the orig specified line widget to + // the line widget corresponding to the specified "hLine". (Note that + // this is not a simple matter of free-ing & realloc-ing another call, + // since TAPI saved the &pCall->hCall.) + // + + PMYWIDGET pWidget = aWidgets; + + + // + // Remove call widget from the global list + // + + while (pWidget->pNext != (PMYWIDGET) pCall) + { + pWidget = pWidget->pNext; + } + + pWidget->pNext = pCall->Widget.pNext; + + + // + // Find the right place to insert it in list, then insert it + // + + pWidget = (PMYWIDGET) GetLine (hLine); + + pCall->pLine = (PMYLINE) pWidget; + + while (pWidget->pNext && (pWidget->pNext->dwType == WT_CALL)) + { + pWidget = pWidget->pNext; + } + + pCall->Widget.pNext = pWidget->pNext; + pWidget->pNext = (PMYWIDGET) pCall; + + UpdateWidgetList(); +} + + +PMYPHONEAPP +AllocPhoneApp( + void + ) +{ + PMYPHONEAPP pNewPhoneApp = (PMYPHONEAPP) malloc (sizeof(MYPHONEAPP)); + + + if (pNewPhoneApp) + { + PMYWIDGET pWidget = aWidgets; + + + memset (pNewPhoneApp, 0, sizeof(MYPHONEAPP)); + pNewPhoneApp->Widget.dwType = WT_PHONEAPP; + + + // + // Insert new phone app at end of list + // + + InsertWidgetInList ((PMYWIDGET) pNewPhoneApp, (PMYWIDGET) NULL); + } + + return pNewPhoneApp; +} + + +PMYPHONEAPP +GetPhoneApp( + HPHONEAPP hPhoneApp + ) +{ + PMYWIDGET pWidget = aWidgets; + + + while (pWidget) + { + if (pWidget->dwType == WT_PHONEAPP) + { + PMYPHONEAPP pPhoneApp = (PMYPHONEAPP) pWidget; + + + if (pPhoneApp->hPhoneApp == hPhoneApp) + { + break; + } + } + + pWidget = pWidget->pNext; + } + + return ((PMYPHONEAPP) pWidget); +} + + +VOID +FreePhoneApp( + PMYPHONEAPP pPhoneApp + ) +{ + PMYWIDGET pWidget = pPhoneApp->Widget.pNext; + + + if (RemoveWidgetFromList ((PMYWIDGET) pPhoneApp)) + { + while (pWidget && (pWidget->dwType == WT_PHONE)) + { + PMYWIDGET pWidget2 = pWidget->pNext; + + + RemoveWidgetFromList (pWidget); + pWidget = pWidget2; + } + } +} + + +PMYPHONE +AllocPhone( + PMYPHONEAPP pPhoneApp + ) +{ + PMYPHONE pNewPhone = (PMYPHONE) malloc (sizeof(MYPHONE)); + + + if (pNewPhone) + { + PMYWIDGET pWidget = (PMYWIDGET) pPhoneApp->Widget.pNext; + + + memset (pNewPhone, 0, sizeof(MYPHONE)); + pNewPhone->Widget.dwType = WT_PHONE; + pNewPhone->pPhoneApp = pPhoneApp; + + + // + // Insert new phone after all phones on the specified phone app, + // and before the next phone app + // + + while (pWidget && (pWidget->dwType == WT_PHONE)) + { + pWidget = pWidget->pNext; + } + + InsertWidgetInList ((PMYWIDGET) pNewPhone, pWidget); + } + + return pNewPhone; +} + + +PMYPHONE +GetPhone( + HPHONE hPhone + ) +{ + PMYWIDGET pWidget = aWidgets; + + + while (pWidget) + { + if (pWidget->dwType == WT_PHONE) + { + PMYPHONE pPhone = (PMYPHONE) pWidget; + + + if (pPhone->hPhone == hPhone) + { + break; + } + } + + pWidget = pWidget->pNext; + } + + return ((PMYPHONE) pWidget); +} + + +VOID +FreePhone( + PMYPHONE pPhone + ) +{ + RemoveWidgetFromList ((PMYWIDGET) pPhone); +} + + +int +GetWidgetIndex( + PMYWIDGET pWidget + ) +{ + int i; + PMYWIDGET pWidget2 = aWidgets; + + + for (i = 0; (pWidget2 && (pWidget != pWidget2)); i++) + { + pWidget2 = pWidget2->pNext; + } + + if (!pWidget2) + { + i = -1; + } + + return i; +} + + +void +SelectWidget( + PMYWIDGET pWidget + ) +{ + int i; + PMYWIDGET pWidget2 = aWidgets; + + + for (i = 0; pWidget2; i++) + { + if (pWidget == pWidget2) + { + SendMessage (ghwndList1, LB_SETCURSEL, (WPARAM) i, 0); + break; + } + + pWidget2 = pWidget2->pNext; + } +} diff --git a/private/tapi/dev/apps/tb/win31.mak b/private/tapi/dev/apps/tb/win31.mak new file mode 100644 index 000000000..95475aeb1 --- /dev/null +++ b/private/tapi/dev/apps/tb/win31.mak @@ -0,0 +1,39 @@ +!ifndef TAPI_1_1 +TAPI_1_1 = 0 +!endif + +!ifndef MYDEBUG +MYDEBUG = 0 +!endif + +!if $(TAPI_1_1) +TAPI_VER_FLAGS = -DTAPI_1_1 +TAPILIB = ..\..\lib\i386\tapi.lib +TAPIINC = -I..\..\inc +TARGET = ..\..\lib\i386\tb1416.exe +!else +TAPI_VER_FLAGS = +TAPILIB = ..\..\lib\tapi10\tapi.lib +TAPIINC = -I..\..\inc\tapi10 +TARGET = $(BASEDIR)\public\sdk\lib\i386\tb13.exe +!endif + +!if $(MYDEBUG) +C_FLAGS = -AL -G2s -W3 -GA -GEf -Zp /Od /Oi /Zi +!else +C_FLAGS = -AL -G2s -W3 -GA -GEf -Zp /Od /Oi +!endif + + +OBJS=ui.obj vars.obj tb.obj tb2.obj widget.obj + +all : $(TARGET) + +.c.obj: + cl -c $(TAPI_VER_FLAGS) $(TAPIINC) $(C_FLAGS) $*.c + +$(TARGET) : $(OBJS) tb.def tb.rc + rc -r -dTB_13=1 $(TAPI_VER_FLAGS) tb.rc + link $(OBJS),$(TARGET),tb.map,libw.lib /MAP:FULL /COD /NOD:llibce llibcew commdlg $(TAPILIB),tb.def + rc -k tb.res $(TARGET) + mapsym tb |