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