partly implemented the mixer selection dialog
Modified: trunk/reactos/subsys/system/sndvol32/Cz.rc
Modified: trunk/reactos/subsys/system/sndvol32/De.rc
Modified: trunk/reactos/subsys/system/sndvol32/En.rc
Modified: trunk/reactos/subsys/system/sndvol32/Fr.rc
Modified: trunk/reactos/subsys/system/sndvol32/mixer.c
Modified: trunk/reactos/subsys/system/sndvol32/resources.h
Modified: trunk/reactos/subsys/system/sndvol32/sndvol32.c
Modified: trunk/reactos/subsys/system/sndvol32/sndvol32.h
Modified: trunk/reactos/subsys/system/sndvol32/sndvol32.xml

Modified: trunk/reactos/subsys/system/sndvol32/Cz.rc
--- trunk/reactos/subsys/system/sndvol32/Cz.rc	2005-09-27 00:46:19 UTC (rev 18114)
+++ trunk/reactos/subsys/system/sndvol32/Cz.rc	2005-09-27 01:02:15 UTC (rev 18115)
@@ -35,6 +35,8 @@
   PUSHBUTTON "&Zßznam", IDC_RECORDING, 13,61,47,8, BS_AUTORADIOBUTTON
   PUSHBUTTON "&JinÚ:", IDC_OTHER, 13,80,42,8, BS_AUTORADIOBUTTON | WS_DISABLED
   COMBOBOX IDC_LINE, 55,80,155,50, CBS_DROPDOWNLIST | WS_TABSTOP | WS_DISABLED
+  LTEXT "Show the following volume controls:", IDC_LABELCONTROLS, 7, 109, 162, 8
+  CONTROL "", IDC_CONTROLS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | WS_TABSTOP | WS_BORDER, 7, 122, 211, 96
 
   PUSHBUTTON "OK", IDOK, 114,226,50,14
   PUSHBUTTON "ZruÜit", IDCANCEL, 168,226,50,14

Modified: trunk/reactos/subsys/system/sndvol32/De.rc
--- trunk/reactos/subsys/system/sndvol32/De.rc	2005-09-27 00:46:19 UTC (rev 18114)
+++ trunk/reactos/subsys/system/sndvol32/De.rc	2005-09-27 01:02:15 UTC (rev 18115)
@@ -35,6 +35,8 @@
   PUSHBUTTON "&Aufnahme", IDC_RECORDING, 13,61,47,8, BS_AUTORADIOBUTTON
   PUSHBUTTON "A&ndere:", IDC_OTHER, 13,80,42,8, BS_AUTORADIOBUTTON | WS_DISABLED
   COMBOBOX IDC_LINE, 55,80,155,50, CBS_DROPDOWNLIST | WS_TABSTOP | WS_DISABLED
+  LTEXT "Show the following volume controls:", IDC_LABELCONTROLS, 7, 109, 162, 8
+  CONTROL "", IDC_CONTROLS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | WS_TABSTOP | WS_BORDER, 7, 122, 211, 96
 
   PUSHBUTTON "OK", IDOK, 114,226,50,14
   PUSHBUTTON "Abbrechen", IDCANCEL, 168,226,50,14

Modified: trunk/reactos/subsys/system/sndvol32/En.rc
--- trunk/reactos/subsys/system/sndvol32/En.rc	2005-09-27 00:46:19 UTC (rev 18114)
+++ trunk/reactos/subsys/system/sndvol32/En.rc	2005-09-27 01:02:15 UTC (rev 18115)
@@ -35,6 +35,8 @@
   PUSHBUTTON "&Recording", IDC_RECORDING, 13,61,47,8, BS_AUTORADIOBUTTON
   PUSHBUTTON "&Other:", IDC_OTHER, 13,80,42,8, BS_AUTORADIOBUTTON | WS_DISABLED
   COMBOBOX IDC_LINE, 55,80,155,50, CBS_DROPDOWNLIST | WS_TABSTOP | WS_DISABLED
+  LTEXT "Show the following volume controls:", IDC_LABELCONTROLS, 7, 109, 162, 8
+  CONTROL "", IDC_CONTROLS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | WS_TABSTOP | WS_BORDER, 7, 122, 211, 96
   
   PUSHBUTTON "OK", IDOK, 114,226,50,14
   PUSHBUTTON "Cancel", IDCANCEL, 168,226,50,14

Modified: trunk/reactos/subsys/system/sndvol32/Fr.rc
--- trunk/reactos/subsys/system/sndvol32/Fr.rc	2005-09-27 00:46:19 UTC (rev 18114)
+++ trunk/reactos/subsys/system/sndvol32/Fr.rc	2005-09-27 01:02:15 UTC (rev 18115)
@@ -35,6 +35,8 @@
   PUSHBUTTON "&Enregistrement", IDC_RECORDING, 13,61,47,8, BS_AUTORADIOBUTTON
   PUSHBUTTON "&Autre :", IDC_OTHER, 13,80,42,8, BS_AUTORADIOBUTTON | WS_DISABLED
   COMBOBOX IDC_LINE, 55,80,155,50, CBS_DROPDOWNLIST | WS_TABSTOP | WS_DISABLED
+  LTEXT "Show the following volume controls:", IDC_LABELCONTROLS, 7, 109, 162, 8
+  CONTROL "", IDC_CONTROLS, "SysListView32", LVS_REPORT | LVS_NOCOLUMNHEADER | WS_TABSTOP | WS_BORDER, 7, 122, 211, 96
   
   PUSHBUTTON "OK", IDOK, 114,226,50,14
   PUSHBUTTON "Annuler", IDCANCEL, 168,226,50,14

Modified: trunk/reactos/subsys/system/sndvol32/mixer.c
--- trunk/reactos/subsys/system/sndvol32/mixer.c	2005-09-27 00:46:19 UTC (rev 18114)
+++ trunk/reactos/subsys/system/sndvol32/mixer.c	2005-09-27 01:02:15 UTC (rev 18115)
@@ -117,11 +117,12 @@
     if (LineInfo->cControls > 0)
     {
         *Controls = HeapAlloc(GetProcessHeap(),
-                              HEAP_ZERO_MEMORY,
+                              0,
                               LineInfo->cControls * sizeof(MIXERCONTROL));
         if (*Controls != NULL)
         {
             MIXERLINECONTROLS LineControls;
+            MMRESULT Result;
             UINT j;
 
             LineControls.cbStruct = sizeof(LineControls);
@@ -130,18 +131,14 @@
             LineControls.cbmxctrl = sizeof(MIXERCONTROL);
             LineControls.pamxctrl = (PVOID)(*Controls);
 
-            for (j = 0; j < LineInfo->cControls; j++)
+            Result = mixerGetLineControls((HMIXEROBJ)Mixer->hmx,
+                                          &LineControls,
+                                          MIXER_GETLINECONTROLSF_ALL);
+            if (Result == MMSYSERR_NOERROR)
             {
-                (*Controls)[j].cbStruct = sizeof(MIXERCONTROL);
-            }
-
-            if (mixerGetLineControls((HMIXEROBJ)Mixer->hmx,
-                                     &LineControls,
-                                     MIXER_GETLINECONTROLSF_ALL) == MMSYSERR_NOERROR)
-            {
-                for (j = 0; j < LineInfo->cControls; j++)
+                for (j = 0; j < LineControls.cControls; j++)
                 {
-                    DPRINT("Line control: %ws", (*Controls)[j].szName);
+                    DPRINT("Line control: %ws\n", (*Controls)[j].szName);
                 }
 
                 return TRUE;
@@ -152,12 +149,12 @@
                          0,
                          *Controls);
                 *Controls = NULL;
-                DPRINT("Failed to get line controls!\n");
+                DPRINT("Failed to get line (ID: 0x%x) controls: %d\n", LineInfo->dwLineID, Result);
             }
         }
         else
         {
-            DPRINT("Failed to allocate memory for %d line controls!\n", LineInfo->cControls);
+            DPRINT("Failed to allocate memory for %d line (ID: 0x%x) controls!\n", LineInfo->dwLineID, LineInfo->cControls);
         }
 
         return FALSE;
@@ -174,19 +171,23 @@
 {
     UINT i;
     MIXERLINE LineInfo;
+    MMRESULT Result;
     BOOL Ret = TRUE;
 
     LineInfo.cbStruct = sizeof(LineInfo);
-    LineInfo.dwDestination = Line->Info.dwDestination;
     for (i = Line->Info.cConnections; i > 0; i--)
     {
+        LineInfo.dwDestination = Line->Info.dwDestination;
         LineInfo.dwSource = i - 1;
-        if (mixerGetLineInfo((HMIXEROBJ)Mixer->hmx,
-                             &LineInfo,
-                             MIXER_GETLINEINFOF_SOURCE) == MMSYSERR_NOERROR)
+        Result = mixerGetLineInfo((HMIXEROBJ)Mixer->hmx,
+                                  &LineInfo,
+                                  MIXER_GETLINEINFOF_SOURCE);
+        if (Result == MMSYSERR_NOERROR)
         {
             LPMIXERCONTROL Controls;
             PSND_MIXER_CONNECTION Con;
+            
+            DPRINT("++ Source: %ws\n", LineInfo.szName);
 
             if (!SndMixerQueryControls(Mixer,
                                        &LineInfo,
@@ -216,7 +217,7 @@
         }
         else
         {
-            DPRINT("Failed to get connection information!\n");
+            DPRINT("Failed to get connection information: %d\n", Result);
             Ret = FALSE;
             break;
         }
@@ -246,6 +247,8 @@
                                  &Line->Info,
                                  MIXER_GETLINEINFOF_DESTINATION) == MMSYSERR_NOERROR)
             {
+                DPRINT("+ Destination: %ws (%d)\n", Line->Info.szName, Line->Info.dwComponentType);
+
                 if (!SndMixerQueryConnections(Mixer, Line))
                 {
                     DPRINT("Failed to query mixer connections!\n");
@@ -445,3 +448,38 @@
     return FALSE;
 }
 
+BOOL
+SndMixerEnumConnections(PSND_MIXER Mixer,
+                        DWORD LineID,
+                        PFNSNDMIXENUMCONNECTIONS EnumProc,
+                        PVOID Context)
+{
+    if (Mixer->hmx)
+    {
+        PSND_MIXER_DESTINATION Line;
+
+        for (Line = Mixer->Lines; Line != NULL; Line = Line->Next)
+        {
+            if (Line->Info.dwLineID == LineID)
+            {
+                PSND_MIXER_CONNECTION Connection;
+
+                for (Connection = Line->Connections; Connection != NULL; Connection = Connection->Next)
+                {
+                    if (!EnumProc(Mixer,
+                                  LineID,
+                                  &Connection->Info,
+                                  Context))
+                    {
+                        return FALSE;
+                    }
+                }
+                
+                return TRUE;
+            }
+        }
+    }
+
+    return FALSE;
+}
+

Modified: trunk/reactos/subsys/system/sndvol32/resources.h
--- trunk/reactos/subsys/system/sndvol32/resources.h	2005-09-27 00:46:19 UTC (rev 18114)
+++ trunk/reactos/subsys/system/sndvol32/resources.h	2005-09-27 01:02:15 UTC (rev 18115)
@@ -17,6 +17,8 @@
 #define IDC_RECORDING 1003
 #define IDC_OTHER 1004
 #define IDC_LINE 1005
+#define IDC_LABELCONTROLS 1006
+#define IDC_CONTROLS 1007
 
 #define IDS_SNDVOL32 100
 #define IDS_NOMIXERDEVICES 101

Modified: trunk/reactos/subsys/system/sndvol32/sndvol32.c
--- trunk/reactos/subsys/system/sndvol32/sndvol32.c	2005-09-27 00:46:19 UTC (rev 18114)
+++ trunk/reactos/subsys/system/sndvol32/sndvol32.c	2005-09-27 01:02:15 UTC (rev 18115)
@@ -31,6 +31,7 @@
 ATOM MainWindowClass;
 HWND hMainWnd;
 HANDLE hAppHeap;
+LPTSTR lpAppTitle;
 
 #define GetDialogData(hwndDlg, type) \
     ( P##type )GetWindowLongPtr((hwndDlg), DWLP_USER)
@@ -44,6 +45,12 @@
     PMIXER_WINDOW MixerWindow;
     PSND_MIXER Mixer;
     HWND hwndDlg;
+    
+    UINT Selected;
+    DWORD SelectedLine;
+    DWORD PlaybackID;
+    DWORD RecordingID;
+    UINT OtherLines;
 } PREFERENCES_CONTEXT, *PPREFERENCES_CONTEXT;
 
 typedef struct _PREFERENCES_FILL_DEVICES
@@ -86,6 +93,209 @@
     return TRUE;
 }
 
+static BOOL CALLBACK
+PrefDlgAddLine(PSND_MIXER Mixer,
+               LPMIXERLINE Line,
+               PVOID Context)
+{
+    PPREFERENCES_CONTEXT PrefContext = (PPREFERENCES_CONTEXT)Context;
+    
+    switch (Line->dwComponentType)
+    {
+        case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS:
+            if (PrefContext->PlaybackID == (DWORD)-1)
+            {
+                PrefContext->PlaybackID = Line->dwLineID;
+
+                if (PrefContext->SelectedLine == (DWORD)-1)
+                {
+                    PrefContext->SelectedLine = Line->dwLineID;
+                }
+            }
+            else
+                goto AddToOthersLines;
+
+            break;
+
+        case MIXERLINE_COMPONENTTYPE_DST_WAVEIN:
+            if (PrefContext->RecordingID == (DWORD)-1)
+            {
+                PrefContext->RecordingID = Line->dwLineID;
+                
+                if (PrefContext->SelectedLine == (DWORD)-1)
+                {
+                    PrefContext->SelectedLine = Line->dwLineID;
+                }
+            }
+            else
+                goto AddToOthersLines;
+
+            break;
+
+        default:
+        {
+            LRESULT lres;
+            HWND hwndCbOthers;
+            
+            if (PrefContext->SelectedLine == (DWORD)-1)
+            {
+                PrefContext->SelectedLine = Line->dwLineID;
+            }
+
+AddToOthersLines:
+            hwndCbOthers = GetDlgItem(PrefContext->hwndDlg,
+                                      IDC_LINE);
+
+            lres = SendMessage(hwndCbOthers,
+                               CB_ADDSTRING,
+                               0,
+                               (LPARAM)Line->szName);
+            if (lres != CB_ERR)
+            {
+                SendMessage(hwndCbOthers,
+                            CB_SETITEMDATA,
+                            (WPARAM)lres,
+                            Line->dwLineID);
+
+                PrefContext->OtherLines++;
+            }
+            break;
+        }
+    }
+    
+    return TRUE;
+}
+
+static BOOL CALLBACK
+PrefDlgAddConnection(PSND_MIXER Mixer,
+                     DWORD LineID,
+                     LPMIXERLINE Line,
+                     PVOID Context)
+{
+    PPREFERENCES_CONTEXT PrefContext = (PPREFERENCES_CONTEXT)Context;
+    LVITEM lvi;
+    
+    lvi.mask = LVIF_TEXT | LVIF_PARAM;
+    lvi.iItem = 0;
+    lvi.iSubItem = 0;
+    lvi.pszText = Line->szName;
+    lvi.lParam = (LPARAM)Line->dwSource;
+    
+    SendMessage(GetDlgItem(PrefContext->hwndDlg,
+                           IDC_CONTROLS),
+                LVM_INSERTITEM,
+                0,
+                (LPARAM)&lvi);
+
+    return TRUE;
+}
+
+static VOID
+UpdatePrefDlgControls(PPREFERENCES_CONTEXT Context,
+                      DWORD LineID)
+{
+    UINT OldID, MixerID = 0;
+    INT DeviceCbIndex;
+
+    /* select the mixer */
+    DeviceCbIndex = SendMessage(GetDlgItem(Context->hwndDlg,
+                                           IDC_MIXERDEVICE),
+                                CB_GETCURSEL,
+                                0,
+                                0);
+    if (DeviceCbIndex != CB_ERR)
+    {
+        MixerID = SendMessage(GetDlgItem(Context->hwndDlg,
+                                         IDC_MIXERDEVICE),
+                              CB_GETITEMDATA,
+                              DeviceCbIndex,
+                              0);
+        if (MixerID == CB_ERR)
+        {
+            MixerID = 0;
+        }
+    }
+    
+    OldID = Context->Selected;
+    if (MixerID != OldID &&
+        SndMixerSelect(Context->Mixer,
+                       MixerID))
+    {
+        Context->Selected = SndMixerGetSelection(Context->Mixer);
+        
+        /* update the controls */
+        Context->PlaybackID = (DWORD)-1;
+        Context->RecordingID = (DWORD)-1;
+        Context->OtherLines = 0;
+        Context->SelectedLine = (DWORD)-1;
+
+        if (SndMixerEnumLines(Context->Mixer,
+                              PrefDlgAddLine,
+                              Context))
+        {
+            UINT SelBox = 0;
+
+            /* enable/disable controls and make default selection */
+            EnableWindow(GetDlgItem(Context->hwndDlg,
+                                    IDC_PLAYBACK),
+                         Context->PlaybackID != (DWORD)-1);
+            CheckDlgButton(Context->hwndDlg,
+                           IDC_PLAYBACK,
+                           (Context->PlaybackID != (DWORD)-1 && SelBox++ == 0) ?
+                               BST_CHECKED : BST_UNCHECKED);
+
+            EnableWindow(GetDlgItem(Context->hwndDlg,
+                                    IDC_RECORDING),
+                         Context->RecordingID != (DWORD)-1);
+            CheckDlgButton(Context->hwndDlg,
+                           IDC_RECORDING,
+                           (Context->RecordingID != (DWORD)-1 && SelBox++ == 0) ?
+                               BST_CHECKED : BST_UNCHECKED);
+
+            if (Context->OtherLines != 0)
+            {
+                /* select the first item in the other lines combo box by default */
+                SendMessage(GetDlgItem(Context->hwndDlg,
+                                       IDC_LINE),
+                            CB_SETCURSEL,
+                            0,
+                            0);
+            }
+            EnableWindow(GetDlgItem(Context->hwndDlg,
+                                    IDC_LINE),
+                         Context->OtherLines != 0);
+            CheckDlgButton(Context->hwndDlg,
+                           IDC_LINE,
+                           (Context->OtherLines != 0 && SelBox++ == 0) ?
+                               BST_CHECKED : BST_UNCHECKED);
+            
+            /* disable the OK button if the device doesn't have any lines */
+            EnableWindow(GetDlgItem(Context->hwndDlg,
+                                    IDOK),
+                         Context->PlaybackID != (DWORD)-1 ||
+                         Context->RecordingID != (DWORD)-1 ||
+                         Context->OtherLines != 0);
+
+            LineID = Context->SelectedLine;
+        }
+    }
+    
+    /* update the line sources list */
+    if ((MixerID != OldID && Context->SelectedLine != (DWORD)-1) ||
+        (Context->SelectedLine != LineID && LineID != (DWORD)-1))
+    {
+        Context->SelectedLine = LineID;
+        
+        ListView_DeleteAllItems(GetDlgItem(Context->hwndDlg,
+                                  IDC_CONTROLS));
+        
+        SndMixerEnumConnections(Context->Mixer,
+                                LineID,
+                                PrefDlgAddConnection,
+                                Context);
+    }
+}
+
 static INT_PTR CALLBACK
 DlgPreferencesProc(HWND hwndDlg,
                    UINT uMsg,
@@ -98,8 +308,70 @@
     {
         case WM_COMMAND:
         {
+            Context = GetDialogData(hwndDlg,
+                                    PREFERENCES_CONTEXT);
             switch (LOWORD(wParam))
             {
+                case IDC_MIXERDEVICE:
+                {
+                    if (HIWORD(wParam) == CBN_SELCHANGE)
+                    {
+                        UpdatePrefDlgControls(Context,
+                                              (DWORD)-1);
+                    }
+                    break;
+                }
+                
+                case IDC_LINE:
+                {
+                    if (HIWORD(wParam) == CBN_SELCHANGE)
+                    {
+                        UpdatePrefDlgControls(Context,
+                                              (DWORD)-1);
+                    }
+                    break;
+                }
+                
+                case IDC_PLAYBACK:
+                {
+                    UpdatePrefDlgControls(Context,
+                                          Context->PlaybackID);
+                    break;
+                }
+                
+                case IDC_RECORDING:
+                {
+                    UpdatePrefDlgControls(Context,
+                                          Context->RecordingID);
+                    break;
+                }
+                
+                case IDC_OTHER:
+                {
+                    INT LineCbIndex;
+                    DWORD LineID;
+
+                    LineCbIndex = SendMessage(GetDlgItem(Context->hwndDlg,
+                                                         IDC_MIXERDEVICE),
+                                              CB_GETCURSEL,
+                                              0,
+                                              0);
+                    if (LineCbIndex != CB_ERR)
+                    {
+                        LineID = SendMessage(GetDlgItem(Context->hwndDlg,
+                                                        IDC_MIXERDEVICE),
+                                             CB_GETITEMDATA,
+                                             LineCbIndex,
+                                             0);
+                        if (LineID != CB_ERR)
+                        {
+                            UpdatePrefDlgControls(Context,
+                                                  LineID);
+                        }
+                    }
+                    break;
+                }
+                
                 case IDOK:
                 case IDCANCEL:
                 {
@@ -126,6 +398,9 @@
         case WM_INITDIALOG:
         {
             PREFERENCES_FILL_DEVICES FillDevContext;
+            LVCOLUMN lvc;
+            RECT rcClient;
+            HWND hwndControls;
 
             SetWindowLongPtr(hwndDlg,
                              DWLP_USER,
@@ -133,6 +408,7 @@
             Context = (PPREFERENCES_CONTEXT)((LONG_PTR)lParam);
             Context->hwndDlg = hwndDlg;
             Context->Mixer = SndMixerCreate(hwndDlg);
+            Context->Selected = (UINT)-1;
 
             FillDevContext.PrefContext = Context;
             FillDevContext.hComboBox = GetDlgItem(hwndDlg,
@@ -141,6 +417,26 @@
             SndMixerEnumProducts(Context->Mixer,
                                  FillDeviceComboBox,
                                  &FillDevContext);
+
+            /* initialize the list view control */
+            hwndControls = GetDlgItem(hwndDlg,
+                                      IDC_CONTROLS);
+            ListView_SetExtendedListViewStyle(hwndControls,
+                                              LVS_EX_CHECKBOXES);
+
+            GetClientRect(hwndControls,
+                          &rcClient);
+            lvc.mask = LVCF_TEXT | LVCF_WIDTH;
+            lvc.pszText = TEXT("");
+            lvc.cx = rcClient.right;
+            SendMessage(hwndControls,
+                        LVM_INSERTCOLUMN,
+                        0,
+                        (LPARAM)&lvc);
+
+            /* update all controls */
+            UpdatePrefDlgControls(Context,
+                                  (DWORD)-1);
             return TRUE;
         }
 
@@ -222,6 +518,17 @@
                     PostQuitMessage(0);
                     break;
                 }
+                
+                case IDC_ABOUT:
+                {
+                    HICON hAppIcon = (HICON)GetClassLongPtrW(hwnd,
+                                                             GCLP_HICON);
+                    ShellAbout(hwnd,
+                               lpAppTitle,
+                               NULL,
+                               hAppIcon);
+                    break;
+                }
             }
             break;
         }
@@ -350,7 +657,6 @@
 static HWND
 CreateApplicationWindow(VOID)
 {
-    LPTSTR lpAppTitle;
     HWND hWnd;
 
     PMIXER_WINDOW MixerWindow = HeapAlloc(hAppHeap,
@@ -361,14 +667,6 @@
         return NULL;
     }
 
-    /* load the application title */
-    if (AllocAndLoadString(&lpAppTitle,
-                           hAppInstance,
-                           IDS_SNDVOL32) == 0)
-    {
-      lpAppTitle = NULL;
-    }
-
     if (mixerGetNumDevs() > 0)
     {
         hWnd = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT,
@@ -401,11 +699,6 @@
         LocalFree(lpErrMessage);
     }
 
-    if (lpAppTitle != NULL)
-    {
-        LocalFree(lpAppTitle);
-    }
-
     if (hWnd == NULL)
     {
         HeapFree(hAppHeap,
@@ -426,6 +719,14 @@
 
     hAppInstance = hInstance;
     hAppHeap = GetProcessHeap();
+    
+    /* load the application title */
+    if (AllocAndLoadString(&lpAppTitle,
+                           hAppInstance,
+                           IDS_SNDVOL32) == 0)
+    {
+      lpAppTitle = NULL;
+    }
 
     InitCommonControls();
 
@@ -454,6 +755,11 @@
     DestroyWindow(hMainWnd);
 
     UnregisterApplicationClasses();
+    
+    if (lpAppTitle != NULL)
+    {
+        LocalFree(lpAppTitle);
+    }
 
     return 0;
 }

Modified: trunk/reactos/subsys/system/sndvol32/sndvol32.h
--- trunk/reactos/subsys/system/sndvol32/sndvol32.h	2005-09-27 00:46:19 UTC (rev 18114)
+++ trunk/reactos/subsys/system/sndvol32/sndvol32.h	2005-09-27 01:02:15 UTC (rev 18115)
@@ -4,6 +4,7 @@
 #include <windows.h>
 #include <mmsystem.h>
 #include <commctrl.h>
+#include <shellapi.h>
 #include <stdio.h>
 #include <tchar.h>
 #include <string.h>
@@ -63,6 +64,7 @@
 } SND_MIXER, *PSND_MIXER;
 
 typedef BOOL (CALLBACK *PFNSNDMIXENUMLINES)(PSND_MIXER Mixer, LPMIXERLINE Line, PVOID Context);
+typedef BOOL (CALLBACK *PFNSNDMIXENUMCONNECTIONS)(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Context);
 typedef BOOL (CALLBACK *PFNSNDMIXENUMPRODUCTS)(PSND_MIXER Mixer, UINT Id, LPCTSTR ProductName, PVOID Context);
 
 PSND_MIXER SndMixerCreate(HWND hWndNotification);
@@ -73,7 +75,8 @@
 INT SndMixerGetProductName(PSND_MIXER Mixer, LPTSTR lpBuffer, UINT uSize);
 BOOL SndMixerEnumProducts(PSND_MIXER Mixer, PFNSNDMIXENUMPRODUCTS EnumProc, PVOID Context);
 INT SndMixerGetDestinationCount(PSND_MIXER Mixer);
-BOOL SndMixerEnumDestinationLines(PSND_MIXER Mixer, PFNSNDMIXENUMLINES EnumProc, PVOID Context);
+BOOL SndMixerEnumLines(PSND_MIXER Mixer, PFNSNDMIXENUMLINES EnumProc, PVOID Context);
+BOOL SndMixerEnumConnections(PSND_MIXER Mixer, DWORD LineID, PFNSNDMIXENUMCONNECTIONS EnumProc, PVOID Context);
 
 /*
  * MISC

Modified: trunk/reactos/subsys/system/sndvol32/sndvol32.xml
--- trunk/reactos/subsys/system/sndvol32/sndvol32.xml	2005-09-27 00:46:19 UTC (rev 18114)
+++ trunk/reactos/subsys/system/sndvol32/sndvol32.xml	2005-09-27 01:02:15 UTC (rev 18115)
@@ -4,7 +4,9 @@
 	<define name="__USE_W32API" />
 	<define name="UNICODE" />
 	<define name="_UNICODE" />
-	<define name="_WIN32_WINNT">0x6501</define>
+	<define name="_WIN32_IE">0x0500</define>
+	<define name="_WIN32_WINNT">0x0600</define>
+	<define name="WINVER">0x0600</define>
 	<library>ntdll</library>
 	<library>user32</library>
 	<library>gdi32</library>