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