winhttp, wininet: Load i2d_X509 from libcrypto.so.
[wine] / dlls / tapi32 / line.c
1 /*
2  * TAPI32 line services
3  *
4  * Copyright 1999  Andreas Mohr
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * 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 #include <string.h>
22 #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 /* registry keys */
38 static const char szCountrylistKey[] =
39     "Software\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Country List";
40 static const char szLocationsKey[] =
41     "Software\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Locations";
42 static const char szCardsKey[] =
43     "Software\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Cards";
44
45
46 /***********************************************************************
47  *              lineAccept (TAPI32.@)
48  */
49 DWORD WINAPI lineAccept(HCALL hCall, LPCSTR lpsUserUserInfo, DWORD dwSize)
50 {
51     FIXME("(%p, %s, %d): stub.\n", hCall, lpsUserUserInfo, dwSize);
52     return 1;
53 }
54
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     return LINEERR_OPERATIONFAILED;
62 }
63
64 /***********************************************************************
65  *              lineAddProviderW (TAPI32.@)
66  */
67 DWORD WINAPI lineAddProviderW(LPCWSTR lpszProviderName, HWND hwndOwner, LPDWORD lpdwPermanentProviderID)
68 {
69     FIXME("(%s, %p, %p): stub.\n", wine_dbgstr_w(lpszProviderName), hwndOwner, lpdwPermanentProviderID);
70     return LINEERR_OPERATIONFAILED;
71 }
72
73 /***********************************************************************
74  *              lineAddToConference (TAPI32.@)
75  */
76 DWORD WINAPI lineAddToConference(HCALL hConfCall, HCALL hConsultCall)
77 {
78     FIXME("(%p, %p): stub.\n", hConfCall, hConsultCall);
79     return 1;
80 }
81
82 /***********************************************************************
83  *              lineAnswer (TAPI32.@)
84  */
85 DWORD WINAPI lineAnswer(HCALL hCall, LPCSTR lpsUserUserInfo, DWORD dwSize)
86 {
87     FIXME("(%p, %s, %d): stub.\n", hCall, lpsUserUserInfo, dwSize);
88     return 1;
89 }
90
91 /***********************************************************************
92  *              lineBlindTransfer (TAPI32.@)
93  */
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  *              lineClose (TAPI32.@)
102  */
103 DWORD WINAPI lineClose(HLINE hLine)
104 {
105     FIXME("(%p): stub.\n", hLine);
106     return 0;
107 }
108
109 /***********************************************************************
110  *              lineCompleteCall (TAPI32.@)
111  */
112 DWORD WINAPI lineCompleteCall(HCALL hCall, LPDWORD lpdwCompletionID, DWORD dwCompletionMode, DWORD dwMessageID)
113 {
114     FIXME("(%p, %p, %08x, %08x): stub.\n", hCall, lpdwCompletionID, dwCompletionMode, dwMessageID);
115     return 1;
116 }
117
118 /***********************************************************************
119  *              lineCompleteTransfer (TAPI32.@)
120  */
121 DWORD WINAPI lineCompleteTransfer(HCALL hCall, HCALL hConsultCall, LPHCALL lphConfCall, DWORD dwTransferMode)
122 {
123     FIXME("(%p, %p, %p, %08x): stub.\n", hCall, hConsultCall, lphConfCall, dwTransferMode);
124     return 1;
125 }
126
127 /***********************************************************************
128  *              lineConfigDialog (TAPI32.@)
129  */
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  *              lineConfigDialogEdit (TAPI32.@)
138  */
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  *              lineConfigProvider (TAPI32.@)
147  */
148 DWORD WINAPI lineConfigProvider(HWND hwndOwner, DWORD dwPermanentProviderID)
149 {
150     FIXME("(%p, %08x): stub.\n", hwndOwner, dwPermanentProviderID);
151     return 0;
152 }
153
154 /***********************************************************************
155  *              lineDeallocateCall (TAPI32.@)
156  */
157 DWORD WINAPI lineDeallocateCall(HCALL hCall)
158 {
159     FIXME("(%p): stub.\n", hCall);
160     return 0;
161 }
162
163 /***********************************************************************
164  *              lineDevSpecific (TAPI32.@)
165  */
166 DWORD WINAPI lineDevSpecific(HLINE hLine, DWORD dwAddressId, HCALL hCall, LPVOID lpParams, DWORD dwSize)
167 {
168     FIXME("(%p, %08x, %p, %p, %d): stub.\n", hLine, dwAddressId, hCall, lpParams, dwSize);
169     return 1;
170 }
171
172 /***********************************************************************
173  *              lineDevSpecificFeature (TAPI32.@)
174  */
175 DWORD WINAPI lineDevSpecificFeature(HLINE hLine, DWORD dwFeature, LPVOID lpParams, DWORD dwSize)
176 {
177     FIXME("(%p, %08x, %p, %d): stub.\n", hLine, dwFeature, lpParams, dwSize);
178     return 1;
179 }
180
181 /***********************************************************************
182  *              lineDial (TAPI32.@)
183  */
184 DWORD WINAPI lineDialA(HCALL hCall, LPCSTR lpszDestAddress, DWORD dwCountryCode)
185 {
186     FIXME("(%p, %s, %08x): stub.\n", hCall, lpszDestAddress, dwCountryCode);
187     return 1;
188 }
189
190 /***********************************************************************
191  *              lineDrop (TAPI32.@)
192  */
193 DWORD WINAPI lineDrop(HCALL hCall, LPCSTR lpsUserUserInfo, DWORD dwSize)
194 {
195     FIXME("(%p, %s, %08x): stub.\n", hCall, lpsUserUserInfo, dwSize);
196     return 1;
197 }
198
199 /***********************************************************************
200  *              lineForward (TAPI32.@)
201  */
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     return 0;
215 }
216
217 /***********************************************************************
218  *              lineGenerateDigits (TAPI32.@)
219  */
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     return 0;
224 }
225
226 /***********************************************************************
227  *              lineGenerateTone (TAPI32.@)
228  */
229 DWORD WINAPI lineGenerateTone(HCALL hCall, DWORD dwToneMode, DWORD dwDuration, DWORD dwNumTones, LPLINEGENERATETONE lpTones)
230 {
231     FIXME("(%p, %08x, %d, %d, %p): stub.\n", hCall, dwToneMode, dwDuration, dwNumTones, lpTones);
232     return 0;
233 }
234
235 /***********************************************************************
236  *              lineGetAddressCaps (TAPI32.@)
237  */
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     return 0;
242 }
243
244 /***********************************************************************
245  *              lineGetAddressID (TAPI32.@)
246  */
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     return 0;
251 }
252
253 /***********************************************************************
254  *              lineGetAddressStatus (TAPI32.@)
255  */
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  *              lineGetAppPriority (TAPI32.@)
264  */
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  *              lineGetCallInfo (TAPI32.@)
273  */
274 DWORD WINAPI lineGetCallInfoA(HCALL hCall, LPLINECALLINFO lpCallInfo)
275 {
276     FIXME("(%p, %p): stub.\n", hCall, lpCallInfo);
277     return 0;
278 }
279
280 /***********************************************************************
281  *              lineGetCallStatus (TAPI32.@)
282  */
283 DWORD WINAPI lineGetCallStatus(HCALL hCall, LPLINECALLSTATUS lpCallStatus)
284 {
285     FIXME("(%p, %p): stub.\n", hCall, lpCallStatus);
286     return 0;
287 }
288
289 /***********************************************************************
290  *              lineGetConfRelatedCalls (TAPI32.@)
291  */
292 DWORD WINAPI lineGetConfRelatedCalls(HCALL hCall, LPLINECALLLIST lpCallList)
293 {
294     FIXME("(%p, %p): stub.\n", hCall, lpCallList);
295     return 0;
296 }
297
298 typedef struct tagTAPI_CountryInfo
299 {
300     DWORD  dwCountryID;
301     DWORD  dwCountryCode;
302     LPSTR  lpCountryName;
303     LPSTR  lpSameAreaRule;
304     LPSTR  lpLongDistanceRule;
305     LPSTR  lpInternationalRule;
306 } TAPI_CountryInfo;
307
308 /***********************************************************************
309  *              lineGetCountry (TAPI32.@)
310  */
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     HKEY hkey;
316     char *subkey_name;
317
318     if(!lpLineCountryList) {
319         TRACE("(%08x, %08x, %p): stub. Returning LINEERR_INVALPOINTER\n",
320               dwCountryID, dwAPIVersion, lpLineCountryList);
321         return LINEERR_INVALPOINTER;
322     }
323
324     TRACE("(%08x, %08x, %p(%d)): stub.\n",
325           dwCountryID, dwAPIVersion, lpLineCountryList,
326           lpLineCountryList->dwTotalSize);
327
328     if(RegOpenKeyA(HKEY_LOCAL_MACHINE, szCountrylistKey, &hkey)
329             != ERROR_SUCCESS)
330         return LINEERR_INIFILECORRUPT;
331
332
333     dwAvailSize = lpLineCountryList->dwTotalSize;
334     dwOffset = sizeof (LINECOUNTRYLIST);
335
336     if(dwAvailSize<dwOffset)
337         return LINEERR_STRUCTURETOOSMALL;
338
339     memset(lpLineCountryList, 0, dwAvailSize);
340
341     lpLineCountryList->dwTotalSize         = dwAvailSize;
342     lpLineCountryList->dwUsedSize          = dwOffset;
343     lpLineCountryList->dwNumCountries      = 0;
344     lpLineCountryList->dwCountryListSize   = 0;
345     lpLineCountryList->dwCountryListOffset = dwOffset;
346
347     lpLCE = (LPLINECOUNTRYENTRY)(&lpLineCountryList[1]);
348
349     if(RegQueryInfoKeyA(hkey, NULL, NULL, NULL, &num_countries, &max_subkey_len,
350                         NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
351         RegCloseKey(hkey);
352         return LINEERR_STRUCTURETOOSMALL;
353     }
354
355     if(dwCountryID)
356         dwOffset = sizeof (LINECOUNTRYENTRY);
357     else
358         dwOffset += num_countries * sizeof (LINECOUNTRYENTRY);
359
360     max_subkey_len++;
361     subkey_name = HeapAlloc(GetProcessHeap(), 0, max_subkey_len);
362     for(i = 0; i < num_countries; i++)
363     {
364         DWORD len, size, size_int, size_long, size_name, size_same;
365         HKEY hsubkey;
366
367         if(RegEnumKeyA(hkey, i, subkey_name, max_subkey_len) !=
368            ERROR_SUCCESS)
369             continue;
370
371         if(dwCountryID && (atoi(subkey_name) != dwCountryID))
372             continue;
373
374         if(RegOpenKeyA(hkey, subkey_name, &hsubkey) != ERROR_SUCCESS)
375             continue;
376
377         RegQueryValueExA(hsubkey, "InternationalRule", NULL, NULL,
378                          NULL, &size_int);
379         len  = size_int;
380
381         RegQueryValueExA(hsubkey, "LongDistanceRule", NULL, NULL,
382                          NULL, &size_long);
383         len += size_long;
384
385         RegQueryValueExA(hsubkey, "Name", NULL, NULL,
386                          NULL, &size_name);
387         len += size_name;
388
389         RegQueryValueExA(hsubkey, "SameAreaRule", NULL, NULL,
390                          NULL, &size_same);
391         len += size_same;
392
393         if(dwAvailSize < (dwOffset+len))
394         {
395             dwOffset += len;
396             RegCloseKey(hsubkey);
397             if(dwCountryID)
398                 break;
399             continue;
400         }
401
402         lpLineCountryList->dwNumCountries++;
403         lpLineCountryList->dwCountryListSize += sizeof (LINECOUNTRYENTRY);
404         lpLineCountryList->dwUsedSize += len + sizeof (LINECOUNTRYENTRY);
405
406         if(dwCountryID)
407             i = 0;
408
409         lpLCE[i].dwCountryID = atoi(subkey_name);
410         size = sizeof(DWORD);
411         RegQueryValueExA(hsubkey, "CountryCode", NULL, NULL,
412                          (BYTE*)&lpLCE[i].dwCountryCode, &size);
413
414         lpLCE[i].dwNextCountryID = 0;
415         
416         if(i > 0)
417             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                          &size_name);
425         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                          &size_same);
433         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                          &size_long);
441         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                          &size_int);
449         dwOffset += size_int;
450         RegCloseKey(hsubkey);
451
452         TRACE("Added country %s at %p\n", (LPSTR)lpLineCountryList + lpLCE[i].dwCountryNameOffset,
453               &lpLCE[i]);
454
455         if(dwCountryID) break;
456     }
457
458     lpLineCountryList->dwNeededSize = dwOffset;
459
460     TRACE("%d available %d required\n", dwAvailSize, dwOffset);
461
462     HeapFree(GetProcessHeap(), 0, subkey_name);
463     RegCloseKey(hkey);
464
465     return 0;
466 }
467
468 /***********************************************************************
469  *              lineGetDevCaps (TAPI32.@)
470  */
471 DWORD WINAPI lineGetDevCapsA(HLINEAPP hLineApp, DWORD dwDeviceID, DWORD dwAPIVersion, DWORD dwExtVersion, LPLINEDEVCAPS lpLineDevCaps)
472 {
473     FIXME("(%p, %08x, %08x, %08x, %p): stub.\n", hLineApp, dwDeviceID, dwAPIVersion, dwExtVersion, lpLineDevCaps);
474     return 0;
475 }
476
477 /***********************************************************************
478  *              lineGetDevConfig (TAPI32.@)
479  */
480 DWORD WINAPI lineGetDevConfigA(DWORD dwDeviceID, LPVARSTRING lpDeviceConfig, LPCSTR lpszDeviceClass)
481 {
482     FIXME("(%08x, %p, %s): stub.\n", dwDeviceID, lpDeviceConfig, lpszDeviceClass);
483     return 0;
484 }
485
486 /***********************************************************************
487  *              lineGetID (TAPI32.@)
488  */
489 DWORD WINAPI lineGetIDA(HLINE hLine, DWORD dwAddressID, HCALL hCall, DWORD dwSelect, LPVARSTRING lpDeviceID, LPCSTR lpszDeviceClass)
490 {
491     FIXME("(%p, %08x, %p, %08x, %p, %s): stub.\n", hLine, dwAddressID, hCall, dwSelect, lpDeviceID, lpszDeviceClass);
492     return 0;
493 }
494
495 /***********************************************************************
496  *              lineGetIcon (TAPI32.@)
497  */
498 DWORD WINAPI lineGetIconA(DWORD dwDeviceID, LPCSTR lpszDeviceClass, HICON *lphIcon)
499 {
500     FIXME("(%08x, %s, %p): stub.\n", dwDeviceID, lpszDeviceClass, lphIcon);
501     return 0;
502 }
503
504 /***********************************************************************
505  *              lineGetLineDevStatus (TAPI32.@)
506  */
507 DWORD WINAPI lineGetLineDevStatusA(HLINE hLine, LPLINEDEVSTATUS lpLineDevStatus)
508 {
509     FIXME("(%p, %p): stub.\n", hLine, lpLineDevStatus);
510     return 0;
511 }
512
513 /***********************************************************************
514  *              lineGetNewCalls (TAPI32.@)
515  */
516 DWORD WINAPI lineGetNewCalls(HLINE hLine, DWORD dwAddressID, DWORD dwSelect, LPLINECALLLIST lpCallList)
517 {
518     FIXME("(%p, %08x, %08x, %p): stub.\n", hLine, dwAddressID, dwSelect, lpCallList);
519     return 0;
520 }
521
522 /***********************************************************************
523  *              lineGetNumRings (TAPI32.@)
524  */
525 DWORD WINAPI lineGetNumRings(HLINE hLine, DWORD dwAddressID, LPDWORD lpdwNumRings)
526 {
527     FIXME("(%p, %08x, %p): stub.\n", hLine, dwAddressID, lpdwNumRings);
528     return 0;
529 }
530
531 /***********************************************************************
532  *              lineGetProviderListA (TAPI32.@)
533  */
534 DWORD WINAPI lineGetProviderListA(DWORD dwAPIVersion, LPLINEPROVIDERLIST lpProviderList)
535 {
536     FIXME("(%08x, %p): stub.\n", dwAPIVersion, lpProviderList);
537     return LINEERR_OPERATIONFAILED;
538 }
539
540 /***********************************************************************
541  *              lineGetProviderListW (TAPI32.@)
542  */
543 DWORD WINAPI lineGetProviderListW(DWORD dwAPIVersion, LPLINEPROVIDERLIST lpProviderList)
544 {
545     FIXME("(%08x, %p): stub.\n", dwAPIVersion, lpProviderList);
546     return LINEERR_OPERATIONFAILED;
547 }
548
549 /***********************************************************************
550  *              lineGetRequest (TAPI32.@)
551  */
552 DWORD WINAPI lineGetRequestA(HLINEAPP hLineApp, DWORD dwRequestMode, LPVOID lpRequestBuffer)
553 {
554     FIXME("%p, %08x, %p): stub.\n", hLineApp, dwRequestMode, lpRequestBuffer);
555     return 0;
556 }
557
558 /***********************************************************************
559  *              lineGetStatusMessages (TAPI32.@)
560  */
561 DWORD WINAPI lineGetStatusMessages(HLINE hLine, LPDWORD lpdwLineStatus, LPDWORD lpdwAddressStates)
562 {
563     FIXME("(%p, %p, %p): stub.\n", hLine, lpdwLineStatus, lpdwAddressStates);
564     return 0;
565 }
566
567 /***********************************************************************
568  *              lineGetTranslateCaps (TAPI32.@)
569  *
570  *      get address translate capabilities. Returns a LINETRANSLATECAPS
571  *      structure:
572  *
573  *      +-----------------------+
574  *      |TotalSize              |
575  *      |NeededSize             |
576  *      |UsedSize               |
577  *      +-----------------------+
578  *      |NumLocations           |
579  *      |LocationsListSize      |
580  *      |LocationsListOffset    | -+
581  *      |CurrentLocationID      |  |
582  *      +-----------------------+  |
583  *      |NumCards               |  |
584  *      |CardListSize           |  |
585  *      |CardListOffset         | -|--+
586  *      |CurrentPreferredCardID |  |  |
587  *      +-----------------------+  |  |
588  *      |                       | <+  |
589  *      |LINELOCATIONENTRY #1   |     |
590  *      |                       |     |
591  *      +-----------------------+     |
592  *      ~                       ~     |
593  *      +-----------------------+     |
594  *      |                       |     |
595  *      |LINELOCATIONENTRY      |     |
596  *      |          #NumLocations|     |
597  *      +-----------------------+     |
598  *      |                       | <---+
599  *      |LINECARDENTRY #1       |
600  *      |                       |
601  *      +-----------------------+
602  *      ~                       ~
603  *      +-----------------------+
604  *      |                       |
605  *      |LINECARDENTRY #NumCards|
606  *      |                       |
607  *      +-----------------------+
608  *      | room for strings named|
609  *      | in the structures     |
610  *      | above.                |
611  *      +-----------------------+
612  */
613 DWORD WINAPI lineGetTranslateCapsA(HLINEAPP hLineApp, DWORD dwAPIVersion,
614         LPLINETRANSLATECAPS lpTranslateCaps)
615 {
616     HKEY hkLocations, hkCards, hkCardLocations, hsubkey;
617     int numlocations, numcards;
618     DWORD maxlockeylen,
619         maxcardkeylen;
620     char *loc_key_name = NULL;
621     char *card_key_name = NULL;
622     LPBYTE strptr;
623     int length;
624     int i;
625     DWORD lendword;
626     DWORD currentid;
627     LPLINELOCATIONENTRY pLocEntry;
628     LPLINECARDENTRY pCardEntry;
629     
630     TRACE("(%p, %08x, %p (tot. size %d)\n", hLineApp, dwAPIVersion,
631             lpTranslateCaps, lpTranslateCaps->dwTotalSize );
632     if( lpTranslateCaps->dwTotalSize < sizeof(LINETRANSLATECAPS))
633         return LINEERR_STRUCTURETOOSMALL;
634     if( RegCreateKeyA(HKEY_LOCAL_MACHINE, szLocationsKey, &hkLocations)
635             != ERROR_SUCCESS ) {
636         ERR("unexpected registry error 1.\n");
637         return LINEERR_INIFILECORRUPT;  
638     }
639     lendword = sizeof( DWORD);
640     if( RegQueryValueExA( hkLocations, "CurrentID", NULL, NULL,
641                 (LPBYTE) &currentid, &lendword) != ERROR_SUCCESS )
642         currentid = -1;  /* change this later */
643     if(RegQueryInfoKeyA(hkLocations, NULL, NULL, NULL, NULL, &maxlockeylen,
644                         NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
645         RegCloseKey(hkLocations);
646         ERR("unexpected registry error 2.\n");
647         return LINEERR_INIFILECORRUPT;
648     }
649     maxlockeylen++;
650     if( maxlockeylen < 10)
651         maxlockeylen = 10; /* need this also if there is no key */
652     loc_key_name = HeapAlloc( GetProcessHeap(), 0, maxlockeylen);
653     /* first time through: calculate needed space */
654     length=0;
655     i=0;
656     numlocations=0;
657     while( RegEnumKeyA(hkLocations, i, loc_key_name, maxlockeylen)
658             == ERROR_SUCCESS){
659         DWORD size_val;
660         i++;
661         if( strncasecmp(loc_key_name, "location", 8)  ||
662                 (RegOpenKeyA(hkLocations, loc_key_name, &hsubkey)
663                  != ERROR_SUCCESS))
664             continue;
665         numlocations++;
666         length += sizeof(LINELOCATIONENTRY);
667         RegQueryValueExA(hsubkey, "Name",NULL,NULL,NULL,&size_val); 
668         length += size_val;
669         RegQueryValueExA(hsubkey, "AreaCode",NULL,NULL,NULL,&size_val); 
670         length += size_val;
671         RegQueryValueExA(hsubkey, "OutsideAccess",NULL,NULL,NULL,&size_val); 
672         length += size_val;
673         RegQueryValueExA(hsubkey, "LongDistanceAccess",NULL,NULL,NULL,&size_val); 
674         length += size_val;
675         RegQueryValueExA(hsubkey, "DisableCallWaiting",NULL,NULL,NULL,&size_val); 
676         length += size_val;
677         /* fixme: what about TollPrefixList???? */
678         RegCloseKey(hsubkey);
679     }
680     if(numlocations == 0) {
681         /* add one location */
682         if( RegCreateKeyA( hkLocations, "Location1", &hsubkey)
683                 == ERROR_SUCCESS) {
684             DWORD dwval;
685             char buf[10];
686             numlocations = 1;
687             length += sizeof(LINELOCATIONENTRY) + 20 ;
688             RegSetValueExA( hsubkey, "AreaCode", 0, REG_SZ, (const BYTE *)"010", 4);
689             GetLocaleInfoA( LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, buf, 8);
690             dwval = atoi(buf);
691             RegSetValueExA( hsubkey, "Country", 0, REG_DWORD, (LPBYTE)&dwval,
692                     sizeof(DWORD));
693             RegSetValueExA( hsubkey, "DisableCallWaiting", 0, REG_SZ, (const BYTE *)"", 1);
694             dwval = 1;  
695             RegSetValueExA( hsubkey, "Flags", 0, REG_DWORD, (LPBYTE)&dwval,
696                     sizeof(DWORD));
697             RegSetValueExA( hsubkey, "LongDistanceAccess", 0, REG_SZ, (const BYTE *)"", 1);
698             RegSetValueExA( hsubkey, "Name", 0, REG_SZ, (const BYTE *)"New Location", 13);
699             RegSetValueExA( hsubkey, "OutsideAccess", 0, REG_SZ, (const BYTE *)"", 1);
700             RegCloseKey(hsubkey);
701             dwval = 1;  
702             RegSetValueExA( hkLocations, "CurrentID", 0, REG_DWORD,
703                     (LPBYTE)&dwval, sizeof(DWORD));
704             dwval = 2;  
705             RegSetValueExA( hkLocations, "NextID", 0, REG_DWORD, (LPBYTE)&dwval,
706                     sizeof(DWORD));
707         }
708     }
709     /* do the card list */
710     numcards=0;
711     if( RegCreateKeyA(HKEY_CURRENT_USER, szCardsKey, &hkCards)
712             == ERROR_SUCCESS ) {
713         if(RegQueryInfoKeyA(hkCards, NULL, NULL, NULL, NULL, &maxcardkeylen,
714                 NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
715             maxcardkeylen++;
716             if( maxcardkeylen < 6) maxcardkeylen = 6;
717             card_key_name = HeapAlloc(GetProcessHeap(), 0, maxcardkeylen);
718             i=0;
719             while( RegEnumKeyA(hkCards, i, card_key_name, maxcardkeylen) ==
720                     ERROR_SUCCESS){
721                 DWORD size_val;
722                 i++;
723                 if( strncasecmp(card_key_name, "card", 4)  || ERROR_SUCCESS !=
724                         (RegOpenKeyA(hkCards, card_key_name, &hsubkey) ))
725                     continue;
726                 numcards++;
727                 length += sizeof(LINECARDENTRY);
728                 RegQueryValueExA(hsubkey, "Name",NULL,NULL,NULL,&size_val); 
729                 length += size_val;
730                 RegQueryValueExA(hsubkey, "LocalRule",NULL,NULL,NULL,&size_val); 
731                 length += size_val;
732                 RegQueryValueExA(hsubkey, "LDRule",NULL,NULL,NULL,&size_val); 
733                 length += size_val;
734                 RegQueryValueExA(hsubkey, "InternationalRule",NULL,NULL,NULL,
735                         &size_val); 
736                 length += size_val;
737                 RegCloseKey(hsubkey);
738             }
739         }
740         /* add one card (direct call) */
741         if (numcards == 0 &&
742                 ERROR_SUCCESS == RegCreateKeyA( hkCards, "Card1", &hsubkey)) {
743             DWORD dwval;
744             numcards = 1;
745             length += sizeof(LINECARDENTRY) + 22 ;
746             RegSetValueExA( hsubkey, "Name", 0, REG_SZ, (const BYTE *)"None (Direct Call)", 19);
747             dwval = 1;  
748             RegSetValueExA( hsubkey, "Flags", 0, REG_DWORD, (LPBYTE)&dwval,
749                     sizeof(DWORD));
750             RegSetValueExA( hsubkey, "InternationalRule", 0, REG_SZ, (const BYTE *)"", 1);
751             RegSetValueExA( hsubkey, "LDRule", 0, REG_SZ, (const BYTE *)"", 1);
752             RegSetValueExA( hsubkey, "LocalRule", 0, REG_SZ, (const BYTE *)"", 1);
753             RegCloseKey(hsubkey);
754             dwval = 2;  
755             RegSetValueExA( hkCards, "NextID", 0, REG_DWORD, (LPBYTE)&dwval,
756                     sizeof(DWORD));
757         }
758     } else hkCards = 0;  /* should really fail */
759     /* check if sufficient room is available */
760     lpTranslateCaps->dwNeededSize =  sizeof(LINETRANSLATECAPS) + length;
761     if ( lpTranslateCaps->dwNeededSize > lpTranslateCaps->dwTotalSize ) {
762         RegCloseKey( hkLocations);
763         if( hkCards) RegCloseKey( hkCards);
764         HeapFree(GetProcessHeap(), 0, loc_key_name);
765         HeapFree(GetProcessHeap(), 0, card_key_name);
766         lpTranslateCaps->dwUsedSize = sizeof(LINETRANSLATECAPS);
767         TRACE("Insufficient space: total %d needed %d used %d\n",
768                 lpTranslateCaps->dwTotalSize,
769                 lpTranslateCaps->dwNeededSize,
770                 lpTranslateCaps->dwUsedSize);
771         return  0;
772     }
773     /* fill in the LINETRANSLATECAPS structure */
774     lpTranslateCaps->dwUsedSize = lpTranslateCaps->dwNeededSize;
775     lpTranslateCaps->dwNumLocations = numlocations;
776     lpTranslateCaps->dwLocationListSize = sizeof(LINELOCATIONENTRY) *
777             lpTranslateCaps->dwNumLocations;
778     lpTranslateCaps->dwLocationListOffset = sizeof(LINETRANSLATECAPS);
779     lpTranslateCaps->dwCurrentLocationID = currentid; 
780     lpTranslateCaps->dwNumCards = numcards;
781     lpTranslateCaps->dwCardListSize = sizeof(LINECARDENTRY) *
782             lpTranslateCaps->dwNumCards;
783     lpTranslateCaps->dwCardListOffset = lpTranslateCaps->dwLocationListOffset +
784             lpTranslateCaps->dwLocationListSize;
785     lpTranslateCaps->dwCurrentPreferredCardID = 0; 
786     /* this is where the strings will be stored */
787     strptr = ((LPBYTE) lpTranslateCaps) +
788         lpTranslateCaps->dwCardListOffset + lpTranslateCaps->dwCardListSize;
789     pLocEntry = (LPLINELOCATIONENTRY) (lpTranslateCaps + 1);
790     /* key with Preferred CardID's */
791     if( RegOpenKeyA(HKEY_CURRENT_USER, szLocationsKey, &hkCardLocations)
792             != ERROR_SUCCESS ) 
793         hkCardLocations = 0;
794     /* second time through all locations */
795     i=0;
796     while(RegEnumKeyA(hkLocations, i, loc_key_name, maxlockeylen)
797             == ERROR_SUCCESS){
798         DWORD size_val;
799         i++;
800         if( strncasecmp(loc_key_name, "location", 8)  ||
801                 (RegOpenKeyA(hkLocations, loc_key_name, &hsubkey)
802                  != ERROR_SUCCESS))
803             continue;
804         size_val=sizeof(DWORD);
805         if( RegQueryValueExA(hsubkey, "ID",NULL, NULL,
806                 (LPBYTE) &(pLocEntry->dwPermanentLocationID), &size_val) !=
807                 ERROR_SUCCESS)
808             pLocEntry->dwPermanentLocationID = atoi( loc_key_name + 8);
809         size_val=2048;
810         RegQueryValueExA(hsubkey, "Name",NULL,NULL, strptr, &size_val);
811         pLocEntry->dwLocationNameSize = size_val;
812         pLocEntry->dwLocationNameOffset = strptr - (LPBYTE) lpTranslateCaps;
813         strptr += size_val;
814  
815         size_val=2048;
816         RegQueryValueExA(hsubkey, "AreaCode",NULL,NULL, strptr, &size_val);
817         pLocEntry->dwCityCodeSize = size_val;
818         pLocEntry->dwCityCodeOffset = strptr - (LPBYTE) lpTranslateCaps;
819         strptr += size_val;
820         
821         size_val=2048;
822         RegQueryValueExA(hsubkey, "OutsideAccess",NULL,NULL, strptr, &size_val);
823         pLocEntry->dwLocalAccessCodeSize = size_val;
824         pLocEntry->dwLocalAccessCodeOffset = strptr - (LPBYTE) lpTranslateCaps;
825         strptr += size_val;
826         size_val=2048;
827         RegQueryValueExA(hsubkey, "LongDistanceAccess",NULL,NULL, strptr,
828                 &size_val);
829         pLocEntry->dwLongDistanceAccessCodeSize= size_val;
830         pLocEntry->dwLongDistanceAccessCodeOffset= strptr -
831             (LPBYTE) lpTranslateCaps;
832         strptr += size_val;
833         size_val=2048;
834         RegQueryValueExA(hsubkey, "DisableCallWaiting",NULL,NULL, strptr,
835                 &size_val);
836         pLocEntry->dwCancelCallWaitingSize= size_val;
837         pLocEntry->dwCancelCallWaitingOffset= strptr - (LPBYTE) lpTranslateCaps;
838         strptr += size_val;
839
840         pLocEntry->dwTollPrefixListSize = 0;    /* FIXME */
841         pLocEntry->dwTollPrefixListOffset = 0;    /* FIXME */
842
843         size_val=sizeof(DWORD);
844         RegQueryValueExA(hsubkey, "Country",NULL,NULL,
845                 (LPBYTE) &(pLocEntry->dwCountryCode), &size_val);
846         pLocEntry->dwCountryID = pLocEntry->dwCountryCode; /* FIXME */
847         RegQueryValueExA(hsubkey, "Flags",NULL,NULL,
848                 (LPBYTE) &(pLocEntry->dwOptions), &size_val);
849         RegCloseKey(hsubkey);
850         /* get preferred cardid */
851         pLocEntry->dwPreferredCardID = 0;
852         if ( hkCardLocations) {
853             size_val=sizeof(DWORD);
854             if(RegOpenKeyA(hkCardLocations, loc_key_name, &hsubkey) ==
855                     ERROR_SUCCESS) {
856                 RegQueryValueExA(hsubkey, "CallingCard",NULL,NULL,
857                         (LPBYTE) &(pLocEntry->dwPreferredCardID), &size_val);
858                 RegCloseKey(hsubkey);
859             }
860                 
861         }
862         /* make sure there is a currentID */
863         if(currentid == -1){
864             currentid = pLocEntry->dwPermanentLocationID;
865             lpTranslateCaps->dwCurrentLocationID = currentid; 
866         }
867         if(pLocEntry->dwPermanentLocationID == currentid )
868             lpTranslateCaps->dwCurrentPreferredCardID =
869                     pLocEntry->dwPreferredCardID;
870         TRACE("added: ID %d %s CountryCode %d CityCode %s CardID %d "
871                 "LocalAccess: %s LongDistanceAccess: %s CountryID %d "
872                 "Options %d CancelCallWait %s\n",
873                 pLocEntry->dwPermanentLocationID,
874                 debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwLocationNameOffset),
875                 pLocEntry->dwCountryCode,
876                 debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwCityCodeOffset),
877                 pLocEntry->dwPreferredCardID,
878                 debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwLocalAccessCodeOffset),
879                 debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwLongDistanceAccessCodeOffset),
880                 pLocEntry->dwCountryID,
881                 pLocEntry->dwOptions,
882                 debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwCancelCallWaitingOffset));
883         pLocEntry++;
884     }
885     pCardEntry= (LPLINECARDENTRY) pLocEntry;
886     /* do the card list */
887     if( hkCards) {
888         i=0;
889         while( RegEnumKeyA(hkCards, i, card_key_name, maxcardkeylen) ==
890                 ERROR_SUCCESS){
891             DWORD size_val;
892             i++;
893             if( strncasecmp(card_key_name, "card", 4)  ||
894                     (RegOpenKeyA(hkCards, card_key_name, &hsubkey) != ERROR_SUCCESS))
895                 continue;
896             size_val=sizeof(DWORD);
897             if( RegQueryValueExA(hsubkey, "ID",NULL, NULL,
898                     (LPBYTE) &(pCardEntry->dwPermanentCardID), &size_val) !=
899                     ERROR_SUCCESS)
900                 pCardEntry->dwPermanentCardID= atoi( card_key_name + 4);
901             size_val=2048;
902             RegQueryValueExA(hsubkey, "Name",NULL,NULL, strptr, &size_val);
903             pCardEntry->dwCardNameSize = size_val;
904             pCardEntry->dwCardNameOffset = strptr - (LPBYTE) lpTranslateCaps;
905             strptr += size_val;
906             pCardEntry->dwCardNumberDigits = 1; /* FIXME */
907             size_val=2048;
908             RegQueryValueExA(hsubkey, "LocalRule",NULL,NULL, strptr, &size_val);
909             pCardEntry->dwSameAreaRuleSize= size_val;
910             pCardEntry->dwSameAreaRuleOffset= strptr - (LPBYTE) lpTranslateCaps;
911             strptr += size_val;
912             size_val=2048;
913             RegQueryValueExA(hsubkey, "LDRule",NULL,NULL, strptr, &size_val);
914             pCardEntry->dwLongDistanceRuleSize = size_val;
915             pCardEntry->dwLongDistanceRuleOffset = strptr - (LPBYTE) lpTranslateCaps;
916             strptr += size_val;
917             size_val=2048;
918             RegQueryValueExA(hsubkey, "InternationalRule",NULL,NULL, strptr,
919                     &size_val);
920             pCardEntry->dwInternationalRuleSize = size_val;
921             pCardEntry->dwInternationalRuleOffset = strptr -
922                 (LPBYTE) lpTranslateCaps;
923             strptr += size_val;
924             size_val=sizeof(DWORD);
925             RegQueryValueExA(hsubkey, "Flags",NULL, NULL,
926                     (LPBYTE) &(pCardEntry->dwOptions), &size_val); 
927             TRACE( "added card: ID %d name %s SameArea %s LongDistance %s International %s Options 0x%x\n", 
928                     pCardEntry->dwPermanentCardID,
929                     debugstr_a( (char*)lpTranslateCaps + pCardEntry->dwCardNameOffset),
930                     debugstr_a( (char*)lpTranslateCaps + pCardEntry->dwSameAreaRuleOffset),
931                     debugstr_a( (char*)lpTranslateCaps + pCardEntry->dwLongDistanceRuleOffset),
932                     debugstr_a( (char*)lpTranslateCaps + pCardEntry->dwInternationalRuleOffset),
933                     pCardEntry->dwOptions);
934
935             pCardEntry++;
936         }
937     }
938
939     if(hkLocations) RegCloseKey(hkLocations);
940     if(hkCards) RegCloseKey(hkCards);
941     if(hkCardLocations) RegCloseKey(hkCardLocations);
942     HeapFree(GetProcessHeap(), 0, loc_key_name);
943     HeapFree(GetProcessHeap(), 0, card_key_name);
944     TRACE(" returning success tot %d needed %d used %d\n",
945             lpTranslateCaps->dwTotalSize,
946             lpTranslateCaps->dwNeededSize,
947             lpTranslateCaps->dwUsedSize );
948     return 0; /* success */
949 }
950
951 /***********************************************************************
952  *              lineHandoff (TAPI32.@)
953  */
954 DWORD WINAPI lineHandoffA(HCALL hCall, LPCSTR lpszFileName, DWORD dwMediaMode)
955 {
956     FIXME("(%p, %s, %08x): stub.\n", hCall, lpszFileName, dwMediaMode);
957     return 0;
958 }
959
960 /***********************************************************************
961  *              lineHold (TAPI32.@)
962  */
963 DWORD WINAPI lineHold(HCALL hCall)
964 {
965     FIXME("(%p): stub.\n", hCall);
966     return 1;
967 }
968
969 /***********************************************************************
970  *              lineInitialize (TAPI32.@)
971  */
972 DWORD WINAPI lineInitialize(
973   LPHLINEAPP lphLineApp,
974   HINSTANCE hInstance,
975   LINECALLBACK lpfnCallback,
976   LPCSTR lpszAppName,
977   LPDWORD lpdwNumDevs)
978 {
979     FIXME("(%p, %p, %p, %s, %p): stub.\n", lphLineApp, hInstance,
980           lpfnCallback, debugstr_a(lpszAppName), lpdwNumDevs);
981     return 0;
982 }
983
984 /***********************************************************************
985  *              lineInitializeExA (TAPI32.@)
986  */
987 LONG WINAPI lineInitializeExA(LPHLINEAPP lphLineApp, HINSTANCE hInstance, LINECALLBACK lpfnCallback, LPCSTR lpszFriendlyAppName, LPDWORD lpdwNumDevs, LPDWORD lpdwAPIVersion, LPLINEINITIALIZEEXPARAMS lpLineInitializeExParams)
988 {
989     FIXME("(%p, %p, %p, %s, %p, %p, %p): stub.\n", lphLineApp, hInstance,
990           lpfnCallback, debugstr_a(lpszFriendlyAppName), lpdwNumDevs, lpdwAPIVersion, lpLineInitializeExParams);
991     return 0;
992 }
993
994 /***********************************************************************
995  *              lineMakeCall (TAPI32.@)
996  */
997 DWORD WINAPI lineMakeCallA(HLINE hLine, LPHCALL lphCall, LPCSTR lpszDestAddress, DWORD dwCountryCode, LPLINECALLPARAMS lpCallParams)
998 {
999     FIXME("(%p, %p, %s, %08x, %p): stub.\n", hLine, lphCall, lpszDestAddress, dwCountryCode, lpCallParams);
1000     return 1;
1001 }
1002
1003 /***********************************************************************
1004  *              lineMonitorDigits (TAPI32.@)
1005  */
1006 DWORD WINAPI lineMonitorDigits(HCALL hCall, DWORD dwDigitModes)
1007 {
1008     FIXME("(%p, %08x): stub.\n", hCall, dwDigitModes);
1009     return 0;
1010 }
1011
1012 /***********************************************************************
1013  *              lineMonitorMedia (TAPI32.@)
1014  */
1015 DWORD WINAPI lineMonitorMedia(HCALL hCall, DWORD dwMediaModes)
1016 {
1017     FIXME("(%p, %08x): stub.\n", hCall, dwMediaModes);
1018     return 0;
1019 }
1020
1021 /***********************************************************************
1022  *              lineMonitorTones (TAPI32.@)
1023  */
1024 DWORD WINAPI lineMonitorTones(HCALL hCall, LPLINEMONITORTONE lpToneList, DWORD dwNumEntries)
1025 {
1026     FIXME("(%p, %p, %08x): stub.\n", hCall, lpToneList, dwNumEntries);
1027     return 0;
1028 }
1029
1030 /***********************************************************************
1031  *              lineNegotiateAPIVersion (TAPI32.@)
1032  */
1033 DWORD WINAPI lineNegotiateAPIVersion(
1034   HLINEAPP hLineApp,
1035   DWORD dwDeviceID,
1036   DWORD dwAPILowVersion,
1037   DWORD dwAPIHighVersion,
1038   LPDWORD lpdwAPIVersion,
1039   LPLINEEXTENSIONID lpExtensionID
1040 )
1041 {
1042     FIXME("(%p, %d, %d, %d, %p, %p): stub.\n", hLineApp, dwDeviceID,
1043           dwAPILowVersion, dwAPIHighVersion, lpdwAPIVersion, lpExtensionID);
1044     *lpdwAPIVersion = dwAPIHighVersion;
1045     return 0;
1046 }
1047
1048 /***********************************************************************
1049  *              lineNegotiateExtVersion (TAPI32.@)
1050  */
1051 DWORD WINAPI lineNegotiateExtVersion(HLINEAPP hLineApp, DWORD dwDeviceID, DWORD dwAPIVersion, DWORD dwExtLowVersion, DWORD dwExtHighVersion, LPDWORD lpdwExtVersion)
1052 {
1053     FIXME("stub.\n");
1054     return 0;
1055 }
1056
1057 /***********************************************************************
1058  *              lineOpen (TAPI32.@)
1059  */
1060 DWORD WINAPI lineOpenA(HLINEAPP hLineApp, DWORD dwDeviceID, LPHLINE lphLine, DWORD dwAPIVersion, DWORD dwExtVersion, DWORD dwCallbackInstance, DWORD dwPrivileges, DWORD dwMediaModes, LPLINECALLPARAMS lpCallParams)
1061 {
1062     FIXME("stub.\n");
1063     return 0;
1064 }
1065
1066 /***********************************************************************
1067  *              linePark (TAPI32.@)
1068  */
1069 DWORD WINAPI lineParkA(HCALL hCall, DWORD dwParkMode, LPCSTR lpszDirAddress, LPVARSTRING lpNonDirAddress)
1070 {
1071     FIXME("(%p, %08x, %s, %p): stub.\n", hCall, dwParkMode, lpszDirAddress, lpNonDirAddress);
1072     return 1;
1073 }
1074
1075 /***********************************************************************
1076  *              linePickup (TAPI32.@)
1077  */
1078 DWORD WINAPI linePickupA(HLINE hLine, DWORD dwAddressID, LPHCALL lphCall, LPCSTR lpszDestAddress, LPCSTR lpszGroupID)
1079 {
1080     FIXME("(%p, %08x, %p, %s, %s): stub.\n", hLine, dwAddressID, lphCall, lpszDestAddress, lpszGroupID);
1081     return 1;
1082 }
1083
1084 /***********************************************************************
1085  *              linePrepareAddToConference (TAPI32.@)
1086  */
1087 DWORD WINAPI linePrepareAddToConferenceA(HCALL hConfCall, LPHCALL lphConsultCall, LPLINECALLPARAMS lpCallParams)
1088 {
1089     FIXME("(%p, %p, %p): stub.\n", hConfCall, lphConsultCall, lpCallParams);
1090     return 1;
1091 }
1092
1093 /***********************************************************************
1094  *              lineRedirect (TAPI32.@)
1095  */
1096 DWORD WINAPI lineRedirectA(
1097   HCALL hCall,
1098   LPCSTR lpszDestAddress,
1099   DWORD  dwCountryCode) {
1100
1101   FIXME(": stub.\n");
1102   return 1;
1103 }
1104
1105 /***********************************************************************
1106  *              lineRegisterRequestRecipient (TAPI32.@)
1107  */
1108 DWORD WINAPI lineRegisterRequestRecipient(HLINEAPP hLineApp, DWORD dwRegistrationInstance, DWORD dwRequestMode, DWORD dwEnable)
1109 {
1110     FIXME("(%p, %08x, %08x, %08x): stub.\n", hLineApp, dwRegistrationInstance, dwRequestMode, dwEnable);
1111     return 1;
1112 }
1113
1114 /***********************************************************************
1115  *              lineReleaseUserUserInfo (TAPI32.@)
1116  */
1117 DWORD WINAPI lineReleaseUserUserInfo(HCALL hCall)
1118 {
1119     FIXME("(%p): stub.\n", hCall);
1120     return 1;
1121 }
1122
1123 /***********************************************************************
1124  *              lineRemoveFromConference (TAPI32.@)
1125  */
1126 DWORD WINAPI lineRemoveFromConference(HCALL hCall)
1127 {
1128     FIXME("(%p): stub.\n", hCall);
1129     return 1;
1130 }
1131
1132 /***********************************************************************
1133  *              lineRemoveProvider (TAPI32.@)
1134  */
1135 DWORD WINAPI lineRemoveProvider(DWORD dwPermanentProviderID, HWND hwndOwner)
1136 {
1137     FIXME("(%08x, %p): stub.\n", dwPermanentProviderID, hwndOwner);
1138     return 1;
1139 }
1140
1141 /***********************************************************************
1142  *              lineSecureCall (TAPI32.@)
1143  */
1144 DWORD WINAPI lineSecureCall(HCALL hCall)
1145 {
1146     FIXME("(%p): stub.\n", hCall);
1147     return 1;
1148 }
1149
1150 /***********************************************************************
1151  *              lineSendUserUserInfo (TAPI32.@)
1152  */
1153 DWORD WINAPI lineSendUserUserInfo(HCALL hCall, LPCSTR lpsUserUserInfo, DWORD dwSize)
1154 {
1155     FIXME("(%p, %s, %08x): stub.\n", hCall, lpsUserUserInfo, dwSize);
1156     return 1;
1157 }
1158
1159 /***********************************************************************
1160  *              lineSetAppPriority (TAPI32.@)
1161  */
1162 DWORD WINAPI lineSetAppPriorityA(LPCSTR lpszAppFilename, DWORD dwMediaMode, LPLINEEXTENSIONID const lpExtensionID, DWORD dwRequestMode, LPCSTR lpszExtensionName, DWORD dwPriority)
1163 {
1164     FIXME("(%s, %08x, %p, %08x, %s, %08x): stub.\n", lpszAppFilename, dwMediaMode, lpExtensionID, dwRequestMode, lpszExtensionName, dwPriority);
1165     return 0;
1166 }
1167
1168 /***********************************************************************
1169  *              lineSetAppSpecific (TAPI32.@)
1170  */
1171 DWORD WINAPI lineSetAppSpecific(HCALL hCall, DWORD dwAppSpecific)
1172 {
1173     FIXME("(%p, %08x): stub.\n", hCall, dwAppSpecific);
1174     return 0;
1175 }
1176
1177 /***********************************************************************
1178  *              lineSetCallParams (TAPI32.@)
1179  */
1180 DWORD WINAPI lineSetCallParams(HCALL hCall, DWORD dwBearerMode, DWORD dwMinRate, DWORD dwMaxRate, LPLINEDIALPARAMS lpDialParams)
1181 {
1182     FIXME("(%p, %08x, %08x, %08x, %p): stub.\n", hCall, dwBearerMode, dwMinRate, dwMaxRate, lpDialParams);
1183     return 1;
1184 }
1185
1186 /***********************************************************************
1187  *              lineSetCallPrivilege (TAPI32.@)
1188  */
1189 DWORD WINAPI lineSetCallPrivilege(HCALL hCall, DWORD dwCallPrivilege)
1190 {
1191     FIXME("(%p, %08x): stub.\n", hCall, dwCallPrivilege);
1192     return 0;
1193 }
1194
1195 /***********************************************************************
1196  *              lineSetCurrentLocation (TAPI32.@)
1197  */
1198 DWORD WINAPI lineSetCurrentLocation(HLINEAPP hLineApp, DWORD dwLocation)
1199 {
1200     FIXME("(%p, %08x): stub.\n", hLineApp, dwLocation);
1201     return 0;
1202 }
1203
1204 /***********************************************************************
1205  *              lineSetDevConfig (TAPI32.@)
1206  */
1207 DWORD WINAPI lineSetDevConfigA(DWORD dwDeviceID, LPVOID lpDeviceConfig, DWORD dwSize, LPCSTR lpszDeviceClass)
1208 {
1209     FIXME("(%08x, %p, %08x, %s): stub.\n", dwDeviceID, lpDeviceConfig, dwSize, lpszDeviceClass);
1210     return 0;
1211 }
1212
1213 /***********************************************************************
1214  *              lineSetMediaControl (TAPI32.@)
1215  */
1216 DWORD WINAPI lineSetMediaControl(
1217 HLINE hLine,
1218 DWORD dwAddressID,
1219 HCALL hCall,
1220 DWORD dwSelect,
1221 LPLINEMEDIACONTROLDIGIT const lpDigitList,
1222 DWORD dwDigitNumEntries,
1223 LPLINEMEDIACONTROLMEDIA const lpMediaList,
1224 DWORD dwMediaNumEntries,
1225 LPLINEMEDIACONTROLTONE const lpToneList,
1226 DWORD dwToneNumEntries,
1227 LPLINEMEDIACONTROLCALLSTATE const lpCallStateList,
1228 DWORD dwCallStateNumEntries)
1229 {
1230     FIXME(": stub.\n");
1231     return 0;
1232 }
1233
1234 /***********************************************************************
1235  *              lineSetMediaMode (TAPI32.@)
1236  */
1237 DWORD WINAPI lineSetMediaMode(HCALL hCall, DWORD dwMediaModes)
1238 {
1239     FIXME("(%p, %08x): stub.\n", hCall, dwMediaModes);
1240     return 0;
1241 }
1242
1243 /***********************************************************************
1244  *              lineSetNumRings (TAPI32.@)
1245  */
1246 DWORD WINAPI lineSetNumRings(HLINE hLine, DWORD dwAddressID, DWORD dwNumRings)
1247 {
1248     FIXME("(%p, %08x, %08x): stub.\n", hLine, dwAddressID, dwNumRings);
1249     return 0;
1250 }
1251
1252 /***********************************************************************
1253  *              lineSetStatusMessages (TAPI32.@)
1254  */
1255 DWORD WINAPI lineSetStatusMessages(HLINE hLine, DWORD dwLineStates, DWORD dwAddressStates)
1256 {
1257     FIXME("(%p, %08x, %08x): stub.\n", hLine, dwLineStates, dwAddressStates);
1258     return 0;
1259 }
1260
1261 /***********************************************************************
1262  *              lineSetTerminal (TAPI32.@)
1263  */
1264 DWORD WINAPI lineSetTerminal(HLINE hLine, DWORD dwAddressID, HCALL hCall, DWORD dwSelect, DWORD dwTerminalModes, DWORD dwTerminalID, DWORD bEnable)
1265 {
1266     FIXME("(%p, %08x, %p, %08x, %08x, %08x, %08x): stub.\n", hLine, dwAddressID, hCall, dwSelect, dwTerminalModes, dwTerminalID, bEnable);
1267     return 1;
1268 }
1269
1270 /***********************************************************************
1271  *              lineSetTollList (TAPI32.@)
1272  */
1273 DWORD WINAPI lineSetTollListA(HLINEAPP hLineApp, DWORD dwDeviceID, LPCSTR lpszAddressIn, DWORD dwTollListOption)
1274 {
1275     FIXME("(%p, %08x, %s, %08x): stub.\n", hLineApp, dwDeviceID, lpszAddressIn, dwTollListOption);
1276     return 0;
1277 }
1278
1279 /***********************************************************************
1280  *              lineSetupConference (TAPI32.@)
1281  */
1282 DWORD WINAPI lineSetupConferenceA(HCALL hCall, HLINE hLine, LPHCALL lphConfCall, LPHCALL lphConsultCall, DWORD dwNumParties, LPLINECALLPARAMS lpCallParams)
1283 {
1284     FIXME("(%p, %p, %p, %p, %08x, %p): stub.\n", hCall, hLine, lphConfCall, lphConsultCall, dwNumParties, lpCallParams);
1285     return 1;
1286 }
1287
1288 /***********************************************************************
1289  *              lineSetupTransfer (TAPI32.@)
1290  */
1291 DWORD WINAPI lineSetupTransferA(HCALL hCall, LPHCALL lphConsultCall, LPLINECALLPARAMS lpCallParams)
1292 {
1293     FIXME("(%p, %p, %p): stub.\n", hCall, lphConsultCall, lpCallParams);
1294     return 1;
1295 }
1296
1297 /***********************************************************************
1298  *              lineShutdown (TAPI32.@)
1299  */
1300 DWORD WINAPI lineShutdown(HLINEAPP hLineApp)
1301 {
1302     FIXME("(%p): stub.\n", hLineApp);
1303     return 0;
1304 }
1305
1306 /***********************************************************************
1307  *              lineSwapHold (TAPI32.@)
1308  */
1309 DWORD WINAPI lineSwapHold(HCALL hActiveCall, HCALL hHeldCall)
1310 {
1311     FIXME("(active: %p, held: %p): stub.\n", hActiveCall, hHeldCall);
1312     return 1;
1313 }
1314
1315 /***********************************************************************
1316  *              lineTranslateAddress (TAPI32.@)
1317  */
1318 DWORD WINAPI lineTranslateAddressA(HLINEAPP hLineApp, DWORD dwDeviceID, DWORD dwAPIVersion, LPCSTR lpszAddressIn, DWORD dwCard, DWORD dwTranslateOptions, LPLINETRANSLATEOUTPUT lpTranslateOutput)
1319 {
1320     FIXME("(%p, %08x, %08x, %s, %08x, %08x, %p): stub.\n", hLineApp, dwDeviceID, dwAPIVersion, lpszAddressIn, dwCard, dwTranslateOptions, lpTranslateOutput);
1321     return 0;
1322 }
1323
1324 /***********************************************************************
1325  *              lineTranslateDialog (TAPI32.@)
1326  */
1327 DWORD WINAPI lineTranslateDialogA(HLINEAPP hLineApp, DWORD dwDeviceID, DWORD dwAPIVersion, HWND hwndOwner, LPCSTR lpszAddressIn)
1328 {
1329     FIXME("(%p, %08x, %08x, %p, %s): stub.\n", hLineApp, dwDeviceID, dwAPIVersion, hwndOwner, lpszAddressIn);
1330     return 0;
1331 }
1332
1333 /***********************************************************************
1334  *              lineUncompleteCall (TAPI32.@)
1335  */
1336 DWORD WINAPI lineUncompleteCall(HLINE hLine, DWORD dwCompletionID)
1337 {
1338     FIXME("(%p, %08x): stub.\n", hLine, dwCompletionID);
1339     return 1;
1340 }
1341
1342 /***********************************************************************
1343  *              lineUnhold (TAPI32.@)
1344  */
1345 DWORD WINAPI lineUnhold(HCALL hCall)
1346 {
1347     FIXME("(%p): stub.\n", hCall);
1348     return 1;
1349 }
1350
1351 /***********************************************************************
1352  *              lineUnpark (TAPI32.@)
1353  */
1354 DWORD WINAPI lineUnparkA(HLINE hLine, DWORD dwAddressID, LPHCALL lphCall, LPCSTR lpszDestAddress)
1355 {
1356     FIXME("(%p, %08x, %p, %s): stub.\n", hLine, dwAddressID, lphCall, lpszDestAddress);
1357     return 1;
1358 }