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