msvcrt: Fix malloc_func_t/free_func_t calling convention.
[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  *              lineGetNewCalls (TAPI32.@)
548  */
549 DWORD WINAPI lineGetNewCalls(HLINE hLine, DWORD dwAddressID, DWORD dwSelect, LPLINECALLLIST lpCallList)
550 {
551     FIXME("(%p, %08x, %08x, %p): stub.\n", hLine, dwAddressID, dwSelect, lpCallList);
552     return 0;
553 }
554
555 /***********************************************************************
556  *              lineGetNumRings (TAPI32.@)
557  */
558 DWORD WINAPI lineGetNumRings(HLINE hLine, DWORD dwAddressID, LPDWORD lpdwNumRings)
559 {
560     FIXME("(%p, %08x, %p): stub.\n", hLine, dwAddressID, lpdwNumRings);
561     return 0;
562 }
563
564 /***********************************************************************
565  *              lineGetProviderListA (TAPI32.@)
566  */
567 DWORD WINAPI lineGetProviderListA(DWORD dwAPIVersion, LPLINEPROVIDERLIST lpProviderList)
568 {
569     FIXME("(%08x, %p): stub.\n", dwAPIVersion, lpProviderList);
570     return LINEERR_OPERATIONFAILED;
571 }
572
573 /***********************************************************************
574  *              lineGetProviderListW (TAPI32.@)
575  */
576 DWORD WINAPI lineGetProviderListW(DWORD dwAPIVersion, LPLINEPROVIDERLIST lpProviderList)
577 {
578     FIXME("(%08x, %p): stub.\n", dwAPIVersion, lpProviderList);
579     return LINEERR_OPERATIONFAILED;
580 }
581
582 /***********************************************************************
583  *              lineGetRequest (TAPI32.@)
584  */
585 DWORD WINAPI lineGetRequestA(HLINEAPP hLineApp, DWORD dwRequestMode, LPVOID lpRequestBuffer)
586 {
587     FIXME("%p, %08x, %p): stub.\n", hLineApp, dwRequestMode, lpRequestBuffer);
588     return 0;
589 }
590
591 /***********************************************************************
592  *              lineGetStatusMessages (TAPI32.@)
593  */
594 DWORD WINAPI lineGetStatusMessages(HLINE hLine, LPDWORD lpdwLineStatus, LPDWORD lpdwAddressStates)
595 {
596     FIXME("(%p, %p, %p): stub.\n", hLine, lpdwLineStatus, lpdwAddressStates);
597     return 0;
598 }
599
600 /***********************************************************************
601  *              lineGetTranslateCaps (TAPI32.@)
602  *
603  *      get address translate capabilities. Returns a LINETRANSLATECAPS
604  *      structure:
605  *
606  *      +-----------------------+
607  *      |TotalSize              |
608  *      |NeededSize             |
609  *      |UsedSize               |
610  *      +-----------------------+
611  *      |NumLocations           |
612  *      |LocationsListSize      |
613  *      |LocationsListOffset    | -+
614  *      |CurrentLocationID      |  |
615  *      +-----------------------+  |
616  *      |NumCards               |  |
617  *      |CardListSize           |  |
618  *      |CardListOffset         | -|--+
619  *      |CurrentPreferredCardID |  |  |
620  *      +-----------------------+  |  |
621  *      |                       | <+  |
622  *      |LINELOCATIONENTRY #1   |     |
623  *      |                       |     |
624  *      +-----------------------+     |
625  *      ~                       ~     |
626  *      +-----------------------+     |
627  *      |                       |     |
628  *      |LINELOCATIONENTRY      |     |
629  *      |          #NumLocations|     |
630  *      +-----------------------+     |
631  *      |                       | <---+
632  *      |LINECARDENTRY #1       |
633  *      |                       |
634  *      +-----------------------+
635  *      ~                       ~
636  *      +-----------------------+
637  *      |                       |
638  *      |LINECARDENTRY #NumCards|
639  *      |                       |
640  *      +-----------------------+
641  *      | room for strings named|
642  *      | in the structures     |
643  *      | above.                |
644  *      +-----------------------+
645  */
646 DWORD WINAPI lineGetTranslateCapsA(HLINEAPP hLineApp, DWORD dwAPIVersion,
647         LPLINETRANSLATECAPS lpTranslateCaps)
648 {
649     HKEY hkLocations, hkCards, hkCardLocations, hsubkey;
650     int numlocations, numcards;
651     DWORD maxlockeylen,
652         maxcardkeylen;
653     char *loc_key_name = NULL;
654     char *card_key_name = NULL;
655     LPBYTE strptr;
656     int length;
657     int i;
658     DWORD lendword;
659     DWORD currentid;
660     LPLINELOCATIONENTRY pLocEntry;
661     LPLINECARDENTRY pCardEntry;
662     
663     TRACE("(%p, %08x, %p (tot. size %d)\n", hLineApp, dwAPIVersion,
664             lpTranslateCaps, lpTranslateCaps->dwTotalSize );
665     if( lpTranslateCaps->dwTotalSize < sizeof(LINETRANSLATECAPS))
666         return LINEERR_STRUCTURETOOSMALL;
667     if( RegCreateKeyA(HKEY_LOCAL_MACHINE, szLocationsKey, &hkLocations)
668             != ERROR_SUCCESS ) {
669         ERR("unexpected registry error 1.\n");
670         return LINEERR_INIFILECORRUPT;  
671     }
672     lendword = sizeof( DWORD);
673     if( RegQueryValueExA( hkLocations, "CurrentID", NULL, NULL,
674                 (LPBYTE) &currentid, &lendword) != ERROR_SUCCESS )
675         currentid = -1;  /* change this later */
676     if(RegQueryInfoKeyA(hkLocations, NULL, NULL, NULL, NULL, &maxlockeylen,
677                         NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
678         RegCloseKey(hkLocations);
679         ERR("unexpected registry error 2.\n");
680         return LINEERR_INIFILECORRUPT;
681     }
682     maxlockeylen++;
683     if( maxlockeylen < 10)
684         maxlockeylen = 10; /* need this also if there is no key */
685     loc_key_name = HeapAlloc( GetProcessHeap(), 0, maxlockeylen);
686     /* first time through: calculate needed space */
687     length=0;
688     i=0;
689     numlocations=0;
690     while( RegEnumKeyA(hkLocations, i, loc_key_name, maxlockeylen)
691             == ERROR_SUCCESS){
692         DWORD size_val;
693         i++;
694         if( strncasecmp(loc_key_name, "location", 8)  ||
695                 (RegOpenKeyA(hkLocations, loc_key_name, &hsubkey)
696                  != ERROR_SUCCESS))
697             continue;
698         numlocations++;
699         length += sizeof(LINELOCATIONENTRY);
700         RegQueryValueExA(hsubkey, "Name",NULL,NULL,NULL,&size_val); 
701         length += size_val;
702         RegQueryValueExA(hsubkey, "AreaCode",NULL,NULL,NULL,&size_val); 
703         length += size_val;
704         RegQueryValueExA(hsubkey, "OutsideAccess",NULL,NULL,NULL,&size_val); 
705         length += size_val;
706         RegQueryValueExA(hsubkey, "LongDistanceAccess",NULL,NULL,NULL,&size_val); 
707         length += size_val;
708         RegQueryValueExA(hsubkey, "DisableCallWaiting",NULL,NULL,NULL,&size_val); 
709         length += size_val;
710         /* fixme: what about TollPrefixList???? */
711         RegCloseKey(hsubkey);
712     }
713     if(numlocations == 0) {
714         /* add one location */
715         if( RegCreateKeyA( hkLocations, "Location1", &hsubkey)
716                 == ERROR_SUCCESS) {
717             DWORD dwval;
718             char buf[10];
719             numlocations = 1;
720             length += sizeof(LINELOCATIONENTRY) + 20 ;
721             RegSetValueExA( hsubkey, "AreaCode", 0, REG_SZ, (const BYTE *)"010", 4);
722             GetLocaleInfoA( LOCALE_SYSTEM_DEFAULT, LOCALE_ICOUNTRY, buf, 8);
723             dwval = atoi(buf);
724             RegSetValueExA( hsubkey, "Country", 0, REG_DWORD, (LPBYTE)&dwval,
725                     sizeof(DWORD));
726             RegSetValueExA( hsubkey, "DisableCallWaiting", 0, REG_SZ, (const BYTE *)"", 1);
727             dwval = 1;  
728             RegSetValueExA( hsubkey, "Flags", 0, REG_DWORD, (LPBYTE)&dwval,
729                     sizeof(DWORD));
730             RegSetValueExA( hsubkey, "LongDistanceAccess", 0, REG_SZ, (const BYTE *)"", 1);
731             RegSetValueExA( hsubkey, "Name", 0, REG_SZ, (const BYTE *)"New Location", 13);
732             RegSetValueExA( hsubkey, "OutsideAccess", 0, REG_SZ, (const BYTE *)"", 1);
733             RegCloseKey(hsubkey);
734             dwval = 1;  
735             RegSetValueExA( hkLocations, "CurrentID", 0, REG_DWORD,
736                     (LPBYTE)&dwval, sizeof(DWORD));
737             dwval = 2;  
738             RegSetValueExA( hkLocations, "NextID", 0, REG_DWORD, (LPBYTE)&dwval,
739                     sizeof(DWORD));
740         }
741     }
742     /* do the card list */
743     numcards=0;
744     if( RegCreateKeyA(HKEY_CURRENT_USER, szCardsKey, &hkCards)
745             == ERROR_SUCCESS ) {
746         if(RegQueryInfoKeyA(hkCards, NULL, NULL, NULL, NULL, &maxcardkeylen,
747                 NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
748             maxcardkeylen++;
749             if( maxcardkeylen < 6) maxcardkeylen = 6;
750             card_key_name = HeapAlloc(GetProcessHeap(), 0, maxcardkeylen);
751             i=0;
752             while( RegEnumKeyA(hkCards, i, card_key_name, maxcardkeylen) ==
753                     ERROR_SUCCESS){
754                 DWORD size_val;
755                 i++;
756                 if( strncasecmp(card_key_name, "card", 4)  || ERROR_SUCCESS !=
757                         (RegOpenKeyA(hkCards, card_key_name, &hsubkey) ))
758                     continue;
759                 numcards++;
760                 length += sizeof(LINECARDENTRY);
761                 RegQueryValueExA(hsubkey, "Name",NULL,NULL,NULL,&size_val); 
762                 length += size_val;
763                 RegQueryValueExA(hsubkey, "LocalRule",NULL,NULL,NULL,&size_val); 
764                 length += size_val;
765                 RegQueryValueExA(hsubkey, "LDRule",NULL,NULL,NULL,&size_val); 
766                 length += size_val;
767                 RegQueryValueExA(hsubkey, "InternationalRule",NULL,NULL,NULL,
768                         &size_val); 
769                 length += size_val;
770                 RegCloseKey(hsubkey);
771             }
772         }
773         /* add one card (direct call) */
774         if (numcards == 0 &&
775                 ERROR_SUCCESS == RegCreateKeyA( hkCards, "Card1", &hsubkey)) {
776             DWORD dwval;
777             numcards = 1;
778             length += sizeof(LINECARDENTRY) + 22 ;
779             RegSetValueExA( hsubkey, "Name", 0, REG_SZ, (const BYTE *)"None (Direct Call)", 19);
780             dwval = 1;  
781             RegSetValueExA( hsubkey, "Flags", 0, REG_DWORD, (LPBYTE)&dwval,
782                     sizeof(DWORD));
783             RegSetValueExA( hsubkey, "InternationalRule", 0, REG_SZ, (const BYTE *)"", 1);
784             RegSetValueExA( hsubkey, "LDRule", 0, REG_SZ, (const BYTE *)"", 1);
785             RegSetValueExA( hsubkey, "LocalRule", 0, REG_SZ, (const BYTE *)"", 1);
786             RegCloseKey(hsubkey);
787             dwval = 2;  
788             RegSetValueExA( hkCards, "NextID", 0, REG_DWORD, (LPBYTE)&dwval,
789                     sizeof(DWORD));
790         }
791     } else hkCards = 0;  /* should really fail */
792     /* check if sufficient room is available */
793     lpTranslateCaps->dwNeededSize =  sizeof(LINETRANSLATECAPS) + length;
794     if ( lpTranslateCaps->dwNeededSize > lpTranslateCaps->dwTotalSize ) {
795         RegCloseKey( hkLocations);
796         if( hkCards) RegCloseKey( hkCards);
797         HeapFree(GetProcessHeap(), 0, loc_key_name);
798         HeapFree(GetProcessHeap(), 0, card_key_name);
799         lpTranslateCaps->dwUsedSize = sizeof(LINETRANSLATECAPS);
800         TRACE("Insufficient space: total %d needed %d used %d\n",
801                 lpTranslateCaps->dwTotalSize,
802                 lpTranslateCaps->dwNeededSize,
803                 lpTranslateCaps->dwUsedSize);
804         return  0;
805     }
806     /* fill in the LINETRANSLATECAPS structure */
807     lpTranslateCaps->dwUsedSize = lpTranslateCaps->dwNeededSize;
808     lpTranslateCaps->dwNumLocations = numlocations;
809     lpTranslateCaps->dwLocationListSize = sizeof(LINELOCATIONENTRY) *
810             lpTranslateCaps->dwNumLocations;
811     lpTranslateCaps->dwLocationListOffset = sizeof(LINETRANSLATECAPS);
812     lpTranslateCaps->dwCurrentLocationID = currentid; 
813     lpTranslateCaps->dwNumCards = numcards;
814     lpTranslateCaps->dwCardListSize = sizeof(LINECARDENTRY) *
815             lpTranslateCaps->dwNumCards;
816     lpTranslateCaps->dwCardListOffset = lpTranslateCaps->dwLocationListOffset +
817             lpTranslateCaps->dwLocationListSize;
818     lpTranslateCaps->dwCurrentPreferredCardID = 0; 
819     /* this is where the strings will be stored */
820     strptr = ((LPBYTE) lpTranslateCaps) +
821         lpTranslateCaps->dwCardListOffset + lpTranslateCaps->dwCardListSize;
822     pLocEntry = (LPLINELOCATIONENTRY) (lpTranslateCaps + 1);
823     /* key with Preferred CardIDs */
824     if( RegOpenKeyA(HKEY_CURRENT_USER, szLocationsKey, &hkCardLocations)
825             != ERROR_SUCCESS ) 
826         hkCardLocations = 0;
827     /* second time through all locations */
828     i=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         size_val=sizeof(DWORD);
838         if( RegQueryValueExA(hsubkey, "ID",NULL, NULL,
839                 (LPBYTE) &(pLocEntry->dwPermanentLocationID), &size_val) !=
840                 ERROR_SUCCESS)
841             pLocEntry->dwPermanentLocationID = atoi( loc_key_name + 8);
842         size_val=2048;
843         RegQueryValueExA(hsubkey, "Name",NULL,NULL, strptr, &size_val);
844         pLocEntry->dwLocationNameSize = size_val;
845         pLocEntry->dwLocationNameOffset = strptr - (LPBYTE) lpTranslateCaps;
846         strptr += size_val;
847  
848         size_val=2048;
849         RegQueryValueExA(hsubkey, "AreaCode",NULL,NULL, strptr, &size_val);
850         pLocEntry->dwCityCodeSize = size_val;
851         pLocEntry->dwCityCodeOffset = strptr - (LPBYTE) lpTranslateCaps;
852         strptr += size_val;
853         
854         size_val=2048;
855         RegQueryValueExA(hsubkey, "OutsideAccess",NULL,NULL, strptr, &size_val);
856         pLocEntry->dwLocalAccessCodeSize = size_val;
857         pLocEntry->dwLocalAccessCodeOffset = strptr - (LPBYTE) lpTranslateCaps;
858         strptr += size_val;
859         size_val=2048;
860         RegQueryValueExA(hsubkey, "LongDistanceAccess",NULL,NULL, strptr,
861                 &size_val);
862         pLocEntry->dwLongDistanceAccessCodeSize= size_val;
863         pLocEntry->dwLongDistanceAccessCodeOffset= strptr -
864             (LPBYTE) lpTranslateCaps;
865         strptr += size_val;
866         size_val=2048;
867         RegQueryValueExA(hsubkey, "DisableCallWaiting",NULL,NULL, strptr,
868                 &size_val);
869         pLocEntry->dwCancelCallWaitingSize= size_val;
870         pLocEntry->dwCancelCallWaitingOffset= strptr - (LPBYTE) lpTranslateCaps;
871         strptr += size_val;
872
873         pLocEntry->dwTollPrefixListSize = 0;    /* FIXME */
874         pLocEntry->dwTollPrefixListOffset = 0;    /* FIXME */
875
876         size_val=sizeof(DWORD);
877         RegQueryValueExA(hsubkey, "Country",NULL,NULL,
878                 (LPBYTE) &(pLocEntry->dwCountryCode), &size_val);
879         pLocEntry->dwCountryID = pLocEntry->dwCountryCode; /* FIXME */
880         RegQueryValueExA(hsubkey, "Flags",NULL,NULL,
881                 (LPBYTE) &(pLocEntry->dwOptions), &size_val);
882         RegCloseKey(hsubkey);
883         /* get preferred cardid */
884         pLocEntry->dwPreferredCardID = 0;
885         if ( hkCardLocations) {
886             size_val=sizeof(DWORD);
887             if(RegOpenKeyA(hkCardLocations, loc_key_name, &hsubkey) ==
888                     ERROR_SUCCESS) {
889                 RegQueryValueExA(hsubkey, "CallingCard",NULL,NULL,
890                         (LPBYTE) &(pLocEntry->dwPreferredCardID), &size_val);
891                 RegCloseKey(hsubkey);
892             }
893                 
894         }
895         /* make sure there is a currentID */
896         if(currentid == -1){
897             currentid = pLocEntry->dwPermanentLocationID;
898             lpTranslateCaps->dwCurrentLocationID = currentid; 
899         }
900         if(pLocEntry->dwPermanentLocationID == currentid )
901             lpTranslateCaps->dwCurrentPreferredCardID =
902                     pLocEntry->dwPreferredCardID;
903         TRACE("added: ID %d %s CountryCode %d CityCode %s CardID %d "
904                 "LocalAccess: %s LongDistanceAccess: %s CountryID %d "
905                 "Options %d CancelCallWait %s\n",
906                 pLocEntry->dwPermanentLocationID,
907                 debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwLocationNameOffset),
908                 pLocEntry->dwCountryCode,
909                 debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwCityCodeOffset),
910                 pLocEntry->dwPreferredCardID,
911                 debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwLocalAccessCodeOffset),
912                 debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwLongDistanceAccessCodeOffset),
913                 pLocEntry->dwCountryID,
914                 pLocEntry->dwOptions,
915                 debugstr_a( (char*)lpTranslateCaps + pLocEntry->dwCancelCallWaitingOffset));
916         pLocEntry++;
917     }
918     pCardEntry= (LPLINECARDENTRY) pLocEntry;
919     /* do the card list */
920     if( hkCards) {
921         i=0;
922         while( RegEnumKeyA(hkCards, i, card_key_name, maxcardkeylen) ==
923                 ERROR_SUCCESS){
924             DWORD size_val;
925             i++;
926             if( strncasecmp(card_key_name, "card", 4)  ||
927                     (RegOpenKeyA(hkCards, card_key_name, &hsubkey) != ERROR_SUCCESS))
928                 continue;
929             size_val=sizeof(DWORD);
930             if( RegQueryValueExA(hsubkey, "ID",NULL, NULL,
931                     (LPBYTE) &(pCardEntry->dwPermanentCardID), &size_val) !=
932                     ERROR_SUCCESS)
933                 pCardEntry->dwPermanentCardID= atoi( card_key_name + 4);
934             size_val=2048;
935             RegQueryValueExA(hsubkey, "Name",NULL,NULL, strptr, &size_val);
936             pCardEntry->dwCardNameSize = size_val;
937             pCardEntry->dwCardNameOffset = strptr - (LPBYTE) lpTranslateCaps;
938             strptr += size_val;
939             pCardEntry->dwCardNumberDigits = 1; /* FIXME */
940             size_val=2048;
941             RegQueryValueExA(hsubkey, "LocalRule",NULL,NULL, strptr, &size_val);
942             pCardEntry->dwSameAreaRuleSize= size_val;
943             pCardEntry->dwSameAreaRuleOffset= strptr - (LPBYTE) lpTranslateCaps;
944             strptr += size_val;
945             size_val=2048;
946             RegQueryValueExA(hsubkey, "LDRule",NULL,NULL, strptr, &size_val);
947             pCardEntry->dwLongDistanceRuleSize = size_val;
948             pCardEntry->dwLongDistanceRuleOffset = strptr - (LPBYTE) lpTranslateCaps;
949             strptr += size_val;
950             size_val=2048;
951             RegQueryValueExA(hsubkey, "InternationalRule",NULL,NULL, strptr,
952                     &size_val);
953             pCardEntry->dwInternationalRuleSize = size_val;
954             pCardEntry->dwInternationalRuleOffset = strptr -
955                 (LPBYTE) lpTranslateCaps;
956             strptr += size_val;
957             size_val=sizeof(DWORD);
958             RegQueryValueExA(hsubkey, "Flags",NULL, NULL,
959                     (LPBYTE) &(pCardEntry->dwOptions), &size_val); 
960             TRACE( "added card: ID %d name %s SameArea %s LongDistance %s International %s Options 0x%x\n", 
961                     pCardEntry->dwPermanentCardID,
962                     debugstr_a( (char*)lpTranslateCaps + pCardEntry->dwCardNameOffset),
963                     debugstr_a( (char*)lpTranslateCaps + pCardEntry->dwSameAreaRuleOffset),
964                     debugstr_a( (char*)lpTranslateCaps + pCardEntry->dwLongDistanceRuleOffset),
965                     debugstr_a( (char*)lpTranslateCaps + pCardEntry->dwInternationalRuleOffset),
966                     pCardEntry->dwOptions);
967
968             pCardEntry++;
969         }
970     }
971
972     if(hkLocations) RegCloseKey(hkLocations);
973     if(hkCards) RegCloseKey(hkCards);
974     if(hkCardLocations) RegCloseKey(hkCardLocations);
975     HeapFree(GetProcessHeap(), 0, loc_key_name);
976     HeapFree(GetProcessHeap(), 0, card_key_name);
977     TRACE(" returning success tot %d needed %d used %d\n",
978             lpTranslateCaps->dwTotalSize,
979             lpTranslateCaps->dwNeededSize,
980             lpTranslateCaps->dwUsedSize );
981     return 0; /* success */
982 }
983
984 /***********************************************************************
985  *              lineHandoff (TAPI32.@)
986  */
987 DWORD WINAPI lineHandoffA(HCALL hCall, LPCSTR lpszFileName, DWORD dwMediaMode)
988 {
989     FIXME("(%p, %s, %08x): stub.\n", hCall, lpszFileName, dwMediaMode);
990     return 0;
991 }
992
993 /***********************************************************************
994  *              lineHold (TAPI32.@)
995  */
996 DWORD WINAPI lineHold(HCALL hCall)
997 {
998     FIXME("(%p): stub.\n", hCall);
999     return 1;
1000 }
1001
1002 /***********************************************************************
1003  *              lineInitialize (TAPI32.@)
1004  */
1005 DWORD WINAPI lineInitialize(
1006   LPHLINEAPP lphLineApp,
1007   HINSTANCE hInstance,
1008   LINECALLBACK lpfnCallback,
1009   LPCSTR lpszAppName,
1010   LPDWORD lpdwNumDevs)
1011 {
1012     FIXME("(%p, %p, %p, %s, %p): stub.\n", lphLineApp, hInstance,
1013           lpfnCallback, debugstr_a(lpszAppName), lpdwNumDevs);
1014     return 0;
1015 }
1016
1017 /***********************************************************************
1018  *              lineInitializeExA (TAPI32.@)
1019  */
1020 LONG WINAPI lineInitializeExA(LPHLINEAPP lphLineApp, HINSTANCE hInstance, LINECALLBACK lpfnCallback, LPCSTR lpszFriendlyAppName, LPDWORD lpdwNumDevs, LPDWORD lpdwAPIVersion, LPLINEINITIALIZEEXPARAMS lpLineInitializeExParams)
1021 {
1022     FIXME("(%p, %p, %p, %s, %p, %p, %p): stub.\n", lphLineApp, hInstance,
1023           lpfnCallback, debugstr_a(lpszFriendlyAppName), lpdwNumDevs, lpdwAPIVersion, lpLineInitializeExParams);
1024     return 0;
1025 }
1026
1027 /***********************************************************************
1028  *              lineMakeCallW (TAPI32.@)
1029  */
1030 DWORD WINAPI lineMakeCallW(HLINE hLine, LPHCALL lphCall, LPCWSTR lpszDestAddress,
1031                            DWORD dwCountryCode, LPLINECALLPARAMS lpCallParams)
1032 {
1033     FIXME("(%p, %p, %s, %08x, %p): stub.\n", hLine, lphCall, debugstr_w(lpszDestAddress),
1034                                              dwCountryCode, lpCallParams);
1035     return LINEERR_OPERATIONFAILED;
1036 }
1037
1038 /***********************************************************************
1039  *              lineMakeCallA (TAPI32.@)
1040  */
1041 DWORD WINAPI lineMakeCallA(HLINE hLine, LPHCALL lphCall, LPCSTR lpszDestAddress,
1042                            DWORD dwCountryCode, LPLINECALLPARAMS lpCallParams)
1043 {
1044     FIXME("(%p, %p, %s, %08x, %p): stub.\n", hLine, lphCall, lpszDestAddress,
1045                                              dwCountryCode, lpCallParams);
1046     return LINEERR_OPERATIONFAILED;
1047 }
1048
1049 /***********************************************************************
1050  *              lineMonitorDigits (TAPI32.@)
1051  */
1052 DWORD WINAPI lineMonitorDigits(HCALL hCall, DWORD dwDigitModes)
1053 {
1054     FIXME("(%p, %08x): stub.\n", hCall, dwDigitModes);
1055     return 0;
1056 }
1057
1058 /***********************************************************************
1059  *              lineMonitorMedia (TAPI32.@)
1060  */
1061 DWORD WINAPI lineMonitorMedia(HCALL hCall, DWORD dwMediaModes)
1062 {
1063     FIXME("(%p, %08x): stub.\n", hCall, dwMediaModes);
1064     return 0;
1065 }
1066
1067 /***********************************************************************
1068  *              lineMonitorTones (TAPI32.@)
1069  */
1070 DWORD WINAPI lineMonitorTones(HCALL hCall, LPLINEMONITORTONE lpToneList, DWORD dwNumEntries)
1071 {
1072     FIXME("(%p, %p, %08x): stub.\n", hCall, lpToneList, dwNumEntries);
1073     return 0;
1074 }
1075
1076 /***********************************************************************
1077  *              lineNegotiateAPIVersion (TAPI32.@)
1078  */
1079 DWORD WINAPI lineNegotiateAPIVersion(
1080   HLINEAPP hLineApp,
1081   DWORD dwDeviceID,
1082   DWORD dwAPILowVersion,
1083   DWORD dwAPIHighVersion,
1084   LPDWORD lpdwAPIVersion,
1085   LPLINEEXTENSIONID lpExtensionID
1086 )
1087 {
1088     static int warn_once;
1089
1090     if(!warn_once++)
1091         FIXME("(%p, %d, %d, %d, %p, %p): stub.\n", hLineApp, dwDeviceID,
1092               dwAPILowVersion, dwAPIHighVersion, lpdwAPIVersion, lpExtensionID);
1093     *lpdwAPIVersion = dwAPIHighVersion;
1094     return 0;
1095 }
1096
1097 /***********************************************************************
1098  *              lineNegotiateExtVersion (TAPI32.@)
1099  */
1100 DWORD WINAPI lineNegotiateExtVersion(HLINEAPP hLineApp, DWORD dwDeviceID, DWORD dwAPIVersion, DWORD dwExtLowVersion, DWORD dwExtHighVersion, LPDWORD lpdwExtVersion)
1101 {
1102     FIXME("stub.\n");
1103     return 0;
1104 }
1105
1106 /***********************************************************************
1107  *              lineOpen (TAPI32.@)
1108  */
1109 DWORD WINAPI lineOpenA(HLINEAPP hLineApp, DWORD dwDeviceID, LPHLINE lphLine, DWORD dwAPIVersion, DWORD dwExtVersion, DWORD dwCallbackInstance, DWORD dwPrivileges, DWORD dwMediaModes, LPLINECALLPARAMS lpCallParams)
1110 {
1111     FIXME("stub.\n");
1112     return 0;
1113 }
1114
1115 /***********************************************************************
1116  *              linePark (TAPI32.@)
1117  */
1118 DWORD WINAPI lineParkA(HCALL hCall, DWORD dwParkMode, LPCSTR lpszDirAddress, LPVARSTRING lpNonDirAddress)
1119 {
1120     FIXME("(%p, %08x, %s, %p): stub.\n", hCall, dwParkMode, lpszDirAddress, lpNonDirAddress);
1121     return 1;
1122 }
1123
1124 /***********************************************************************
1125  *              linePickup (TAPI32.@)
1126  */
1127 DWORD WINAPI linePickupA(HLINE hLine, DWORD dwAddressID, LPHCALL lphCall, LPCSTR lpszDestAddress, LPCSTR lpszGroupID)
1128 {
1129     FIXME("(%p, %08x, %p, %s, %s): stub.\n", hLine, dwAddressID, lphCall, lpszDestAddress, lpszGroupID);
1130     return 1;
1131 }
1132
1133 /***********************************************************************
1134  *              linePrepareAddToConference (TAPI32.@)
1135  */
1136 DWORD WINAPI linePrepareAddToConferenceA(HCALL hConfCall, LPHCALL lphConsultCall, LPLINECALLPARAMS lpCallParams)
1137 {
1138     FIXME("(%p, %p, %p): stub.\n", hConfCall, lphConsultCall, lpCallParams);
1139     return 1;
1140 }
1141
1142 /***********************************************************************
1143  *              lineRedirect (TAPI32.@)
1144  */
1145 DWORD WINAPI lineRedirectA(
1146   HCALL hCall,
1147   LPCSTR lpszDestAddress,
1148   DWORD  dwCountryCode) {
1149
1150   FIXME(": stub.\n");
1151   return 1;
1152 }
1153
1154 /***********************************************************************
1155  *              lineRegisterRequestRecipient (TAPI32.@)
1156  */
1157 DWORD WINAPI lineRegisterRequestRecipient(HLINEAPP hLineApp, DWORD dwRegistrationInstance, DWORD dwRequestMode, DWORD dwEnable)
1158 {
1159     FIXME("(%p, %08x, %08x, %08x): stub.\n", hLineApp, dwRegistrationInstance, dwRequestMode, dwEnable);
1160     return 1;
1161 }
1162
1163 /***********************************************************************
1164  *              lineReleaseUserUserInfo (TAPI32.@)
1165  */
1166 DWORD WINAPI lineReleaseUserUserInfo(HCALL hCall)
1167 {
1168     FIXME("(%p): stub.\n", hCall);
1169     return 1;
1170 }
1171
1172 /***********************************************************************
1173  *              lineRemoveFromConference (TAPI32.@)
1174  */
1175 DWORD WINAPI lineRemoveFromConference(HCALL hCall)
1176 {
1177     FIXME("(%p): stub.\n", hCall);
1178     return 1;
1179 }
1180
1181 /***********************************************************************
1182  *              lineRemoveProvider (TAPI32.@)
1183  */
1184 DWORD WINAPI lineRemoveProvider(DWORD dwPermanentProviderID, HWND hwndOwner)
1185 {
1186     FIXME("(%08x, %p): stub.\n", dwPermanentProviderID, hwndOwner);
1187     return 1;
1188 }
1189
1190 /***********************************************************************
1191  *              lineSecureCall (TAPI32.@)
1192  */
1193 DWORD WINAPI lineSecureCall(HCALL hCall)
1194 {
1195     FIXME("(%p): stub.\n", hCall);
1196     return 1;
1197 }
1198
1199 /***********************************************************************
1200  *              lineSendUserUserInfo (TAPI32.@)
1201  */
1202 DWORD WINAPI lineSendUserUserInfo(HCALL hCall, LPCSTR lpsUserUserInfo, DWORD dwSize)
1203 {
1204     FIXME("(%p, %s, %08x): stub.\n", hCall, lpsUserUserInfo, dwSize);
1205     return 1;
1206 }
1207
1208 /***********************************************************************
1209  *              lineSetAppPriority (TAPI32.@)
1210  */
1211 DWORD WINAPI lineSetAppPriorityA(LPCSTR lpszAppFilename, DWORD dwMediaMode, LPLINEEXTENSIONID const lpExtensionID, DWORD dwRequestMode, LPCSTR lpszExtensionName, DWORD dwPriority)
1212 {
1213     FIXME("(%s, %08x, %p, %08x, %s, %08x): stub.\n", lpszAppFilename, dwMediaMode, lpExtensionID, dwRequestMode, lpszExtensionName, dwPriority);
1214     return 0;
1215 }
1216
1217 /***********************************************************************
1218  *              lineSetAppSpecific (TAPI32.@)
1219  */
1220 DWORD WINAPI lineSetAppSpecific(HCALL hCall, DWORD dwAppSpecific)
1221 {
1222     FIXME("(%p, %08x): stub.\n", hCall, dwAppSpecific);
1223     return 0;
1224 }
1225
1226 /***********************************************************************
1227  *              lineSetCallParams (TAPI32.@)
1228  */
1229 DWORD WINAPI lineSetCallParams(HCALL hCall, DWORD dwBearerMode, DWORD dwMinRate, DWORD dwMaxRate, LPLINEDIALPARAMS lpDialParams)
1230 {
1231     FIXME("(%p, %08x, %08x, %08x, %p): stub.\n", hCall, dwBearerMode, dwMinRate, dwMaxRate, lpDialParams);
1232     return 1;
1233 }
1234
1235 /***********************************************************************
1236  *              lineSetCallPrivilege (TAPI32.@)
1237  */
1238 DWORD WINAPI lineSetCallPrivilege(HCALL hCall, DWORD dwCallPrivilege)
1239 {
1240     FIXME("(%p, %08x): stub.\n", hCall, dwCallPrivilege);
1241     return 0;
1242 }
1243
1244 /***********************************************************************
1245  *              lineSetCurrentLocation (TAPI32.@)
1246  */
1247 DWORD WINAPI lineSetCurrentLocation(HLINEAPP hLineApp, DWORD dwLocation)
1248 {
1249     FIXME("(%p, %08x): stub.\n", hLineApp, dwLocation);
1250     return 0;
1251 }
1252
1253 /***********************************************************************
1254  *              lineSetDevConfig (TAPI32.@)
1255  */
1256 DWORD WINAPI lineSetDevConfigA(DWORD dwDeviceID, LPVOID lpDeviceConfig, DWORD dwSize, LPCSTR lpszDeviceClass)
1257 {
1258     FIXME("(%08x, %p, %08x, %s): stub.\n", dwDeviceID, lpDeviceConfig, dwSize, lpszDeviceClass);
1259     return 0;
1260 }
1261
1262 /***********************************************************************
1263  *              lineSetMediaControl (TAPI32.@)
1264  */
1265 DWORD WINAPI lineSetMediaControl(
1266 HLINE hLine,
1267 DWORD dwAddressID,
1268 HCALL hCall,
1269 DWORD dwSelect,
1270 LPLINEMEDIACONTROLDIGIT const lpDigitList,
1271 DWORD dwDigitNumEntries,
1272 LPLINEMEDIACONTROLMEDIA const lpMediaList,
1273 DWORD dwMediaNumEntries,
1274 LPLINEMEDIACONTROLTONE const lpToneList,
1275 DWORD dwToneNumEntries,
1276 LPLINEMEDIACONTROLCALLSTATE const lpCallStateList,
1277 DWORD dwCallStateNumEntries)
1278 {
1279     FIXME(": stub.\n");
1280     return 0;
1281 }
1282
1283 /***********************************************************************
1284  *              lineSetMediaMode (TAPI32.@)
1285  */
1286 DWORD WINAPI lineSetMediaMode(HCALL hCall, DWORD dwMediaModes)
1287 {
1288     FIXME("(%p, %08x): stub.\n", hCall, dwMediaModes);
1289     return 0;
1290 }
1291
1292 /***********************************************************************
1293  *              lineSetNumRings (TAPI32.@)
1294  */
1295 DWORD WINAPI lineSetNumRings(HLINE hLine, DWORD dwAddressID, DWORD dwNumRings)
1296 {
1297     FIXME("(%p, %08x, %08x): stub.\n", hLine, dwAddressID, dwNumRings);
1298     return 0;
1299 }
1300
1301 /***********************************************************************
1302  *              lineSetStatusMessages (TAPI32.@)
1303  */
1304 DWORD WINAPI lineSetStatusMessages(HLINE hLine, DWORD dwLineStates, DWORD dwAddressStates)
1305 {
1306     FIXME("(%p, %08x, %08x): stub.\n", hLine, dwLineStates, dwAddressStates);
1307     return 0;
1308 }
1309
1310 /***********************************************************************
1311  *              lineSetTerminal (TAPI32.@)
1312  */
1313 DWORD WINAPI lineSetTerminal(HLINE hLine, DWORD dwAddressID, HCALL hCall, DWORD dwSelect, DWORD dwTerminalModes, DWORD dwTerminalID, DWORD bEnable)
1314 {
1315     FIXME("(%p, %08x, %p, %08x, %08x, %08x, %08x): stub.\n", hLine, dwAddressID, hCall, dwSelect, dwTerminalModes, dwTerminalID, bEnable);
1316     return 1;
1317 }
1318
1319 /***********************************************************************
1320  *              lineSetTollList (TAPI32.@)
1321  */
1322 DWORD WINAPI lineSetTollListA(HLINEAPP hLineApp, DWORD dwDeviceID, LPCSTR lpszAddressIn, DWORD dwTollListOption)
1323 {
1324     FIXME("(%p, %08x, %s, %08x): stub.\n", hLineApp, dwDeviceID, lpszAddressIn, dwTollListOption);
1325     return 0;
1326 }
1327
1328 /***********************************************************************
1329  *              lineSetupConference (TAPI32.@)
1330  */
1331 DWORD WINAPI lineSetupConferenceA(HCALL hCall, HLINE hLine, LPHCALL lphConfCall, LPHCALL lphConsultCall, DWORD dwNumParties, LPLINECALLPARAMS lpCallParams)
1332 {
1333     FIXME("(%p, %p, %p, %p, %08x, %p): stub.\n", hCall, hLine, lphConfCall, lphConsultCall, dwNumParties, lpCallParams);
1334     return 1;
1335 }
1336
1337 /***********************************************************************
1338  *              lineSetupTransfer (TAPI32.@)
1339  */
1340 DWORD WINAPI lineSetupTransferA(HCALL hCall, LPHCALL lphConsultCall, LPLINECALLPARAMS lpCallParams)
1341 {
1342     FIXME("(%p, %p, %p): stub.\n", hCall, lphConsultCall, lpCallParams);
1343     return 1;
1344 }
1345
1346 /***********************************************************************
1347  *              lineShutdown (TAPI32.@)
1348  */
1349 DWORD WINAPI lineShutdown(HLINEAPP hLineApp)
1350 {
1351     FIXME("(%p): stub.\n", hLineApp);
1352     return 0;
1353 }
1354
1355 /***********************************************************************
1356  *              lineSwapHold (TAPI32.@)
1357  */
1358 DWORD WINAPI lineSwapHold(HCALL hActiveCall, HCALL hHeldCall)
1359 {
1360     FIXME("(active: %p, held: %p): stub.\n", hActiveCall, hHeldCall);
1361     return 1;
1362 }
1363
1364 /***********************************************************************
1365  *              lineTranslateAddress (TAPI32.@)
1366  */
1367 DWORD WINAPI lineTranslateAddressA(HLINEAPP hLineApp, DWORD dwDeviceID, DWORD dwAPIVersion, LPCSTR lpszAddressIn, DWORD dwCard, DWORD dwTranslateOptions, LPLINETRANSLATEOUTPUT lpTranslateOutput)
1368 {
1369     FIXME("(%p, %08x, %08x, %s, %08x, %08x, %p): stub.\n", hLineApp, dwDeviceID, dwAPIVersion, lpszAddressIn, dwCard, dwTranslateOptions, lpTranslateOutput);
1370     return 0;
1371 }
1372
1373 /***********************************************************************
1374  *              lineTranslateDialog (TAPI32.@)
1375  */
1376 DWORD WINAPI lineTranslateDialogA(HLINEAPP hLineApp, DWORD dwDeviceID, DWORD dwAPIVersion, HWND hwndOwner, LPCSTR lpszAddressIn)
1377 {
1378     FIXME("(%p, %08x, %08x, %p, %s): stub.\n", hLineApp, dwDeviceID, dwAPIVersion, hwndOwner, lpszAddressIn);
1379     return 0;
1380 }
1381
1382 /***********************************************************************
1383  *              lineUncompleteCall (TAPI32.@)
1384  */
1385 DWORD WINAPI lineUncompleteCall(HLINE hLine, DWORD dwCompletionID)
1386 {
1387     FIXME("(%p, %08x): stub.\n", hLine, dwCompletionID);
1388     return 1;
1389 }
1390
1391 /***********************************************************************
1392  *              lineUnhold (TAPI32.@)
1393  */
1394 DWORD WINAPI lineUnhold(HCALL hCall)
1395 {
1396     FIXME("(%p): stub.\n", hCall);
1397     return 1;
1398 }
1399
1400 /***********************************************************************
1401  *              lineUnpark (TAPI32.@)
1402  */
1403 DWORD WINAPI lineUnparkA(HLINE hLine, DWORD dwAddressID, LPHCALL lphCall, LPCSTR lpszDestAddress)
1404 {
1405     FIXME("(%p, %08x, %p, %s): stub.\n", hLine, dwAddressID, lphCall, lpszDestAddress);
1406     return 1;
1407 }