line.c 49.8 KB
Newer Older
1 2 3 4
/*
 * TAPI32 line services
 *
 * Copyright 1999  Andreas Mohr
5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 20 21 22
 */

#include <string.h>
#include <stdlib.h>
23
#include <stdarg.h>
24
#include <stdio.h>
25
#include "windef.h"
26
#include "winbase.h"
27
#include "wingdi.h"
28
#include "winreg.h"
29
#include "winnls.h"
30
#include "winerror.h"
31
#include "objbase.h"
32
#include "tapi.h"
33
#include "wine/debug.h"
34

35
WINE_DEFAULT_DEBUG_CHANNEL(tapi);
36

37 38 39 40 41 42 43 44 45
/* registry keys */
static const char szCountrylistKey[] =
    "Software\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Country List";
static const char szLocationsKey[] =
    "Software\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Locations";
static const char szCardsKey[] =
    "Software\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Cards";


46 47 48
/***********************************************************************
 *		lineAccept (TAPI32.@)
 */
49 50
DWORD WINAPI lineAccept(HCALL hCall, LPCSTR lpsUserUserInfo, DWORD dwSize)
{
51
    FIXME("(%p, %s, %d): stub.\n", hCall, lpsUserUserInfo, dwSize);
52 53 54
    return 1;
}

55
/***********************************************************************
56
 *		lineAddProviderA (TAPI32.@)
57
 */
58
DWORD WINAPI lineAddProviderA(LPCSTR lpszProviderName, HWND hwndOwner, LPDWORD lpdwPermanentProviderID)
59
{
60
    FIXME("(%s, %p, %p): stub.\n", lpszProviderName, hwndOwner, lpdwPermanentProviderID);
61 62 63 64 65 66 67 68 69 70
    return LINEERR_OPERATIONFAILED;
}

/***********************************************************************
 *		lineAddProviderW (TAPI32.@)
 */
DWORD WINAPI lineAddProviderW(LPCWSTR lpszProviderName, HWND hwndOwner, LPDWORD lpdwPermanentProviderID)
{
    FIXME("(%s, %p, %p): stub.\n", wine_dbgstr_w(lpszProviderName), hwndOwner, lpdwPermanentProviderID);
    return LINEERR_OPERATIONFAILED;
71
}
72

73 74 75
/***********************************************************************
 *		lineAddToConference (TAPI32.@)
 */
76 77
DWORD WINAPI lineAddToConference(HCALL hConfCall, HCALL hConsultCall)
{
78
    FIXME("(%p, %p): stub.\n", hConfCall, hConsultCall);
79 80 81
    return 1;
}

82 83 84
/***********************************************************************
 *		lineAnswer (TAPI32.@)
 */
85 86
DWORD WINAPI lineAnswer(HCALL hCall, LPCSTR lpsUserUserInfo, DWORD dwSize)
{
87
    FIXME("(%p, %s, %d): stub.\n", hCall, lpsUserUserInfo, dwSize);
88
    return 1;
89
}
90

91 92 93
/***********************************************************************
 *		lineBlindTransfer (TAPI32.@)
 */
94
DWORD WINAPI lineBlindTransferA(HCALL hCall, LPCSTR lpszDestAddress, DWORD dwCountryCode)
95
{
96
    FIXME("(%p, %s, %08x): stub.\n", hCall, lpszDestAddress, dwCountryCode);
97
    return 1;
98
}
99

100 101 102
/***********************************************************************
 *		lineClose (TAPI32.@)
 */
103 104
DWORD WINAPI lineClose(HLINE hLine)
{
105
    FIXME("(%p): stub.\n", hLine);
106
    return 0;
107
}
108

109 110 111
/***********************************************************************
 *		lineCompleteCall (TAPI32.@)
 */
112 113
DWORD WINAPI lineCompleteCall(HCALL hCall, LPDWORD lpdwCompletionID, DWORD dwCompletionMode, DWORD dwMessageID)
{
114
    FIXME("(%p, %p, %08x, %08x): stub.\n", hCall, lpdwCompletionID, dwCompletionMode, dwMessageID);
115
    return 1;
116
}
117

118 119 120
/***********************************************************************
 *		lineCompleteTransfer (TAPI32.@)
 */
121 122
DWORD WINAPI lineCompleteTransfer(HCALL hCall, HCALL hConsultCall, LPHCALL lphConfCall, DWORD dwTransferMode)
{
123
    FIXME("(%p, %p, %p, %08x): stub.\n", hCall, hConsultCall, lphConfCall, dwTransferMode);
124 125 126
    return 1;
}

127 128 129
/***********************************************************************
 *		lineConfigDialog (TAPI32.@)
 */
130
DWORD WINAPI lineConfigDialogA(DWORD dwDeviceID, HWND hwndOwner, LPCSTR lpszDeviceClass)
131
{
132
    FIXME("(%08x, %p, %s): stub.\n", dwDeviceID, hwndOwner, lpszDeviceClass);
133
    return 0;
134
}
135

136 137 138
/***********************************************************************
 *		lineConfigDialogEdit (TAPI32.@)
 */
139
DWORD WINAPI lineConfigDialogEditA(DWORD dwDeviceID, HWND hwndOwner, LPCSTR lpszDeviceClass, LPVOID const lpDeviceConfigIn, DWORD dwSize, LPVARSTRING lpDeviceConfigOut)
140
{
141
    FIXME("stub.\n");
142
    return 0;
143
}
144

145 146 147
/***********************************************************************
 *		lineConfigProvider (TAPI32.@)
 */
148 149
DWORD WINAPI lineConfigProvider(HWND hwndOwner, DWORD dwPermanentProviderID)
{
150
    FIXME("(%p, %08x): stub.\n", hwndOwner, dwPermanentProviderID);
151 152 153
    return 0;
}

154 155 156
/***********************************************************************
 *		lineDeallocateCall (TAPI32.@)
 */
157 158
DWORD WINAPI lineDeallocateCall(HCALL hCall)
{
159
    FIXME("(%p): stub.\n", hCall);
160 161 162
    return 0;
}

163 164 165
/***********************************************************************
 *		lineDevSpecific (TAPI32.@)
 */
166 167
DWORD WINAPI lineDevSpecific(HLINE hLine, DWORD dwAddressId, HCALL hCall, LPVOID lpParams, DWORD dwSize)
{
168
    FIXME("(%p, %08x, %p, %p, %d): stub.\n", hLine, dwAddressId, hCall, lpParams, dwSize);
169
    return 1;
170
}
171

172 173 174
/***********************************************************************
 *		lineDevSpecificFeature (TAPI32.@)
 */
175 176
DWORD WINAPI lineDevSpecificFeature(HLINE hLine, DWORD dwFeature, LPVOID lpParams, DWORD dwSize)
{
177
    FIXME("(%p, %08x, %p, %d): stub.\n", hLine, dwFeature, lpParams, dwSize);
178 179 180
    return 1;
}

181 182 183
/***********************************************************************
 *		lineDial (TAPI32.@)
 */
184
DWORD WINAPI lineDialA(HCALL hCall, LPCSTR lpszDestAddress, DWORD dwCountryCode)
185
{
186
    FIXME("(%p, %s, %08x): stub.\n", hCall, lpszDestAddress, dwCountryCode);
187 188
    return 1;
}
189 190 191

/***********************************************************************
 *		lineDrop (TAPI32.@)
192
 */
193 194
DWORD WINAPI lineDrop(HCALL hCall, LPCSTR lpsUserUserInfo, DWORD dwSize)
{
195
    FIXME("(%p, %s, %08x): stub.\n", hCall, lpsUserUserInfo, dwSize);
196 197 198
    return 1;
}

199 200 201
/***********************************************************************
 *		lineForward (TAPI32.@)
 */
202
DWORD WINAPI lineForwardA(HLINE hLine, DWORD bAllAddress, DWORD dwAddressID, LPLINEFORWARDLIST lpForwardList, DWORD dwNumRingsNoAnswer, LPHCALL lphConsultCall, LPLINECALLPARAMS lpCallParams)
203
{
204
    FIXME("stub.\n");
205
    return 1;
206 207 208 209
}

/***********************************************************************
 *		lineGatherDigits (TAPI32.@)
210
 */
211
DWORD WINAPI lineGatherDigitsA(HCALL hCall, DWORD dwDigitModes, LPSTR lpsDigits, DWORD dwNumDigits, LPCSTR lpszTerminationDigits, DWORD dwFirstDigitTimeout, DWORD dwInterDigitTimeout)
212
{
213
    FIXME("stub.\n");
214 215 216
    return 0;
}

217 218 219
/***********************************************************************
 *		lineGenerateDigits (TAPI32.@)
 */
220
DWORD WINAPI lineGenerateDigitsA(HCALL hCall, DWORD dwDigitModes, LPCSTR lpszDigits, DWORD dwDuration)
221
{
222
    FIXME("(%p, %08x, %s, %d): stub.\n", hCall, dwDigitModes, lpszDigits, dwDuration);
223 224 225
    return 0;
}

226 227 228
/***********************************************************************
 *		lineGenerateTone (TAPI32.@)
 */
229 230
DWORD WINAPI lineGenerateTone(HCALL hCall, DWORD dwToneMode, DWORD dwDuration, DWORD dwNumTones, LPLINEGENERATETONE lpTones)
{
231
    FIXME("(%p, %08x, %d, %d, %p): stub.\n", hCall, dwToneMode, dwDuration, dwNumTones, lpTones);
232
    return 0;
233
}
234

235 236 237
/***********************************************************************
 *		lineGetAddressCaps (TAPI32.@)
 */
238
DWORD WINAPI lineGetAddressCapsA(HLINEAPP hLineApp, DWORD dwDeviceID, DWORD dwAddressID, DWORD dwAPIVersion, DWORD dwExtVersion, LPLINEADDRESSCAPS lpAddressCaps)
239
{
240
    FIXME("(%p, %08x, %08x, %08x, %08x, %p): stub.\n", hLineApp, dwDeviceID, dwAddressID, dwAPIVersion, dwExtVersion, lpAddressCaps);
241 242 243
    return 0;
}

244 245 246
/***********************************************************************
 *		lineGetAddressID (TAPI32.@)
 */
247
DWORD WINAPI lineGetAddressIDA(HLINE hLine, LPDWORD lpdwAddressID, DWORD dwAddressMode, LPCSTR lpsAddress, DWORD dwSize)
248
{
249
    FIXME("%p, %p, %08x, %s, %d): stub.\n", hLine, lpdwAddressID, dwAddressMode, lpsAddress, dwSize);
250 251 252
    return 0;
}

253 254 255
/***********************************************************************
 *		lineGetAddressStatus (TAPI32.@)
 */
256
DWORD WINAPI lineGetAddressStatusA(HLINE hLine, DWORD dwAddressID, LPLINEADDRESSSTATUS lpAddressStatus)
257
{
258
    FIXME("(%p, %08x, %p): stub.\n", hLine, dwAddressID, lpAddressStatus);
259
    return 0;
260
}
261

262 263 264
/***********************************************************************
 *		lineGetAppPriority (TAPI32.@)
 */
265
DWORD WINAPI lineGetAppPriorityA(LPCSTR lpszAppFilename, DWORD dwMediaMode, LPLINEEXTENSIONID const lpExtensionID, DWORD dwRequestMode, LPVARSTRING lpExtensionName, LPDWORD lpdwPriority)
266
{
267
    FIXME("(%s, %08x, %p, %08x, %p, %p): stub.\n", lpszAppFilename, dwMediaMode, lpExtensionID, dwRequestMode, lpExtensionName, lpdwPriority);
268
    return 0;
269
}
270

271 272 273
/***********************************************************************
 *		lineGetCallInfo (TAPI32.@)
 */
274
DWORD WINAPI lineGetCallInfoA(HCALL hCall, LPLINECALLINFO lpCallInfo)
275
{
276
    FIXME("(%p, %p): stub.\n", hCall, lpCallInfo);
277 278 279
    return 0;
}

280 281 282
/***********************************************************************
 *		lineGetCallStatus (TAPI32.@)
 */
283 284
DWORD WINAPI lineGetCallStatus(HCALL hCall, LPLINECALLSTATUS lpCallStatus)
{
285
    FIXME("(%p, %p): stub.\n", hCall, lpCallStatus);
286 287 288
    return 0;
}

289 290 291
/***********************************************************************
 *		lineGetConfRelatedCalls (TAPI32.@)
 */
292 293
DWORD WINAPI lineGetConfRelatedCalls(HCALL hCall, LPLINECALLLIST lpCallList)
{
294
    FIXME("(%p, %p): stub.\n", hCall, lpCallList);
295
    return 0;
296
}
297

298 299 300 301 302
typedef struct tagTAPI_CountryInfo
{
    DWORD  dwCountryID;
    DWORD  dwCountryCode;
    LPSTR  lpCountryName;
303 304 305
    LPSTR  lpSameAreaRule;
    LPSTR  lpLongDistanceRule;
    LPSTR  lpInternationalRule;
306 307
} TAPI_CountryInfo;

308 309 310
/***********************************************************************
 *		lineGetCountry (TAPI32.@)
 */
311
DWORD WINAPI lineGetCountryA(DWORD dwCountryID, DWORD dwAPIVersion, LPLINECOUNTRYLIST lpLineCountryList)
312
{
313
    DWORD dwAvailSize, dwOffset, i, num_countries, max_subkey_len;
314
    LPLINECOUNTRYENTRY lpLCE;
315 316
    HKEY hkey;
    char *subkey_name;
317

318
    if(!lpLineCountryList) {
319
	TRACE("(%08x, %08x, %p): stub. Returning LINEERR_INVALPOINTER\n",
320 321 322 323
	      dwCountryID, dwAPIVersion, lpLineCountryList);
        return LINEERR_INVALPOINTER;
    }

324
    TRACE("(%08x, %08x, %p(%d)): stub.\n",
325 326
	  dwCountryID, dwAPIVersion, lpLineCountryList,
	  lpLineCountryList->dwTotalSize);
327

328 329
    if(RegOpenKeyA(HKEY_LOCAL_MACHINE, szCountrylistKey, &hkey)
            != ERROR_SUCCESS)
330 331 332
        return LINEERR_INIFILECORRUPT;


333 334 335 336 337 338 339 340
    dwAvailSize = lpLineCountryList->dwTotalSize;
    dwOffset = sizeof (LINECOUNTRYLIST);

    if(dwAvailSize<dwOffset)
        return LINEERR_STRUCTURETOOSMALL;

    memset(lpLineCountryList, 0, dwAvailSize);

341
    lpLineCountryList->dwTotalSize         = dwAvailSize;
342 343 344 345 346 347 348
    lpLineCountryList->dwUsedSize          = dwOffset;
    lpLineCountryList->dwNumCountries      = 0;
    lpLineCountryList->dwCountryListSize   = 0;
    lpLineCountryList->dwCountryListOffset = dwOffset;

    lpLCE = (LPLINECOUNTRYENTRY)(&lpLineCountryList[1]);

349 350 351 352 353 354 355 356 357 358 359 360 361 362
    if(RegQueryInfoKeyA(hkey, NULL, NULL, NULL, &num_countries, &max_subkey_len,
			NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
        RegCloseKey(hkey);
        return LINEERR_STRUCTURETOOSMALL;
    }

    if(dwCountryID)
        dwOffset = sizeof (LINECOUNTRYENTRY);
    else
        dwOffset += num_countries * sizeof (LINECOUNTRYENTRY);

    max_subkey_len++;
    subkey_name = HeapAlloc(GetProcessHeap(), 0, max_subkey_len);
    for(i = 0; i < num_countries; i++)
363
    {
364 365
        DWORD len, size, size_int, size_long, size_name, size_same;
	HKEY hsubkey;
366

367 368 369 370 371
	if(RegEnumKeyA(hkey, i, subkey_name, max_subkey_len) !=
	   ERROR_SUCCESS)
	    continue;

        if(dwCountryID && (atoi(subkey_name) != dwCountryID))
372 373
            continue;

374 375 376 377 378 379 380 381 382 383 384 385 386 387
	if(RegOpenKeyA(hkey, subkey_name, &hsubkey) != ERROR_SUCCESS)
	    continue;

	RegQueryValueExA(hsubkey, "InternationalRule", NULL, NULL,
			 NULL, &size_int);
        len  = size_int;

	RegQueryValueExA(hsubkey, "LongDistanceRule", NULL, NULL,
			 NULL, &size_long);
        len += size_long;

	RegQueryValueExA(hsubkey, "Name", NULL, NULL,
			 NULL, &size_name);
        len += size_name;
388

389 390 391 392 393
	RegQueryValueExA(hsubkey, "SameAreaRule", NULL, NULL,
			 NULL, &size_same);
        len += size_same;

        if(dwAvailSize < (dwOffset+len))
394
        {
395 396 397 398
            dwOffset += len;
	    RegCloseKey(hsubkey);
	    if(dwCountryID)
		break;
399 400 401 402
            continue;
        }

        lpLineCountryList->dwNumCountries++;
403 404
        lpLineCountryList->dwCountryListSize += sizeof (LINECOUNTRYENTRY);
        lpLineCountryList->dwUsedSize += len + sizeof (LINECOUNTRYENTRY);
405

406 407
	if(dwCountryID)
	    i = 0;
408

409 410 411 412
        lpLCE[i].dwCountryID = atoi(subkey_name);
	size = sizeof(DWORD);
	RegQueryValueExA(hsubkey, "CountryCode", NULL, NULL,
			 (BYTE*)&lpLCE[i].dwCountryCode, &size);
413

414 415 416 417
	lpLCE[i].dwNextCountryID = 0;
        
	if(i > 0)
            lpLCE[i-1].dwNextCountryID = lpLCE[i].dwCountryID;
418 419

        /* add country name */
420
        lpLCE[i].dwCountryNameSize = size_name;
421
        lpLCE[i].dwCountryNameOffset = dwOffset;
422
	RegQueryValueExA(hsubkey, "Name", NULL, NULL,
423
			 ((LPBYTE)lpLineCountryList)+dwOffset,
424 425
			 &size_name);
        dwOffset += size_name;
426 427

        /* add Same Area Rule */
428
        lpLCE[i].dwSameAreaRuleSize = size_same;
429
        lpLCE[i].dwSameAreaRuleOffset = dwOffset;
430
	RegQueryValueExA(hsubkey, "SameAreaRule", NULL, NULL,
431
			 ((LPBYTE)lpLineCountryList)+dwOffset,
432 433
			 &size_same);
        dwOffset += size_same;
434 435

        /* add Long Distance Rule */
436
        lpLCE[i].dwLongDistanceRuleSize = size_long;
437
        lpLCE[i].dwLongDistanceRuleOffset = dwOffset;
438
	RegQueryValueExA(hsubkey, "LongDistanceRule", NULL, NULL,
439
			 ((LPBYTE)lpLineCountryList)+dwOffset,
440 441
			 &size_long);
        dwOffset += size_long;
442 443

        /* add Long Distance Rule */
444
        lpLCE[i].dwInternationalRuleSize = size_int;
445
        lpLCE[i].dwInternationalRuleOffset = dwOffset;
446
	RegQueryValueExA(hsubkey, "InternationalRule", NULL, NULL,
447
			 ((LPBYTE)lpLineCountryList)+dwOffset,
448 449 450 451 452 453 454 455
			 &size_int);
        dwOffset += size_int;
	RegCloseKey(hsubkey);

        TRACE("Added country %s at %p\n", (LPSTR)lpLineCountryList + lpLCE[i].dwCountryNameOffset,
	      &lpLCE[i]);

	if(dwCountryID) break;
456 457 458 459
    }

    lpLineCountryList->dwNeededSize = dwOffset;

460
    TRACE("%d available %d required\n", dwAvailSize, dwOffset);
461

462 463 464
    HeapFree(GetProcessHeap(), 0, subkey_name);
    RegCloseKey(hkey);

465 466 467
    return 0;
}

468
/***********************************************************************
469
 *		lineGetDevCapsW (TAPI32.@)
470
 */
471 472
DWORD WINAPI lineGetDevCapsW(HLINEAPP hLineApp, DWORD dwDeviceID, DWORD dwAPIVersion,
                             DWORD dwExtVersion, LPLINEDEVCAPS lpLineDevCaps)
473
{
474 475 476 477 478 479 480 481 482 483 484 485 486 487
    FIXME("(%p, %08x, %08x, %08x, %p): stub.\n", hLineApp, dwDeviceID, dwAPIVersion,
                                                 dwExtVersion, lpLineDevCaps);
    return LINEERR_OPERATIONFAILED;
}

/***********************************************************************
 *		lineGetDevCapsA (TAPI32.@)
 */
DWORD WINAPI lineGetDevCapsA(HLINEAPP hLineApp, DWORD dwDeviceID, DWORD dwAPIVersion,
                             DWORD dwExtVersion, LPLINEDEVCAPS lpLineDevCaps)
{
    FIXME("(%p, %08x, %08x, %08x, %p): stub.\n", hLineApp, dwDeviceID, dwAPIVersion,
                                                 dwExtVersion, lpLineDevCaps);
    return LINEERR_OPERATIONFAILED;
488
}
489

490 491 492
/***********************************************************************
 *		lineGetDevConfig (TAPI32.@)
 */
493
DWORD WINAPI lineGetDevConfigA(DWORD dwDeviceID, LPVARSTRING lpDeviceConfig, LPCSTR lpszDeviceClass)
494
{
495
    FIXME("(%08x, %p, %s): stub.\n", dwDeviceID, lpDeviceConfig, lpszDeviceClass);
496 497 498
    return 0;
}

499
/***********************************************************************
Andrew Nguyen's avatar
Andrew Nguyen committed
500
 *		lineGetIDW (TAPI32.@)
501
 */
Andrew Nguyen's avatar
Andrew Nguyen committed
502 503
DWORD WINAPI lineGetIDW(HLINE hLine, DWORD dwAddressID, HCALL hCall, DWORD dwSelect,
                        LPVARSTRING lpDeviceID, LPCWSTR lpszDeviceClass)
504
{
Andrew Nguyen's avatar
Andrew Nguyen committed
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519
    FIXME("(%p, %08x, %p, %08x, %p, %s): stub.\n", hLine, dwAddressID, hCall,
                                                   dwSelect, lpDeviceID,
                                                   debugstr_w(lpszDeviceClass));
    return LINEERR_OPERATIONFAILED;
}

/***********************************************************************
 *		lineGetIDA (TAPI32.@)
 */
DWORD WINAPI lineGetIDA(HLINE hLine, DWORD dwAddressID, HCALL hCall, DWORD dwSelect,
                        LPVARSTRING lpDeviceID, LPCSTR lpszDeviceClass)
{
    FIXME("(%p, %08x, %p, %08x, %p, %s): stub.\n", hLine, dwAddressID, hCall,
                                                   dwSelect, lpDeviceID, lpszDeviceClass);
    return LINEERR_OPERATIONFAILED;
520 521
}

522 523 524
/***********************************************************************
 *		lineGetIcon (TAPI32.@)
 */
525
DWORD WINAPI lineGetIconA(DWORD dwDeviceID, LPCSTR lpszDeviceClass, HICON *lphIcon)
526
{
527
    FIXME("(%08x, %s, %p): stub.\n", dwDeviceID, lpszDeviceClass, lphIcon);
528
    return 0;
529
}
530

531 532 533
/***********************************************************************
 *		lineGetLineDevStatus (TAPI32.@)
 */
534
DWORD WINAPI lineGetLineDevStatusA(HLINE hLine, LPLINEDEVSTATUS lpLineDevStatus)
535
{
536
    FIXME("(%p, %p): stub.\n", hLine, lpLineDevStatus);
537
    return 0;
538
}
539

540 541 542
/***********************************************************************
 *		lineGetNewCalls (TAPI32.@)
 */
543 544
DWORD WINAPI lineGetNewCalls(HLINE hLine, DWORD dwAddressID, DWORD dwSelect, LPLINECALLLIST lpCallList)
{
545
    FIXME("(%p, %08x, %08x, %p): stub.\n", hLine, dwAddressID, dwSelect, lpCallList);
546 547 548
    return 0;
}

549 550 551
/***********************************************************************
 *		lineGetNumRings (TAPI32.@)
 */
552 553
DWORD WINAPI lineGetNumRings(HLINE hLine, DWORD dwAddressID, LPDWORD lpdwNumRings)
{
554
    FIXME("(%p, %08x, %p): stub.\n", hLine, dwAddressID, lpdwNumRings);
555 556 557
    return 0;
}

558
/***********************************************************************
559
 *		lineGetProviderListA (TAPI32.@)
560
 */
561
DWORD WINAPI lineGetProviderListA(DWORD dwAPIVersion, LPLINEPROVIDERLIST lpProviderList)
562
{
563
    FIXME("(%08x, %p): stub.\n", dwAPIVersion, lpProviderList);
564 565 566 567 568 569 570 571 572 573
    return LINEERR_OPERATIONFAILED;
}

/***********************************************************************
 *		lineGetProviderListW (TAPI32.@)
 */
DWORD WINAPI lineGetProviderListW(DWORD dwAPIVersion, LPLINEPROVIDERLIST lpProviderList)
{
    FIXME("(%08x, %p): stub.\n", dwAPIVersion, lpProviderList);
    return LINEERR_OPERATIONFAILED;
574
}
575

576 577 578
/***********************************************************************
 *		lineGetRequest (TAPI32.@)
 */
579
DWORD WINAPI lineGetRequestA(HLINEAPP hLineApp, DWORD dwRequestMode, LPVOID lpRequestBuffer)
580
{
581
    FIXME("%p, %08x, %p): stub.\n", hLineApp, dwRequestMode, lpRequestBuffer);
582
    return 0;
583
}
584

585 586 587
/***********************************************************************
 *		lineGetStatusMessages (TAPI32.@)
 */
588 589
DWORD WINAPI lineGetStatusMessages(HLINE hLine, LPDWORD lpdwLineStatus, LPDWORD lpdwAddressStates)
{
590
    FIXME("(%p, %p, %p): stub.\n", hLine, lpdwLineStatus, lpdwAddressStates);
591
    return 0;
592
}
593

594 595
/***********************************************************************
 *		lineGetTranslateCaps (TAPI32.@)
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
 *
 *      get address translate capabilities. Returns a LINETRANSLATECAPS
 *      structure:
 *
 *      +-----------------------+
 *      |TotalSize              |
 *      |NeededSize             |
 *      |UsedSize               |
 *      +-----------------------+
 *      |NumLocations           |
 *      |LocationsListSize      |
 *      |LocationsListOffset    | -+
 *      |CurrentLocationID      |  |
 *      +-----------------------+  |
 *      |NumCards               |  |
 *      |CardListSize           |  |
 *      |CardListOffset         | -|--+
 *      |CurrentPreferredCardID |  |  |
 *      +-----------------------+  |  |
 *      |                       | <+  |
 *      |LINELOCATIONENTRY #1   |     |
 *      |                       |     |
 *      +-----------------------+     |
 *      ~                       ~     |
 *      +-----------------------+     |
 *      |                       |     |
 *      |LINELOCATIONENTRY      |     |
 *      |          #NumLocations|     |
 *      +-----------------------+     |
 *      |                       | <---+
 *      |LINECARDENTRY #1       |
 *      |                       |
 *      +-----------------------+
 *      ~                       ~
 *      +-----------------------+
 *      |                       |
 *      |LINECARDENTRY #NumCards|
 *      |                       |
 *      +-----------------------+
 *      | room for strings named|
 *      | in the structures     |
 *      | above.                |
 *      +-----------------------+
 */
640
DWORD WINAPI lineGetTranslateCapsA(HLINEAPP hLineApp, DWORD dwAPIVersion,
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
        LPLINETRANSLATECAPS lpTranslateCaps)
{
    HKEY hkLocations, hkCards, hkCardLocations, hsubkey;
    int numlocations, numcards;
    DWORD maxlockeylen,
        maxcardkeylen;
    char *loc_key_name = NULL;
    char *card_key_name = NULL;
    LPBYTE strptr;
    int length;
    int i;
    DWORD lendword;
    DWORD currentid;
    LPLINELOCATIONENTRY pLocEntry;
    LPLINECARDENTRY pCardEntry;
    
657
    TRACE("(%p, %08x, %p (tot. size %d)\n", hLineApp, dwAPIVersion,
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711
            lpTranslateCaps, lpTranslateCaps->dwTotalSize );
    if( lpTranslateCaps->dwTotalSize < sizeof(LINETRANSLATECAPS))
        return LINEERR_STRUCTURETOOSMALL;
    if( RegCreateKeyA(HKEY_LOCAL_MACHINE, szLocationsKey, &hkLocations)
            != ERROR_SUCCESS ) {
        ERR("unexpected registry error 1.\n");
        return LINEERR_INIFILECORRUPT;  
    }
    lendword = sizeof( DWORD);
    if( RegQueryValueExA( hkLocations, "CurrentID", NULL, NULL,
                (LPBYTE) &currentid, &lendword) != ERROR_SUCCESS )
        currentid = -1;  /* change this later */
    if(RegQueryInfoKeyA(hkLocations, NULL, NULL, NULL, NULL, &maxlockeylen,
			NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
        RegCloseKey(hkLocations);
        ERR("unexpected registry error 2.\n");
        return LINEERR_INIFILECORRUPT;
    }
    maxlockeylen++;
    if( maxlockeylen < 10)
        maxlockeylen = 10; /* need this also if there is no key */
    loc_key_name = HeapAlloc( GetProcessHeap(), 0, maxlockeylen);
    /* first time through: calculate needed space */
    length=0;
    i=0;
    numlocations=0;
    while( RegEnumKeyA(hkLocations, i, loc_key_name, maxlockeylen)
            == ERROR_SUCCESS){
        DWORD size_val;
        i++;
        if( strncasecmp(loc_key_name, "location", 8)  ||
                (RegOpenKeyA(hkLocations, loc_key_name, &hsubkey)
                 != ERROR_SUCCESS))
            continue;
        numlocations++;
        length += sizeof(LINELOCATIONENTRY);
        RegQueryValueExA(hsubkey, "Name",NULL,NULL,NULL,&size_val); 
        length += size_val;
        RegQueryValueExA(hsubkey, "AreaCode",NULL,NULL,NULL,&size_val); 
        length += size_val;
        RegQueryValueExA(hsubkey, "OutsideAccess",NULL,NULL,NULL,&size_val); 
        length += size_val;
        RegQueryValueExA(hsubkey, "LongDistanceAccess",NULL,NULL,NULL,&size_val); 
        length += size_val;
        RegQueryValueExA(hsubkey, "DisableCallWaiting",NULL,NULL,NULL,&size_val); 
        length += size_val;
        /* fixme: what about TollPrefixList???? */
        RegCloseKey(hsubkey);
    }
    if(numlocations == 0) {
        /* add one location */
        if( RegCreateKeyA( hkLocations, "Location1", &hsubkey)
                == ERROR_SUCCESS) {
            DWORD dwval;
712
            char buf[10];
713 714
            numlocations = 1;
            length += sizeof(LINELOCATIONENTRY) + 20 ;
715
            RegSetValueExA( hsubkey, "AreaCode", 0, REG_SZ, (const BYTE *)"010", 4);
716 717 718 719
            GetLocaleInfoA( LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, buf, 8);
            dwval = atoi(buf);
            RegSetValueExA( hsubkey, "Country", 0, REG_DWORD, (LPBYTE)&dwval,
                    sizeof(DWORD));
720
            RegSetValueExA( hsubkey, "DisableCallWaiting", 0, REG_SZ, (const BYTE *)"", 1);
721 722 723
            dwval = 1;  
            RegSetValueExA( hsubkey, "Flags", 0, REG_DWORD, (LPBYTE)&dwval,
                    sizeof(DWORD));
724 725 726
            RegSetValueExA( hsubkey, "LongDistanceAccess", 0, REG_SZ, (const BYTE *)"", 1);
            RegSetValueExA( hsubkey, "Name", 0, REG_SZ, (const BYTE *)"New Location", 13);
            RegSetValueExA( hsubkey, "OutsideAccess", 0, REG_SZ, (const BYTE *)"", 1);
727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772
            RegCloseKey(hsubkey);
            dwval = 1;  
            RegSetValueExA( hkLocations, "CurrentID", 0, REG_DWORD,
                    (LPBYTE)&dwval, sizeof(DWORD));
            dwval = 2;  
            RegSetValueExA( hkLocations, "NextID", 0, REG_DWORD, (LPBYTE)&dwval,
                    sizeof(DWORD));
        }
    }
    /* do the card list */
    numcards=0;
    if( RegCreateKeyA(HKEY_CURRENT_USER, szCardsKey, &hkCards)
            == ERROR_SUCCESS ) {
        if(RegQueryInfoKeyA(hkCards, NULL, NULL, NULL, NULL, &maxcardkeylen,
                NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
            maxcardkeylen++;
            if( maxcardkeylen < 6) maxcardkeylen = 6;
            card_key_name = HeapAlloc(GetProcessHeap(), 0, maxcardkeylen);
            i=0;
            while( RegEnumKeyA(hkCards, i, card_key_name, maxcardkeylen) ==
                    ERROR_SUCCESS){
                DWORD size_val;
                i++;
                if( strncasecmp(card_key_name, "card", 4)  || ERROR_SUCCESS !=
                        (RegOpenKeyA(hkCards, card_key_name, &hsubkey) ))
                    continue;
                numcards++;
                length += sizeof(LINECARDENTRY);
                RegQueryValueExA(hsubkey, "Name",NULL,NULL,NULL,&size_val); 
                length += size_val;
                RegQueryValueExA(hsubkey, "LocalRule",NULL,NULL,NULL,&size_val); 
                length += size_val;
                RegQueryValueExA(hsubkey, "LDRule",NULL,NULL,NULL,&size_val); 
                length += size_val;
                RegQueryValueExA(hsubkey, "InternationalRule",NULL,NULL,NULL,
                        &size_val); 
                length += size_val;
                RegCloseKey(hsubkey);
            }
        }
        /* add one card (direct call) */
        if (numcards == 0 &&
                ERROR_SUCCESS == RegCreateKeyA( hkCards, "Card1", &hsubkey)) {
            DWORD dwval;
            numcards = 1;
            length += sizeof(LINECARDENTRY) + 22 ;
773
            RegSetValueExA( hsubkey, "Name", 0, REG_SZ, (const BYTE *)"None (Direct Call)", 19);
774 775 776
            dwval = 1;  
            RegSetValueExA( hsubkey, "Flags", 0, REG_DWORD, (LPBYTE)&dwval,
                    sizeof(DWORD));
777 778 779
            RegSetValueExA( hsubkey, "InternationalRule", 0, REG_SZ, (const BYTE *)"", 1);
            RegSetValueExA( hsubkey, "LDRule", 0, REG_SZ, (const BYTE *)"", 1);
            RegSetValueExA( hsubkey, "LocalRule", 0, REG_SZ, (const BYTE *)"", 1);
780 781 782 783 784
            RegCloseKey(hsubkey);
            dwval = 2;  
            RegSetValueExA( hkCards, "NextID", 0, REG_DWORD, (LPBYTE)&dwval,
                    sizeof(DWORD));
        }
785
    } else hkCards = 0;  /* should really fail */
786 787 788 789 790 791 792 793
    /* check if sufficient room is available */
    lpTranslateCaps->dwNeededSize =  sizeof(LINETRANSLATECAPS) + length;
    if ( lpTranslateCaps->dwNeededSize > lpTranslateCaps->dwTotalSize ) {
        RegCloseKey( hkLocations);
        if( hkCards) RegCloseKey( hkCards);
        HeapFree(GetProcessHeap(), 0, loc_key_name);
        HeapFree(GetProcessHeap(), 0, card_key_name);
        lpTranslateCaps->dwUsedSize = sizeof(LINETRANSLATECAPS);
794
        TRACE("Insufficient space: total %d needed %d used %d\n",
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896
                lpTranslateCaps->dwTotalSize,
                lpTranslateCaps->dwNeededSize,
                lpTranslateCaps->dwUsedSize);
        return  0;
    }
    /* fill in the LINETRANSLATECAPS structure */
    lpTranslateCaps->dwUsedSize = lpTranslateCaps->dwNeededSize;
    lpTranslateCaps->dwNumLocations = numlocations;
    lpTranslateCaps->dwLocationListSize = sizeof(LINELOCATIONENTRY) *
            lpTranslateCaps->dwNumLocations;
    lpTranslateCaps->dwLocationListOffset = sizeof(LINETRANSLATECAPS);
    lpTranslateCaps->dwCurrentLocationID = currentid; 
    lpTranslateCaps->dwNumCards = numcards;
    lpTranslateCaps->dwCardListSize = sizeof(LINECARDENTRY) *
            lpTranslateCaps->dwNumCards;
    lpTranslateCaps->dwCardListOffset = lpTranslateCaps->dwLocationListOffset +
            lpTranslateCaps->dwLocationListSize;
    lpTranslateCaps->dwCurrentPreferredCardID = 0; 
    /* this is where the strings will be stored */
    strptr = ((LPBYTE) lpTranslateCaps) +
        lpTranslateCaps->dwCardListOffset + lpTranslateCaps->dwCardListSize;
    pLocEntry = (LPLINELOCATIONENTRY) (lpTranslateCaps + 1);
    /* key with Preferred CardID's */
    if( RegOpenKeyA(HKEY_CURRENT_USER, szLocationsKey, &hkCardLocations)
            != ERROR_SUCCESS ) 
        hkCardLocations = 0;
    /* second time through all locations */
    i=0;
    while(RegEnumKeyA(hkLocations, i, loc_key_name, maxlockeylen)
            == ERROR_SUCCESS){
        DWORD size_val;
        i++;
        if( strncasecmp(loc_key_name, "location", 8)  ||
                (RegOpenKeyA(hkLocations, loc_key_name, &hsubkey)
                 != ERROR_SUCCESS))
            continue;
        size_val=sizeof(DWORD);
        if( RegQueryValueExA(hsubkey, "ID",NULL, NULL,
                (LPBYTE) &(pLocEntry->dwPermanentLocationID), &size_val) !=
                ERROR_SUCCESS)
            pLocEntry->dwPermanentLocationID = atoi( loc_key_name + 8);
        size_val=2048;
        RegQueryValueExA(hsubkey, "Name",NULL,NULL, strptr, &size_val);
        pLocEntry->dwLocationNameSize = size_val;
        pLocEntry->dwLocationNameOffset = strptr - (LPBYTE) lpTranslateCaps;
        strptr += size_val;
 
        size_val=2048;
        RegQueryValueExA(hsubkey, "AreaCode",NULL,NULL, strptr, &size_val);
        pLocEntry->dwCityCodeSize = size_val;
        pLocEntry->dwCityCodeOffset = strptr - (LPBYTE) lpTranslateCaps;
        strptr += size_val;
        
        size_val=2048;
        RegQueryValueExA(hsubkey, "OutsideAccess",NULL,NULL, strptr, &size_val);
        pLocEntry->dwLocalAccessCodeSize = size_val;
        pLocEntry->dwLocalAccessCodeOffset = strptr - (LPBYTE) lpTranslateCaps;
        strptr += size_val;
        size_val=2048;
        RegQueryValueExA(hsubkey, "LongDistanceAccess",NULL,NULL, strptr,
                &size_val);
        pLocEntry->dwLongDistanceAccessCodeSize= size_val;
        pLocEntry->dwLongDistanceAccessCodeOffset= strptr -
            (LPBYTE) lpTranslateCaps;
        strptr += size_val;
        size_val=2048;
        RegQueryValueExA(hsubkey, "DisableCallWaiting",NULL,NULL, strptr,
                &size_val);
        pLocEntry->dwCancelCallWaitingSize= size_val;
        pLocEntry->dwCancelCallWaitingOffset= strptr - (LPBYTE) lpTranslateCaps;
        strptr += size_val;

        pLocEntry->dwTollPrefixListSize = 0;    /* FIXME */
        pLocEntry->dwTollPrefixListOffset = 0;    /* FIXME */

        size_val=sizeof(DWORD);
        RegQueryValueExA(hsubkey, "Country",NULL,NULL,
                (LPBYTE) &(pLocEntry->dwCountryCode), &size_val);
        pLocEntry->dwCountryID = pLocEntry->dwCountryCode; /* FIXME */
        RegQueryValueExA(hsubkey, "Flags",NULL,NULL,
                (LPBYTE) &(pLocEntry->dwOptions), &size_val);
        RegCloseKey(hsubkey);
        /* get preferred cardid */
        pLocEntry->dwPreferredCardID = 0;
        if ( hkCardLocations) {
            size_val=sizeof(DWORD);
            if(RegOpenKeyA(hkCardLocations, loc_key_name, &hsubkey) ==
                    ERROR_SUCCESS) {
                RegQueryValueExA(hsubkey, "CallingCard",NULL,NULL,
                        (LPBYTE) &(pLocEntry->dwPreferredCardID), &size_val);
                RegCloseKey(hsubkey);
            }
                
        }
        /* make sure there is a currentID */
        if(currentid == -1){
            currentid = pLocEntry->dwPermanentLocationID;
            lpTranslateCaps->dwCurrentLocationID = currentid; 
        }
        if(pLocEntry->dwPermanentLocationID == currentid )
            lpTranslateCaps->dwCurrentPreferredCardID =
                    pLocEntry->dwPreferredCardID;
897 898 899
        TRACE("added: ID %d %s CountryCode %d CityCode %s CardID %d "
                "LocalAccess: %s LongDistanceAccess: %s CountryID %d "
                "Options %d CancelCallWait %s\n",
900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953
                pLocEntry->dwPermanentLocationID,
                debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwLocationNameOffset),
                pLocEntry->dwCountryCode,
                debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwCityCodeOffset),
                pLocEntry->dwPreferredCardID,
                debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwLocalAccessCodeOffset),
                debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwLongDistanceAccessCodeOffset),
                pLocEntry->dwCountryID,
                pLocEntry->dwOptions,
                debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwCancelCallWaitingOffset));
        pLocEntry++;
    }
    pCardEntry= (LPLINECARDENTRY) pLocEntry;
    /* do the card list */
    if( hkCards) {
        i=0;
        while( RegEnumKeyA(hkCards, i, card_key_name, maxcardkeylen) ==
                ERROR_SUCCESS){
            DWORD size_val;
            i++;
            if( strncasecmp(card_key_name, "card", 4)  ||
                    (RegOpenKeyA(hkCards, card_key_name, &hsubkey) != ERROR_SUCCESS))
                continue;
            size_val=sizeof(DWORD);
            if( RegQueryValueExA(hsubkey, "ID",NULL, NULL,
                    (LPBYTE) &(pCardEntry->dwPermanentCardID), &size_val) !=
                    ERROR_SUCCESS)
                pCardEntry->dwPermanentCardID= atoi( card_key_name + 4);
            size_val=2048;
            RegQueryValueExA(hsubkey, "Name",NULL,NULL, strptr, &size_val);
            pCardEntry->dwCardNameSize = size_val;
            pCardEntry->dwCardNameOffset = strptr - (LPBYTE) lpTranslateCaps;
            strptr += size_val;
            pCardEntry->dwCardNumberDigits = 1; /* FIXME */
            size_val=2048;
            RegQueryValueExA(hsubkey, "LocalRule",NULL,NULL, strptr, &size_val);
            pCardEntry->dwSameAreaRuleSize= size_val;
            pCardEntry->dwSameAreaRuleOffset= strptr - (LPBYTE) lpTranslateCaps;
            strptr += size_val;
            size_val=2048;
            RegQueryValueExA(hsubkey, "LDRule",NULL,NULL, strptr, &size_val);
            pCardEntry->dwLongDistanceRuleSize = size_val;
            pCardEntry->dwLongDistanceRuleOffset = strptr - (LPBYTE) lpTranslateCaps;
            strptr += size_val;
            size_val=2048;
            RegQueryValueExA(hsubkey, "InternationalRule",NULL,NULL, strptr,
                    &size_val);
            pCardEntry->dwInternationalRuleSize = size_val;
            pCardEntry->dwInternationalRuleOffset = strptr -
                (LPBYTE) lpTranslateCaps;
            strptr += size_val;
            size_val=sizeof(DWORD);
            RegQueryValueExA(hsubkey, "Flags",NULL, NULL,
                    (LPBYTE) &(pCardEntry->dwOptions), &size_val); 
954
            TRACE( "added card: ID %d name %s SameArea %s LongDistance %s International %s Options 0x%x\n", 
955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970
                    pCardEntry->dwPermanentCardID,
                    debugstr_a( (char*)lpTranslateCaps + pCardEntry->dwCardNameOffset),
                    debugstr_a( (char*)lpTranslateCaps + pCardEntry->dwSameAreaRuleOffset),
                    debugstr_a( (char*)lpTranslateCaps + pCardEntry->dwLongDistanceRuleOffset),
                    debugstr_a( (char*)lpTranslateCaps + pCardEntry->dwInternationalRuleOffset),
                    pCardEntry->dwOptions);

            pCardEntry++;
        }
    }

    if(hkLocations) RegCloseKey(hkLocations);
    if(hkCards) RegCloseKey(hkCards);
    if(hkCardLocations) RegCloseKey(hkCardLocations);
    HeapFree(GetProcessHeap(), 0, loc_key_name);
    HeapFree(GetProcessHeap(), 0, card_key_name);
971
    TRACE(" returning success tot %d needed %d used %d\n",
972 973 974 975
            lpTranslateCaps->dwTotalSize,
            lpTranslateCaps->dwNeededSize,
            lpTranslateCaps->dwUsedSize );
    return 0; /* success */
976 977
}

978 979 980
/***********************************************************************
 *		lineHandoff (TAPI32.@)
 */
981
DWORD WINAPI lineHandoffA(HCALL hCall, LPCSTR lpszFileName, DWORD dwMediaMode)
982
{
983
    FIXME("(%p, %s, %08x): stub.\n", hCall, lpszFileName, dwMediaMode);
984
    return 0;
985
}
986

987 988 989
/***********************************************************************
 *		lineHold (TAPI32.@)
 */
990 991
DWORD WINAPI lineHold(HCALL hCall)
{
992
    FIXME("(%p): stub.\n", hCall);
993
    return 1;
994
}
995

996 997 998
/***********************************************************************
 *		lineInitialize (TAPI32.@)
 */
999 1000 1001 1002 1003 1004 1005
DWORD WINAPI lineInitialize(
  LPHLINEAPP lphLineApp,
  HINSTANCE hInstance,
  LINECALLBACK lpfnCallback,
  LPCSTR lpszAppName,
  LPDWORD lpdwNumDevs)
{
1006
    FIXME("(%p, %p, %p, %s, %p): stub.\n", lphLineApp, hInstance,
1007
	  lpfnCallback, debugstr_a(lpszAppName), lpdwNumDevs);
1008 1009 1010
    return 0;
}

1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
/***********************************************************************
 *              lineInitializeExA (TAPI32.@)
 */
LONG WINAPI lineInitializeExA(LPHLINEAPP lphLineApp, HINSTANCE hInstance, LINECALLBACK lpfnCallback, LPCSTR lpszFriendlyAppName, LPDWORD lpdwNumDevs, LPDWORD lpdwAPIVersion, LPLINEINITIALIZEEXPARAMS lpLineInitializeExParams)
{
    FIXME("(%p, %p, %p, %s, %p, %p, %p): stub.\n", lphLineApp, hInstance,
          lpfnCallback, debugstr_a(lpszFriendlyAppName), lpdwNumDevs, lpdwAPIVersion, lpLineInitializeExParams);
    return 0;
}

1021
/***********************************************************************
1022
 *		lineMakeCallW (TAPI32.@)
1023
 */
1024 1025
DWORD WINAPI lineMakeCallW(HLINE hLine, LPHCALL lphCall, LPCWSTR lpszDestAddress,
                           DWORD dwCountryCode, LPLINECALLPARAMS lpCallParams)
1026
{
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
    FIXME("(%p, %p, %s, %08x, %p): stub.\n", hLine, lphCall, debugstr_w(lpszDestAddress),
                                             dwCountryCode, lpCallParams);
    return LINEERR_OPERATIONFAILED;
}

/***********************************************************************
 *		lineMakeCallA (TAPI32.@)
 */
DWORD WINAPI lineMakeCallA(HLINE hLine, LPHCALL lphCall, LPCSTR lpszDestAddress,
                           DWORD dwCountryCode, LPLINECALLPARAMS lpCallParams)
{
    FIXME("(%p, %p, %s, %08x, %p): stub.\n", hLine, lphCall, lpszDestAddress,
                                             dwCountryCode, lpCallParams);
    return LINEERR_OPERATIONFAILED;
1041 1042
}

1043 1044 1045
/***********************************************************************
 *		lineMonitorDigits (TAPI32.@)
 */
1046 1047
DWORD WINAPI lineMonitorDigits(HCALL hCall, DWORD dwDigitModes)
{
1048
    FIXME("(%p, %08x): stub.\n", hCall, dwDigitModes);
1049 1050 1051
    return 0;
}

1052 1053 1054
/***********************************************************************
 *		lineMonitorMedia (TAPI32.@)
 */
1055 1056
DWORD WINAPI lineMonitorMedia(HCALL hCall, DWORD dwMediaModes)
{
1057
    FIXME("(%p, %08x): stub.\n", hCall, dwMediaModes);
1058
    return 0;
1059
}
1060

1061 1062 1063
/***********************************************************************
 *		lineMonitorTones (TAPI32.@)
 */
1064 1065
DWORD WINAPI lineMonitorTones(HCALL hCall, LPLINEMONITORTONE lpToneList, DWORD dwNumEntries)
{
1066
    FIXME("(%p, %p, %08x): stub.\n", hCall, lpToneList, dwNumEntries);
1067
    return 0;
1068
}
1069

1070 1071 1072
/***********************************************************************
 *		lineNegotiateAPIVersion (TAPI32.@)
 */
1073 1074 1075 1076 1077 1078 1079 1080 1081
DWORD WINAPI lineNegotiateAPIVersion(
  HLINEAPP hLineApp,
  DWORD dwDeviceID,
  DWORD dwAPILowVersion,
  DWORD dwAPIHighVersion,
  LPDWORD lpdwAPIVersion,
  LPLINEEXTENSIONID lpExtensionID
)
{
1082
    FIXME("(%p, %d, %d, %d, %p, %p): stub.\n", hLineApp, dwDeviceID,
1083
	  dwAPILowVersion, dwAPIHighVersion, lpdwAPIVersion, lpExtensionID);
1084 1085 1086 1087
    *lpdwAPIVersion = dwAPIHighVersion;
    return 0;
}

1088 1089 1090
/***********************************************************************
 *		lineNegotiateExtVersion (TAPI32.@)
 */
1091 1092
DWORD WINAPI lineNegotiateExtVersion(HLINEAPP hLineApp, DWORD dwDeviceID, DWORD dwAPIVersion, DWORD dwExtLowVersion, DWORD dwExtHighVersion, LPDWORD lpdwExtVersion)
{
1093
    FIXME("stub.\n");
1094 1095 1096
    return 0;
}

1097 1098 1099
/***********************************************************************
 *		lineOpen (TAPI32.@)
 */
1100
DWORD WINAPI lineOpenA(HLINEAPP hLineApp, DWORD dwDeviceID, LPHLINE lphLine, DWORD dwAPIVersion, DWORD dwExtVersion, DWORD dwCallbackInstance, DWORD dwPrivileges, DWORD dwMediaModes, LPLINECALLPARAMS lpCallParams)
1101
{
1102
    FIXME("stub.\n");
1103 1104 1105
    return 0;
}

1106 1107 1108
/***********************************************************************
 *		linePark (TAPI32.@)
 */
1109
DWORD WINAPI lineParkA(HCALL hCall, DWORD dwParkMode, LPCSTR lpszDirAddress, LPVARSTRING lpNonDirAddress)
1110
{
1111
    FIXME("(%p, %08x, %s, %p): stub.\n", hCall, dwParkMode, lpszDirAddress, lpNonDirAddress);
1112
    return 1;
1113
}
1114

1115 1116 1117
/***********************************************************************
 *		linePickup (TAPI32.@)
 */
1118
DWORD WINAPI linePickupA(HLINE hLine, DWORD dwAddressID, LPHCALL lphCall, LPCSTR lpszDestAddress, LPCSTR lpszGroupID)
1119
{
1120
    FIXME("(%p, %08x, %p, %s, %s): stub.\n", hLine, dwAddressID, lphCall, lpszDestAddress, lpszGroupID);
1121
    return 1;
1122
}
1123

1124 1125 1126
/***********************************************************************
 *		linePrepareAddToConference (TAPI32.@)
 */
1127
DWORD WINAPI linePrepareAddToConferenceA(HCALL hConfCall, LPHCALL lphConsultCall, LPLINECALLPARAMS lpCallParams)
1128
{
1129
    FIXME("(%p, %p, %p): stub.\n", hConfCall, lphConsultCall, lpCallParams);
1130
    return 1;
1131
}
1132

1133 1134
/***********************************************************************
 *		lineRedirect (TAPI32.@)
1135
 */
1136
DWORD WINAPI lineRedirectA(
1137 1138 1139 1140
  HCALL hCall,
  LPCSTR lpszDestAddress,
  DWORD  dwCountryCode) {

1141
  FIXME(": stub.\n");
1142 1143 1144
  return 1;
}

1145 1146 1147
/***********************************************************************
 *		lineRegisterRequestRecipient (TAPI32.@)
 */
1148 1149
DWORD WINAPI lineRegisterRequestRecipient(HLINEAPP hLineApp, DWORD dwRegistrationInstance, DWORD dwRequestMode, DWORD dwEnable)
{
1150
    FIXME("(%p, %08x, %08x, %08x): stub.\n", hLineApp, dwRegistrationInstance, dwRequestMode, dwEnable);
1151 1152 1153
    return 1;
}

1154 1155 1156
/***********************************************************************
 *		lineReleaseUserUserInfo (TAPI32.@)
 */
1157 1158
DWORD WINAPI lineReleaseUserUserInfo(HCALL hCall)
{
1159
    FIXME("(%p): stub.\n", hCall);
1160
    return 1;
1161
}
1162

1163 1164 1165
/***********************************************************************
 *		lineRemoveFromConference (TAPI32.@)
 */
1166 1167
DWORD WINAPI lineRemoveFromConference(HCALL hCall)
{
1168
    FIXME("(%p): stub.\n", hCall);
1169 1170 1171
    return 1;
}

1172 1173 1174
/***********************************************************************
 *		lineRemoveProvider (TAPI32.@)
 */
1175 1176
DWORD WINAPI lineRemoveProvider(DWORD dwPermanentProviderID, HWND hwndOwner)
{
1177
    FIXME("(%08x, %p): stub.\n", dwPermanentProviderID, hwndOwner);
1178
    return 1;
1179
}
1180

1181 1182 1183
/***********************************************************************
 *		lineSecureCall (TAPI32.@)
 */
1184 1185
DWORD WINAPI lineSecureCall(HCALL hCall)
{
1186
    FIXME("(%p): stub.\n", hCall);
1187 1188 1189
    return 1;
}

1190 1191 1192
/***********************************************************************
 *		lineSendUserUserInfo (TAPI32.@)
 */
1193 1194
DWORD WINAPI lineSendUserUserInfo(HCALL hCall, LPCSTR lpsUserUserInfo, DWORD dwSize)
{
1195
    FIXME("(%p, %s, %08x): stub.\n", hCall, lpsUserUserInfo, dwSize);
1196 1197 1198
    return 1;
}

1199 1200 1201
/***********************************************************************
 *		lineSetAppPriority (TAPI32.@)
 */
1202
DWORD WINAPI lineSetAppPriorityA(LPCSTR lpszAppFilename, DWORD dwMediaMode, LPLINEEXTENSIONID const lpExtensionID, DWORD dwRequestMode, LPCSTR lpszExtensionName, DWORD dwPriority)
1203
{
1204
    FIXME("(%s, %08x, %p, %08x, %s, %08x): stub.\n", lpszAppFilename, dwMediaMode, lpExtensionID, dwRequestMode, lpszExtensionName, dwPriority);
1205 1206 1207
    return 0;
}

1208 1209 1210
/***********************************************************************
 *		lineSetAppSpecific (TAPI32.@)
 */
1211 1212
DWORD WINAPI lineSetAppSpecific(HCALL hCall, DWORD dwAppSpecific)
{
1213
    FIXME("(%p, %08x): stub.\n", hCall, dwAppSpecific);
1214 1215 1216
    return 0;
}

1217 1218 1219
/***********************************************************************
 *		lineSetCallParams (TAPI32.@)
 */
1220 1221
DWORD WINAPI lineSetCallParams(HCALL hCall, DWORD dwBearerMode, DWORD dwMinRate, DWORD dwMaxRate, LPLINEDIALPARAMS lpDialParams)
{
1222
    FIXME("(%p, %08x, %08x, %08x, %p): stub.\n", hCall, dwBearerMode, dwMinRate, dwMaxRate, lpDialParams);
1223 1224 1225
    return 1;
}

1226 1227 1228
/***********************************************************************
 *		lineSetCallPrivilege (TAPI32.@)
 */
1229 1230
DWORD WINAPI lineSetCallPrivilege(HCALL hCall, DWORD dwCallPrivilege)
{
1231
    FIXME("(%p, %08x): stub.\n", hCall, dwCallPrivilege);
1232
    return 0;
1233 1234
}

1235 1236 1237
/***********************************************************************
 *		lineSetCurrentLocation (TAPI32.@)
 */
1238 1239
DWORD WINAPI lineSetCurrentLocation(HLINEAPP hLineApp, DWORD dwLocation)
{
1240
    FIXME("(%p, %08x): stub.\n", hLineApp, dwLocation);
1241 1242 1243
    return 0;
}

1244 1245 1246
/***********************************************************************
 *		lineSetDevConfig (TAPI32.@)
 */
1247
DWORD WINAPI lineSetDevConfigA(DWORD dwDeviceID, LPVOID lpDeviceConfig, DWORD dwSize, LPCSTR lpszDeviceClass)
1248
{
1249
    FIXME("(%08x, %p, %08x, %s): stub.\n", dwDeviceID, lpDeviceConfig, dwSize, lpszDeviceClass);
1250 1251 1252
    return 0;
}

1253 1254 1255
/***********************************************************************
 *		lineSetMediaControl (TAPI32.@)
 */
1256 1257 1258 1259 1260 1261 1262 1263 1264
DWORD WINAPI lineSetMediaControl(
HLINE hLine,
DWORD dwAddressID,
HCALL hCall,
DWORD dwSelect,
LPLINEMEDIACONTROLDIGIT const lpDigitList,
DWORD dwDigitNumEntries,
LPLINEMEDIACONTROLMEDIA const lpMediaList,
DWORD dwMediaNumEntries,
1265
LPLINEMEDIACONTROLTONE const lpToneList,
1266 1267 1268 1269
DWORD dwToneNumEntries,
LPLINEMEDIACONTROLCALLSTATE const lpCallStateList,
DWORD dwCallStateNumEntries)
{
1270
    FIXME(": stub.\n");
1271 1272 1273
    return 0;
}

1274 1275 1276
/***********************************************************************
 *		lineSetMediaMode (TAPI32.@)
 */
1277 1278
DWORD WINAPI lineSetMediaMode(HCALL hCall, DWORD dwMediaModes)
{
1279
    FIXME("(%p, %08x): stub.\n", hCall, dwMediaModes);
1280
    return 0;
1281
}
1282

1283 1284 1285
/***********************************************************************
 *		lineSetNumRings (TAPI32.@)
 */
1286 1287
DWORD WINAPI lineSetNumRings(HLINE hLine, DWORD dwAddressID, DWORD dwNumRings)
{
1288
    FIXME("(%p, %08x, %08x): stub.\n", hLine, dwAddressID, dwNumRings);
1289
    return 0;
1290 1291
}

1292 1293 1294
/***********************************************************************
 *		lineSetStatusMessages (TAPI32.@)
 */
1295 1296
DWORD WINAPI lineSetStatusMessages(HLINE hLine, DWORD dwLineStates, DWORD dwAddressStates)
{
1297
    FIXME("(%p, %08x, %08x): stub.\n", hLine, dwLineStates, dwAddressStates);
1298
    return 0;
1299 1300
}

1301 1302 1303
/***********************************************************************
 *		lineSetTerminal (TAPI32.@)
 */
1304 1305
DWORD WINAPI lineSetTerminal(HLINE hLine, DWORD dwAddressID, HCALL hCall, DWORD dwSelect, DWORD dwTerminalModes, DWORD dwTerminalID, DWORD bEnable)
{
1306
    FIXME("(%p, %08x, %p, %08x, %08x, %08x, %08x): stub.\n", hLine, dwAddressID, hCall, dwSelect, dwTerminalModes, dwTerminalID, bEnable);
1307
    return 1;
1308
}
1309

1310 1311 1312
/***********************************************************************
 *		lineSetTollList (TAPI32.@)
 */
1313
DWORD WINAPI lineSetTollListA(HLINEAPP hLineApp, DWORD dwDeviceID, LPCSTR lpszAddressIn, DWORD dwTollListOption)
1314
{
1315
    FIXME("(%p, %08x, %s, %08x): stub.\n", hLineApp, dwDeviceID, lpszAddressIn, dwTollListOption);
1316
    return 0;
1317 1318
}

1319 1320 1321
/***********************************************************************
 *		lineSetupConference (TAPI32.@)
 */
1322
DWORD WINAPI lineSetupConferenceA(HCALL hCall, HLINE hLine, LPHCALL lphConfCall, LPHCALL lphConsultCall, DWORD dwNumParties, LPLINECALLPARAMS lpCallParams)
1323
{
1324
    FIXME("(%p, %p, %p, %p, %08x, %p): stub.\n", hCall, hLine, lphConfCall, lphConsultCall, dwNumParties, lpCallParams);
1325 1326 1327
    return 1;
}

1328 1329 1330
/***********************************************************************
 *		lineSetupTransfer (TAPI32.@)
 */
1331
DWORD WINAPI lineSetupTransferA(HCALL hCall, LPHCALL lphConsultCall, LPLINECALLPARAMS lpCallParams)
1332
{
1333
    FIXME("(%p, %p, %p): stub.\n", hCall, lphConsultCall, lpCallParams);
1334
    return 1;
1335
}
1336

1337 1338 1339
/***********************************************************************
 *		lineShutdown (TAPI32.@)
 */
1340 1341
DWORD WINAPI lineShutdown(HLINEAPP hLineApp)
{
1342
    FIXME("(%p): stub.\n", hLineApp);
1343 1344 1345
    return 0;
}

1346 1347 1348
/***********************************************************************
 *		lineSwapHold (TAPI32.@)
 */
1349 1350
DWORD WINAPI lineSwapHold(HCALL hActiveCall, HCALL hHeldCall)
{
1351
    FIXME("(active: %p, held: %p): stub.\n", hActiveCall, hHeldCall);
1352 1353 1354
    return 1;
}

1355 1356 1357
/***********************************************************************
 *		lineTranslateAddress (TAPI32.@)
 */
1358
DWORD WINAPI lineTranslateAddressA(HLINEAPP hLineApp, DWORD dwDeviceID, DWORD dwAPIVersion, LPCSTR lpszAddressIn, DWORD dwCard, DWORD dwTranslateOptions, LPLINETRANSLATEOUTPUT lpTranslateOutput)
1359
{
1360
    FIXME("(%p, %08x, %08x, %s, %08x, %08x, %p): stub.\n", hLineApp, dwDeviceID, dwAPIVersion, lpszAddressIn, dwCard, dwTranslateOptions, lpTranslateOutput);
1361 1362 1363
    return 0;
}

1364 1365 1366
/***********************************************************************
 *		lineTranslateDialog (TAPI32.@)
 */
1367
DWORD WINAPI lineTranslateDialogA(HLINEAPP hLineApp, DWORD dwDeviceID, DWORD dwAPIVersion, HWND hwndOwner, LPCSTR lpszAddressIn)
1368
{
1369
    FIXME("(%p, %08x, %08x, %p, %s): stub.\n", hLineApp, dwDeviceID, dwAPIVersion, hwndOwner, lpszAddressIn);
1370 1371 1372
    return 0;
}

1373 1374 1375
/***********************************************************************
 *		lineUncompleteCall (TAPI32.@)
 */
1376 1377
DWORD WINAPI lineUncompleteCall(HLINE hLine, DWORD dwCompletionID)
{
1378
    FIXME("(%p, %08x): stub.\n", hLine, dwCompletionID);
1379 1380 1381
    return 1;
}

1382 1383 1384
/***********************************************************************
 *		lineUnhold (TAPI32.@)
 */
1385
DWORD WINAPI lineUnhold(HCALL hCall)
1386
{
1387
    FIXME("(%p): stub.\n", hCall);
1388 1389 1390
    return 1;
}

1391 1392 1393
/***********************************************************************
 *		lineUnpark (TAPI32.@)
 */
1394
DWORD WINAPI lineUnparkA(HLINE hLine, DWORD dwAddressID, LPHCALL lphCall, LPCSTR lpszDestAddress)
1395
{
1396
    FIXME("(%p, %08x, %p, %s): stub.\n", hLine, dwAddressID, lphCall, lpszDestAddress);
1397
    return 1;
1398
}