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