[ros-diffs] [janderwald] 28433: - support reading multiple boot configuration - support saving prefered boot configuration (freeldr / boot ini style) - parsing of boot options needs to be done

janderwald at svn.reactos.org janderwald at svn.reactos.org
Mon Aug 20 21:21:55 CEST 2007


Author: janderwald
Date: Mon Aug 20 23:21:54 2007
New Revision: 28433

URL: http://svn.reactos.org/svn/reactos?rev=28433&view=rev
Log:
- support reading multiple boot configuration
- support saving prefered boot configuration (freeldr / boot ini style)
- parsing of boot options needs to be done

Modified:
    trunk/reactos/dll/cpl/sysdm/precomp.h
    trunk/reactos/dll/cpl/sysdm/startrec.c
    trunk/reactos/dll/cpl/sysdm/sysdm.rbuild

Modified: trunk/reactos/dll/cpl/sysdm/precomp.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/sysdm/precomp.h?rev=28433&r1=28432&r2=28433&view=diff
==============================================================================
--- trunk/reactos/dll/cpl/sysdm/precomp.h (original)
+++ trunk/reactos/dll/cpl/sysdm/precomp.h Mon Aug 20 23:21:54 2007
@@ -3,7 +3,6 @@
 
 #include <ntstatus.h>
 #define WIN32_NO_STATUS
-#include <windows.h>
 #include <windows.h>
 #include <commctrl.h>
 #include <powrprof.h>
@@ -16,6 +15,7 @@
 #include <shlobj.h>
 #include <cplext.h>
 #include <regstr.h>
+#include <setupapi.h>
 #include "resource.h"
 
 #define NUM_APPLETS (1)
@@ -66,5 +66,13 @@
     PAGEFILE  Pagefile[26];
 } VIRTMEM, *PVIRTMEM;
 
+typedef struct _BOOTRECORD
+{
+  DWORD BootType;
+  TCHAR szSectionName[128];
+  TCHAR szBootPath[MAX_PATH];
+  TCHAR szOptions[512];
+
+}BOOTRECORD, *PBOOTRECORD;
 
 #endif /* __CPL_SYSDM_H */

Modified: trunk/reactos/dll/cpl/sysdm/startrec.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/sysdm/startrec.c?rev=28433&r1=28432&r2=28433&view=diff
==============================================================================
--- trunk/reactos/dll/cpl/sysdm/startrec.c (original)
+++ trunk/reactos/dll/cpl/sysdm/startrec.c Mon Aug 20 23:21:54 2007
@@ -10,10 +10,8 @@
  */
 
 #include "precomp.h"
-
 static TCHAR m_szFreeldrIni[MAX_PATH + 15];
-static TCHAR szBootLdrSection[12];
-static TCHAR szBootLdrDefault[10];
+static int m_FreeLdrIni = 0;
 
 void SetTimeout(HWND hwndDlg, int Timeout)
 {
@@ -27,6 +25,431 @@
     }
     SendDlgItemMessage(hwndDlg, IDC_STRRECLISTUPDWN, UDM_SETPOS, (WPARAM) 0, (LPARAM) MAKELONG((short) Timeout, 0));
 }
+
+DWORD GetSystemDrive(TCHAR ** szSystemDrive)
+{
+    DWORD dwBufSize;
+    /* get Path to freeldr.ini or boot.ini */
+    *szSystemDrive = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(TCHAR));
+    if (szSystemDrive != NULL)
+    {
+        dwBufSize = GetEnvironmentVariable(_T("SystemDrive"), *szSystemDrive, MAX_PATH);
+        if (dwBufSize > MAX_PATH)
+        {
+            TCHAR *szTmp;
+            DWORD dwBufSize2;
+
+            szTmp = HeapReAlloc(GetProcessHeap(), 0, *szSystemDrive, dwBufSize * sizeof(TCHAR));
+            if (szTmp == NULL)
+                goto FailGetSysDrive;
+
+            *szSystemDrive = szTmp;
+
+            dwBufSize2 = GetEnvironmentVariable(_T("SystemDrive"), *szSystemDrive, dwBufSize);
+            if (dwBufSize2 > dwBufSize || dwBufSize2 == 0)
+                goto FailGetSysDrive;
+        }
+        else if (dwBufSize == 0)
+        {
+FailGetSysDrive:
+            HeapFree(GetProcessHeap(), 0, szSystemDrive);
+            *szSystemDrive = NULL;
+            return FALSE;
+        }
+        return dwBufSize;
+    }
+    return FALSE;
+}
+
+PBOOTRECORD ReadFreeldrSection(HINF hInf, TCHAR * szSectionName)
+{
+   PBOOTRECORD pRecord;
+   INFCONTEXT InfContext;
+   TCHAR szName[MAX_PATH];
+   TCHAR szValue[MAX_PATH];
+   DWORD LineLength;
+
+   if (!SetupFindFirstLine(hInf,
+                          szSectionName,
+                          NULL,
+                          &InfContext))
+   {
+       /* failed to find section */
+       return NULL;
+   }
+
+   pRecord = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOTRECORD));
+   if (pRecord == NULL)
+   {
+      return NULL;
+   }
+   _tcscpy(pRecord->szSectionName, szSectionName);
+
+    do
+    {
+        if (!SetupGetStringField(&InfContext,
+                                  0,
+                                  szName,
+                                  sizeof(szName) / sizeof(TCHAR),
+                                  &LineLength))
+        {
+            break;
+        }
+
+        if (!SetupGetStringField(&InfContext,
+                                  1,
+                                  szValue,
+                                  sizeof(szValue) / sizeof(TCHAR),
+                                  &LineLength))
+        {
+            break;
+        }
+
+
+        if (!_tcsnicmp(szName, _T("BootType"), 8))
+        {
+            if (!_tcsnicmp(szValue, _T("ReactOS"), 7))
+            {
+                //FIXME store as enum
+                pRecord->BootType = 1; 
+            }
+            else
+            {
+                pRecord->BootType = 0;
+            }
+        }
+        else if (!_tcsnicmp(szName, _T("SystemPath"), 10))
+        {
+            _tcscpy(pRecord->szBootPath, szValue);
+        }
+        else if (!_tcsnicmp(szName, _T("Options"), 7))
+        {
+            //FIXME store flags as values
+            _tcscpy(pRecord->szOptions, szValue);
+        }
+
+    }while(SetupFindNextLine(&InfContext, &InfContext));
+
+    return pRecord;
+}
+
+
+int LoadFreeldrSettings(HINF hInf, HWND hwndDlg)
+{
+    INFCONTEXT InfContext;
+    PBOOTRECORD pRecord;
+    TCHAR szDefaultOs[MAX_PATH];
+    TCHAR szName[MAX_PATH];
+    TCHAR szValue[MAX_PATH];
+    DWORD LineLength;
+    DWORD TimeOut;
+    LRESULT lResult;
+
+    if (!SetupFindFirstLine(hInf,
+                           _T("FREELOADER"),
+                           _T("DefaultOS"),
+                           &InfContext))
+    {
+        /* failed to find default os */
+        return FALSE;
+    }
+
+    if (!SetupGetStringField(&InfContext,
+                             1,
+                             szDefaultOs,
+                             sizeof(szDefaultOs) / sizeof(TCHAR),
+                             &LineLength))
+    {
+        /* no key */
+        return FALSE;
+    }
+
+    if (!SetupFindFirstLine(hInf,
+                           _T("FREELOADER"),
+                           _T("TimeOut"),
+                           &InfContext))
+    {
+        /* expected to find timeout value */
+        return FALSE;
+    }
+
+
+    if (!SetupGetIntField(&InfContext, 
+                          1,
+                          (PINT)&TimeOut))
+    {
+        /* failed to retrieve timeout */
+        return FALSE;
+    }
+    
+    if (!SetupFindFirstLine(hInf,
+                           _T("Operating Systems"),
+                           NULL,
+                           &InfContext))
+    {
+       /* expected list of operating systems */
+       return FALSE;
+    }
+
+    do
+    {
+        if (!SetupGetStringField(&InfContext,
+                                 0,
+                                 szName,
+                                 sizeof(szName) / sizeof(TCHAR),
+                                 &LineLength))
+        {
+            /* the ini file is messed up */
+            return FALSE;
+        }
+
+        if (!SetupGetStringField(&InfContext,
+                                 1,
+                                 szValue,
+                                 sizeof(szValue) / sizeof(TCHAR),
+                                 &LineLength))
+        {
+            /* the ini file is messed up */
+            return FALSE;
+        }
+
+        pRecord = ReadFreeldrSection(hInf, szName);
+        if (pRecord)
+        {
+            lResult = SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValue);
+            if (lResult != CB_ERR)
+            {
+                SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)pRecord);
+                if (!_tcscmp(szDefaultOs, szName))
+                {
+                    /* we store the friendly name as key */
+                    _tcscpy(szDefaultOs, szValue);
+                }
+
+            }
+            else
+            {
+               HeapFree(GetProcessHeap(), 0, pRecord);
+            }
+        }
+
+    }while(SetupFindNextLine(&InfContext, &InfContext));
+
+    /* find default os in list */
+    lResult = SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_FINDSTRING, (WPARAM)-1, (LPARAM)szDefaultOs);
+    if (lResult != CB_ERR)
+    {
+       /* set cur sel */
+       SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)lResult, (LPARAM)0);
+    }
+
+    SetTimeout(hwndDlg, TimeOut);
+    return TRUE;
+}
+
+int LoadBootSettings(HINF hInf, HWND hwndDlg)
+{
+    INFCONTEXT InfContext;
+    TCHAR szName[MAX_PATH];
+    TCHAR szValue[MAX_PATH];
+    DWORD LineLength;
+    DWORD TimeOut = 0;
+    TCHAR szDefaultOS[MAX_PATH];
+    TCHAR szOptions[MAX_PATH];
+    PBOOTRECORD pRecord;
+    LRESULT lResult;
+
+    if(!SetupFindFirstLine(hInf,
+                           _T("boot loader"),
+                           NULL,
+                           &InfContext))
+    {
+        return FALSE;
+    }
+
+    do
+    {
+        if (!SetupGetStringField(&InfContext, 
+                                 0, 
+                                 szName,
+                                 sizeof(szName) / sizeof(TCHAR),
+                                 &LineLength))
+        {
+            return FALSE;
+        }
+
+        if (!SetupGetStringField(&InfContext, 
+                                 1, 
+                                 szValue,
+                                 sizeof(szValue) / sizeof(TCHAR),
+                                 &LineLength))
+        {
+            return FALSE;
+        }
+
+        if (!_tcsnicmp(szName, _T("timeout"), 7))
+        {
+            TimeOut = _ttoi(szValue);
+        }
+        
+        if (!_tcsnicmp(szName, _T("default"), 7))
+        {
+            _tcscpy(szDefaultOS, szValue);
+        }
+
+    }while(SetupFindNextLine(&InfContext, &InfContext));
+
+    if (!SetupFindFirstLine(hInf,
+                            _T("operating systems"),
+                            NULL,
+                            &InfContext))
+    {
+        /* failed to find operating systems section */
+        return FALSE;
+    }
+
+    do
+    {
+        if (!SetupGetStringField(&InfContext, 
+                                 0, 
+                                 szName,
+                                 sizeof(szName) / sizeof(TCHAR),
+                                 &LineLength))
+        {
+            return FALSE;
+        }
+
+        if (!SetupGetStringField(&InfContext, 
+                                 1, 
+                                 szValue,
+                                 sizeof(szValue) / sizeof(TCHAR),
+                                 &LineLength))
+        {
+            return FALSE;
+        }
+
+        SetupGetStringField(&InfContext, 
+                            2, 
+                            szOptions,
+                            sizeof(szOptions) / sizeof(TCHAR),
+                            &LineLength);
+
+        pRecord = (PBOOTRECORD) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOTRECORD));
+        if (pRecord)
+        {
+            pRecord->BootType = 0;
+            _tcscpy(pRecord->szBootPath, szName);
+            _tcscpy(pRecord->szSectionName, szValue);
+            _tcscpy(pRecord->szOptions, szOptions);
+
+            if (!_tcscmp(szName, szDefaultOS))
+            {
+                /* ms boot ini stores the path not the friendly name */
+                _tcscpy(szDefaultOS, szValue);
+            }
+
+            lResult = SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValue);
+            if (lResult != CB_ERR)
+            {
+                SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)pRecord);
+            }
+            else
+            {
+               HeapFree(GetProcessHeap(), 0, pRecord);
+            }
+        }
+
+    }while(SetupFindNextLine(&InfContext, &InfContext));
+    /* find default os in list */
+    lResult = SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_FINDSTRING, (WPARAM)0, (LPARAM)szDefaultOS);
+    if (lResult != CB_ERR)
+    {
+       /* set cur sel */
+       SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)lResult, (LPARAM)0);
+    }
+
+    SetTimeout(hwndDlg, TimeOut);
+    return TRUE;
+}
+
+void DeleteBootRecords(HWND hwndDlg)
+{
+    LRESULT lIndex;
+    LONG index;
+    PBOOTRECORD pRecord;
+
+
+    lIndex = SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_GETCOUNT, (WPARAM)0, (LPARAM)0);
+    if (lIndex == CB_ERR)
+        return;
+
+    for (index = 0; index <lIndex; index++)
+    {
+        pRecord = (PBOOTRECORD) SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_GETITEMDATA, (WPARAM)index, (LPARAM)0);
+        if ((INT)pRecord != CB_ERR)
+        {
+            HeapFree(GetProcessHeap(), 0, pRecord);
+        }
+    }
+    SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0);
+}
+
+LRESULT LoadOSList(HWND hwndDlg)
+{
+    DWORD dwBufSize;
+    TCHAR *szSystemDrive;
+    HINF hInf;
+
+    SetDlgItemText(hwndDlg, IDC_STRRECDUMPFILE, _T("%SystemRoot%\\MiniDump"));
+        
+    dwBufSize = GetSystemDrive(&szSystemDrive);
+    if (!dwBufSize)
+        return FALSE;
+    
+
+    _tcscpy(m_szFreeldrIni, szSystemDrive);
+    _tcscat(m_szFreeldrIni, _T("\\freeldr.ini"));
+    if (PathFileExists(m_szFreeldrIni))
+    {
+        /* freeldr.ini exists */
+        hInf = SetupOpenInfFile(m_szFreeldrIni, 
+                                NULL,
+                                INF_STYLE_OLDNT,
+                                NULL);
+
+        if (hInf != INVALID_HANDLE_VALUE)
+        {
+            LoadFreeldrSettings(hInf, hwndDlg);
+            SetupCloseInfFile(hInf);
+            m_FreeLdrIni = 1;
+            return TRUE;
+        }
+        return FALSE;
+    }
+    /* try load boot.ini settings */
+    _tcscpy(m_szFreeldrIni, szSystemDrive);
+    _tcscat(m_szFreeldrIni, _T("\\boot.ini"));
+
+    if (PathFileExists(m_szFreeldrIni))
+    {
+        /* load boot.ini settings */
+        hInf = SetupOpenInfFile(m_szFreeldrIni, 
+                                NULL,
+                                INF_STYLE_OLDNT,
+                                NULL);
+
+        if (hInf != INVALID_HANDLE_VALUE)
+        {
+            LoadBootSettings(hInf, hwndDlg);
+            SetupCloseInfFile(hInf);
+            m_FreeLdrIni = 2;
+            return TRUE;
+        }
+        return FALSE;
+    }
+    return FALSE;
+}
+
 
 /* Property page dialog callback */
 INT_PTR CALLBACK
@@ -35,11 +458,10 @@
                 WPARAM wParam,
                 LPARAM lParam)
 {
-    TCHAR *szSystemDrive;
-    TCHAR szDefaultOS[MAX_PATH];
-    TCHAR szDefaultOSName[MAX_PATH];
+    PBOOTRECORD pRecord;
+    int iTimeout;
+    LRESULT lResult;
     TCHAR szTimeout[10];
-    int iTimeout;
 
     UNREFERENCED_PARAMETER(lParam);
 
@@ -47,76 +469,7 @@
     {
         case WM_INITDIALOG:
         {
-            DWORD dwBufSize;
-
-            /* get Path to freeldr.ini or boot.ini */
-            szSystemDrive = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(TCHAR));
-            if (szSystemDrive != NULL)
-            {
-                dwBufSize = GetEnvironmentVariable(_T("SystemDrive"), szSystemDrive, MAX_PATH);
-                if (dwBufSize > MAX_PATH)
-                {
-                    TCHAR *szTmp;
-                    DWORD dwBufSize2;
-
-                    szTmp = HeapReAlloc(GetProcessHeap(), 0, szSystemDrive, dwBufSize * sizeof(TCHAR));
-                    if (szTmp == NULL)
-                        goto FailGetSysDrive;
-
-                    szSystemDrive = szTmp;
-
-                    dwBufSize2 = GetEnvironmentVariable(_T("SystemDrive"), szSystemDrive, dwBufSize);
-                    if (dwBufSize2 > dwBufSize || dwBufSize2 == 0)
-                        goto FailGetSysDrive;
-                }
-                else if (dwBufSize == 0)
-                {
-FailGetSysDrive:
-                    HeapFree(GetProcessHeap(), 0, szSystemDrive);
-                    szSystemDrive = NULL;
-                    return FALSE;
-                }
-
-                if (szSystemDrive != NULL)
-                {
-                    if (m_szFreeldrIni != NULL)
-                    {
-                        _tcscpy(m_szFreeldrIni, szSystemDrive);
-                        _tcscat(m_szFreeldrIni, _T("\\freeldr.ini"));
-                        if (!PathFileExists(m_szFreeldrIni))
-                        {
-                            _tcscpy(m_szFreeldrIni, szSystemDrive);
-                            _tcscat(m_szFreeldrIni, _T("\\boot.ini"));
-                            _tcscpy(szBootLdrSection, _T("boot loader"));
-                            _tcscpy(szBootLdrDefault, _T("default"));
-                        }
-                        else
-                        {
-                            _tcscpy(szBootLdrSection, _T("FREELOADER"));
-                            _tcscpy(szBootLdrDefault, _T("DefaultOS"));
-                        }
-                    }
-                    HeapFree(GetProcessHeap(), 0, szSystemDrive);
-                }
-            }
-
-            if (m_szFreeldrIni == NULL)
-                return FALSE;
-
-            SetDlgItemText(hwndDlg, IDC_STRRECDUMPFILE, _T("%SystemRoot%\\MiniDump"));
-
-            /* load settings from freeldr.ini */
-            GetPrivateProfileString(szBootLdrSection, szBootLdrDefault, NULL, szDefaultOS, MAX_PATH, m_szFreeldrIni);
-            GetPrivateProfileString(_T("operating systems"), szDefaultOS, NULL, szDefaultOSName, MAX_PATH, m_szFreeldrIni);
-            SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM)szDefaultOSName);
-            SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
-
-            /* timeout */
-            iTimeout = GetPrivateProfileInt(szBootLdrSection, _T("timeout"), 0, m_szFreeldrIni);
-            SetTimeout(hwndDlg, iTimeout);
-            if (iTimeout != 0)
-                SendDlgItemMessage(hwndDlg, IDC_STRECLIST, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
-
+            return LoadOSList(hwndDlg);
         }
         break;
 
@@ -127,6 +480,9 @@
                 case IDC_STRRECEDIT:
                 {
                     ShellExecute(0, _T("open"), _T("notepad"), m_szFreeldrIni, NULL, SW_SHOWNORMAL);
+                  // FIXME use CreateProcess and wait untill finished
+                  //  DeleteBootRecords(hwndDlg);
+                  //  LoadOSList(hwndDlg);
                     break;
                 }	
                 case IDOK:
@@ -137,14 +493,63 @@
                     else
                         iTimeout = 0;
                     _stprintf(szTimeout, _T("%i"), iTimeout);
-                    WritePrivateProfileString(szBootLdrSection, _T("timeout"), szTimeout, m_szFreeldrIni);
-                }
-                case IDCANCEL:
-                {
+
+                    lResult = SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
+                    if (lResult == CB_ERR)
+                    {
+                        /* ? */
+                        DeleteBootRecords(hwndDlg);
+                        return TRUE;
+                    }
+
+
+                    pRecord = (PBOOTRECORD) SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_GETITEMDATA, (WPARAM)lResult, (LPARAM)0);
+
+
+
+                    if ((INT)pRecord != CB_ERR)
+                    {
+                        if (m_FreeLdrIni == 1) // FreeLdrIni style
+                        {
+                            /* set default timeout */
+                            WritePrivateProfileString(_T("FREELOADER"),
+                                                      _T("TimeOut"),
+                                                      szTimeout,
+                                                      m_szFreeldrIni);
+                            /* set default os */
+                            WritePrivateProfileString(_T("FREELOADER"),
+                                                      _T("DefaultOS"),
+                                                      pRecord->szSectionName,
+                                                      m_szFreeldrIni);
+
+                        }
+                        else if (m_FreeLdrIni == 2) // BootIni style
+                        {
+                            /* set default timeout */
+                            WritePrivateProfileString(_T("boot loader"),
+                                                      _T("timeout"),
+                                                      szTimeout,
+                                                      m_szFreeldrIni);
+                            /* set default os */
+                            WritePrivateProfileString(_T("boot loader"),
+                                                      _T("default"),
+                                                      pRecord->szBootPath,
+                                                      m_szFreeldrIni);
+
+                        }
+                    }
+                    DeleteBootRecords(hwndDlg);
                     EndDialog(hwndDlg,
                               LOWORD(wParam));
                     return TRUE;
                     break;
+                }
+                case IDCANCEL:
+                {
+                    DeleteBootRecords(hwndDlg);
+                    EndDialog(hwndDlg,
+                              LOWORD(wParam));
+                    return TRUE;
                 }
                 case IDC_STRECLIST:
                 {

Modified: trunk/reactos/dll/cpl/sysdm/sysdm.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/sysdm/sysdm.rbuild?rev=28433&r1=28432&r2=28433&view=diff
==============================================================================
--- trunk/reactos/dll/cpl/sysdm/sysdm.rbuild (original)
+++ trunk/reactos/dll/cpl/sysdm/sysdm.rbuild Mon Aug 20 23:21:54 2007
@@ -8,6 +8,7 @@
 	<define name="WINVER">0x501</define>
 	<library>kernel32</library>
 	<library>advapi32</library>
+	<library>setupapi</library>
 	<library>msvcrt</library>
 	<library>user32</library>
 	<library>gdi32</library>




More information about the Ros-diffs mailing list