private void ReadCountryList() { var lcl = new LINECOUNTRYLIST(); int rc, neededSize = 30 * 1024; // 30K up front do { lcl.dwTotalSize = neededSize; IntPtr pLcl = Marshal.AllocHGlobal(neededSize); Marshal.StructureToPtr(lcl, pLcl, true); rc = NativeMethods.lineGetCountry(0, (int)TapiVersion.V21, pLcl); Marshal.PtrToStructure(pLcl, lcl); if (lcl.dwNeededSize > neededSize) { neededSize = lcl.dwNeededSize; rc = NativeMethods.LINEERR_STRUCTURETOOSMALL; } else if (rc == NativeMethods.LINEERR_OK) { var rawBuffer = new byte[lcl.dwUsedSize]; Marshal.Copy(pLcl, rawBuffer, 0, lcl.dwUsedSize); for (int i = 0; i < lcl.dwNumCountries; i++) { _countries.Add(ReadCountryEntry(lcl, rawBuffer, i)); } } Marshal.FreeHGlobal(pLcl); }while (rc == NativeMethods.LINEERR_STRUCTURETOOSMALL); }
private static Country ReadCountryEntry(LINECOUNTRYLIST lcl, byte[] rawBuffer, int pos) { var lce = new LINECOUNTRYENTRY(); int size = Marshal.SizeOf(lce); pos = lcl.dwCountryListOffset + (pos * size); IntPtr pLce = Marshal.AllocHGlobal(size); Marshal.Copy(rawBuffer, pos, pLce, size); Marshal.PtrToStructure(pLce, lce); Marshal.FreeHGlobal(pLce); return(new Country(lce.dwCountryID, lce.dwCountryCode, NativeMethods.GetString(rawBuffer, lce.dwCountryNameOffset, lce.dwCountryNameSize, NativeMethods.STRINGFORMAT_UNICODE), NativeMethods.GetString(rawBuffer, lce.dwSameAreaRuleOffset, lce.dwSameAreaRuleSize, NativeMethods.STRINGFORMAT_UNICODE), NativeMethods.GetString(rawBuffer, lce.dwLongDistanceRuleOffset, lce.dwLongDistanceRuleSize, NativeMethods.STRINGFORMAT_UNICODE), NativeMethods.GetString(rawBuffer, lce.dwInternationalRuleOffset, lce.dwInternationalRuleSize, NativeMethods.STRINGFORMAT_UNICODE))); }