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