tapi32: Properly implement lineGetCountryW.
Hans Leidekker
hans at codeweavers.com
Wed Jun 12 09:07:37 CDT 2013
---
dlls/tapi32/line.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 135 insertions(+), 16 deletions(-)
diff --git a/dlls/tapi32/line.c b/dlls/tapi32/line.c
index 264e07b..2a13fad 100644
--- a/dlls/tapi32/line.c
+++ b/dlls/tapi32/line.c
@@ -31,6 +31,7 @@
#include "objbase.h"
#include "tapi.h"
#include "wine/debug.h"
+#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(tapi);
@@ -313,18 +314,8 @@ DWORD WINAPI lineGetConfRelatedCalls(HCALL hCall, LPLINECALLLIST lpCallList)
return 0;
}
-typedef struct tagTAPI_CountryInfo
-{
- DWORD dwCountryID;
- DWORD dwCountryCode;
- LPSTR lpCountryName;
- LPSTR lpSameAreaRule;
- LPSTR lpLongDistanceRule;
- LPSTR lpInternationalRule;
-} TAPI_CountryInfo;
-
/***********************************************************************
- * lineGetCountry (TAPI32.@)
+ * lineGetCountryA (TAPI32.@)
*/
DWORD WINAPI lineGetCountryA(DWORD dwCountryID, DWORD dwAPIVersion, LPLINECOUNTRYLIST lpLineCountryList)
{
@@ -484,11 +475,139 @@ DWORD WINAPI lineGetCountryA(DWORD dwCountryID, DWORD dwAPIVersion, LPLINECOUNTR
}
/***********************************************************************
- * lineGetCountry (TAPI32.@)
- */
-DWORD WINAPI lineGetCountryW(DWORD dwCountryID, DWORD dwAPIVersion, LPLINECOUNTRYLIST lpLineCountryList)
-{
- return lineGetCountryA(dwCountryID, dwAPIVersion, lpLineCountryList);
+ * lineGetCountryW (TAPI32.@)
+ */
+DWORD WINAPI lineGetCountryW(DWORD id, DWORD version, LPLINECOUNTRYLIST list)
+{
+ static const WCHAR country_listW[] =
+ {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
+ 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+ 'T','e','l','e','p','h','o','n','y','\\','C','o','u','n','t','r','y',' ','L','i','s','t',0};
+ static const WCHAR international_ruleW[] =
+ {'I','n','t','e','r','n','a','t','i','o','n','a','l','R','u','l','e',0};
+ static const WCHAR longdistance_ruleW[] =
+ {'L','o','n','g','D','i','s','t','a','n','c','e','R','u','l','e',0};
+ static const WCHAR samearea_ruleW[] =
+ {'S','a','m','e','A','r','e','a','R','u','l','e',0};
+ static const WCHAR nameW[] =
+ {'N','a','m','e',0};
+ static const WCHAR country_codeW[] =
+ {'C','o','u','n','t','r','y','C','o','d','e',0};
+ DWORD total_size, offset, i, num_countries, max_subkey_len;
+ LINECOUNTRYENTRY *entry;
+ WCHAR *subkey_name;
+ HKEY hkey;
+
+ if (!list) return LINEERR_INVALPOINTER;
+ TRACE("(%08x, %08x, %p(%d))\n", id, version, list, list->dwTotalSize);
+
+ if (RegOpenKeyW(HKEY_LOCAL_MACHINE, country_listW, &hkey) != ERROR_SUCCESS)
+ return LINEERR_INIFILECORRUPT;
+
+ total_size = list->dwTotalSize;
+ offset = sizeof(LINECOUNTRYLIST);
+ if (total_size < offset) return LINEERR_STRUCTURETOOSMALL;
+
+ memset(list, 0, total_size);
+ list->dwTotalSize = total_size;
+ list->dwUsedSize = offset;
+ list->dwNumCountries = 0;
+ list->dwCountryListSize = 0;
+ list->dwCountryListOffset = offset;
+
+ entry = (LINECOUNTRYENTRY *)(list + 1);
+
+ if (RegQueryInfoKeyW(hkey, NULL, NULL, NULL, &num_countries, &max_subkey_len,
+ NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
+ {
+ RegCloseKey(hkey);
+ return LINEERR_OPERATIONFAILED;
+ }
+ if (id) offset = sizeof(LINECOUNTRYENTRY);
+ else offset += num_countries * sizeof(LINECOUNTRYENTRY);
+
+ max_subkey_len++;
+ if (!(subkey_name = HeapAlloc(GetProcessHeap(), 0, max_subkey_len * sizeof(WCHAR))))
+ {
+ RegCloseKey(hkey);
+ return LINEERR_NOMEM;
+ }
+ for (i = 0; i < num_countries; i++)
+ {
+ DWORD len, size, size_int, size_long, size_name, size_same;
+ HKEY hsubkey;
+
+ if (RegEnumKeyW(hkey, i, subkey_name, max_subkey_len) != ERROR_SUCCESS) continue;
+ if (id && (atoiW(subkey_name) != id)) continue;
+ if (RegOpenKeyW(hkey, subkey_name, &hsubkey) != ERROR_SUCCESS) continue;
+
+ RegQueryValueExW(hsubkey, international_ruleW, NULL, NULL, NULL, &size_int);
+ len = size_int;
+
+ RegQueryValueExW(hsubkey, longdistance_ruleW, NULL, NULL, NULL, &size_long);
+ len += size_long;
+
+ RegQueryValueExW(hsubkey, nameW, NULL, NULL, NULL, &size_name);
+ len += size_name;
+
+ RegQueryValueExW(hsubkey, samearea_ruleW, NULL, NULL, NULL, &size_same);
+ len += size_same;
+
+ if (total_size < offset + len)
+ {
+ offset += len;
+ RegCloseKey(hsubkey);
+ if (id) break;
+ continue;
+ }
+ list->dwNumCountries++;
+ list->dwCountryListSize += sizeof(LINECOUNTRYENTRY);
+ list->dwUsedSize += len + sizeof(LINECOUNTRYENTRY);
+
+ if (id) i = 0;
+ entry[i].dwCountryID = atoiW(subkey_name);
+ size = sizeof(DWORD);
+ RegQueryValueExW(hsubkey, country_codeW, NULL, NULL, (BYTE *)&entry[i].dwCountryCode, &size);
+ entry[i].dwNextCountryID = 0;
+
+ if (i > 0) entry[i - 1].dwNextCountryID = entry[i].dwCountryID;
+
+ /* add country name */
+ entry[i].dwCountryNameSize = size_name;
+ entry[i].dwCountryNameOffset = offset;
+ RegQueryValueExW(hsubkey, nameW, NULL, NULL, (BYTE *)list + offset, &size_name);
+ offset += size_name;
+
+ /* add Same Area Rule */
+ entry[i].dwSameAreaRuleSize = size_same;
+ entry[i].dwSameAreaRuleOffset = offset;
+ RegQueryValueExW(hsubkey, samearea_ruleW, NULL, NULL, (BYTE *)list + offset, &size_same);
+ offset += size_same;
+
+ /* add Long Distance Rule */
+ entry[i].dwLongDistanceRuleSize = size_long;
+ entry[i].dwLongDistanceRuleOffset = offset;
+ RegQueryValueExW(hsubkey, longdistance_ruleW, NULL, NULL, (BYTE *)list + offset, &size_long);
+ offset += size_long;
+
+ /* add Long Distance Rule */
+ entry[i].dwInternationalRuleSize = size_int;
+ entry[i].dwInternationalRuleOffset = offset;
+ RegQueryValueExW(hsubkey, international_ruleW, NULL, NULL, (BYTE *)list + offset, &size_int);
+ offset += size_int;
+ RegCloseKey(hsubkey);
+
+ TRACE("added country %s at %p\n",
+ debugstr_w((const WCHAR *)((const char *)list + entry[i].dwCountryNameOffset)), &entry[i]);
+ if (id) break;
+ }
+ list->dwNeededSize = offset;
+
+ TRACE("%d available %d required\n", total_size, offset);
+
+ HeapFree(GetProcessHeap(), 0, subkey_name);
+ RegCloseKey(hkey);
+ return 0;
}
/***********************************************************************
--
1.7.10.4
More information about the wine-patches
mailing list