Fix little spelling mistakes
[reactos.git] / reactos / dll / win32 / newdev / wizard.c
index 25c0445..de92038 100644 (file)
@@ -18,7 +18,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#define YDEBUG
 #include "newdev_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(newdev);
@@ -177,91 +176,6 @@ StartDevice(
        return Ret;
 }
 
-static BOOL
-PrepareFoldersToScan(
-       IN PDEVINSTDATA DevInstData,
-       IN HWND hwndDlg)
-{
-       TCHAR drive[] = {'?',':',0};
-       DWORD dwDrives = 0;
-       DWORD i;
-       UINT nType;
-       DWORD CustomTextLength = 0;
-       DWORD LengthNeeded = 0;
-       LPTSTR Buffer;
-
-       TRACE("Include removable devices: %s\n", IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEDIA) ? "yes" : "no");
-       TRACE("Include custom path      : %s\n", IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH) ? "yes" : "no");
-
-       /* Calculate length needed to store the search paths */
-       if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEDIA))
-       {
-               dwDrives = GetLogicalDrives();
-               for (drive[0] = 'A', i = 1; drive[0] <= 'Z'; drive[0]++, i <<= 1)
-               {
-                       if (dwDrives & i)
-                       {
-                               nType = GetDriveType(drive);
-                               if (nType == DRIVE_REMOVABLE || nType == DRIVE_CDROM)
-                               {
-                                       LengthNeeded += 3;
-                               }
-                       }
-               }
-       }
-       if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH))
-       {
-               CustomTextLength = 1 + SendDlgItemMessage(
-                       hwndDlg,
-                       IDC_COMBO_PATH,
-                       WM_GETTEXTLENGTH,
-                       (WPARAM)0,
-                       (LPARAM)0);
-               LengthNeeded += CustomTextLength;
-       }
-
-       /* Allocate space for search paths */
-       HeapFree(GetProcessHeap(), 0, DevInstData->CustomSearchPath);
-       DevInstData->CustomSearchPath = Buffer = HeapAlloc(
-               GetProcessHeap(),
-               0,
-               (LengthNeeded + 1) * sizeof(TCHAR));
-       if (!Buffer)
-       {
-               TRACE("HeapAlloc() failed\n");
-               SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-               return FALSE;
-       }
-
-       /* Fill search paths */
-       if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEDIA))
-       {
-               for (drive[0] = 'A', i = 1; drive[0] <= 'Z'; drive[0]++, i <<= 1)
-               {
-                       if (dwDrives & i)
-                       {
-                               nType = GetDriveType(drive);
-                               if (nType == DRIVE_REMOVABLE || nType == DRIVE_CDROM)
-                               {
-                                       Buffer += 1 + _stprintf(Buffer, drive);
-                               }
-                       }
-               }
-       }
-       if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH))
-       {
-               Buffer += 1 + SendDlgItemMessage(
-                       hwndDlg,
-                       IDC_COMBO_PATH,
-                       WM_GETTEXT,
-                       (WPARAM)CustomTextLength,
-                       (LPARAM)Buffer);
-       }
-       *Buffer = _T('\0');
-
-       return TRUE;
-}
-
 static DWORD WINAPI
 FindDriverProc(
        IN LPVOID lpParam)
@@ -272,39 +186,7 @@ FindDriverProc(
 
        DevInstData = (PDEVINSTDATA)lpParam;
 
-       /* Yes, we can safely ignore the problem (if any) */
-       SetupDiDestroyDriverInfoList(
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData,
-               SPDIT_COMPATDRIVER);
-
-       if (!DevInstData->CustomSearchPath)
-       {
-               /* Search in default location */
-               result = SearchDriver(DevInstData, NULL, NULL);
-       }
-       else
-       {
-               /* Search only in specified paths */
-               /* We need to check all specified directories to be
-                * sure to find the best driver for the device.
-                */
-               LPCTSTR Path;
-               for (Path = DevInstData->CustomSearchPath; *Path != '\0'; Path += _tcslen(Path) + 1)
-               {
-                       TRACE("Search driver in %S\n", Path);
-                       if (_tcslen(Path) == 2 && Path[1] == ':')
-                       {
-                               if (SearchDriverRecursive(DevInstData, Path))
-                                       result = TRUE;
-                       }
-                       else
-                       {
-                               if (SearchDriver(DevInstData, Path, NULL))
-                                       result = TRUE;
-                       }
-               }
-       }
+       result = ScanFoldersForDriver(DevInstData);
 
        if (result)
        {
@@ -385,6 +267,7 @@ PopulateCustomPathCombo(
                TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc);
                goto cleanup;
        }
+
        /* Allocate enough space to add 2 NULL chars at the end of the string */
        Buffer = HeapAlloc(GetProcessHeap(), 0, dwPathLength + 2 * sizeof(TCHAR));
        if (!Buffer)
@@ -407,9 +290,12 @@ PopulateCustomPathCombo(
        Buffer[dwPathLength] = Buffer[dwPathLength + 1] = '\0';
 
        /* Populate combo box */
-       for (Path = Buffer; *Path; Path += _tcslen(Path))
+       for (Path = Buffer; *Path; Path += _tcslen(Path) + 1)
+       {
                (void)ComboBox_AddString(hwndCombo, Path);
-       (void)ComboBox_SetCurSel(hwndCombo, 0);
+               if (Path == Buffer)
+                       (void)ComboBox_SetCurSel(hwndCombo, 0);
+       }
 
 cleanup:
        if (hKey != NULL)
@@ -421,7 +307,110 @@ static VOID
 SaveCustomPath(
        IN HWND hwndCombo)
 {
-       FIXME("Stub\n");
+       LPTSTR CustomPath = NULL;
+       DWORD CustomPathLength;
+       LPTSTR Buffer = NULL;
+       LPTSTR pBuffer; /* Pointer into Buffer */
+       int ItemsCount, Length;
+       DWORD i;
+       DWORD TotalLength = 0;
+       BOOL UseCustomPath = TRUE;
+       HKEY hKey = NULL;
+       LONG rc;
+
+       /* Get custom path */
+       Length = ComboBox_GetTextLength(hwndCombo) + 1;
+       CustomPath = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(TCHAR));
+       if (!CustomPath)
+       {
+               TRACE("HeapAlloc() failed\n");
+               goto cleanup;
+       }
+       CustomPathLength = ComboBox_GetText(hwndCombo, CustomPath, Length) + 1;
+
+       /* Calculate length of the buffer */
+       ItemsCount = ComboBox_GetCount(hwndCombo);
+       if (ItemsCount == CB_ERR)
+       {
+               TRACE("ComboBox_GetCount() failed\n");
+               goto cleanup;
+       }
+       for (i = 0; i < ItemsCount; i++)
+       {
+               Length = ComboBox_GetLBTextLen(hwndCombo, i);
+               if (Length == CB_ERR)
+               {
+                       TRACE("ComboBox_GetLBTextLen() failed\n");
+                       goto cleanup;
+               }
+               TotalLength += Length + 1;
+       }
+       TotalLength++; /* Final NULL char */
+
+       /* Allocate buffer */
+       Buffer = HeapAlloc(GetProcessHeap(), 0, (CustomPathLength + TotalLength + 1) * sizeof(TCHAR));
+       if (!Buffer)
+       {
+               TRACE("HeapAlloc() failed\n");
+               goto cleanup;
+       }
+
+       /* Fill the buffer */
+       pBuffer = &Buffer[CustomPathLength];
+       for (i = 0; i < ItemsCount; i++)
+       {
+               Length = ComboBox_GetLBText(hwndCombo, i, pBuffer);
+               if (Length == CB_ERR)
+               {
+                       TRACE("ComboBox_GetLBText() failed\n");
+                       goto cleanup;
+               }
+               else if (UseCustomPath && _tcsicmp(CustomPath, pBuffer) == 0)
+                       UseCustomPath = FALSE;
+               pBuffer += 1 + Length;
+       }
+       *pBuffer = '\0'; /* Add final NULL char */
+
+       if (!UseCustomPath)
+       {
+               /* Nothing to save to registry */
+               goto cleanup;
+       }
+
+       TotalLength += CustomPathLength;
+       _tcscpy(Buffer, CustomPath);
+
+       /* Save the buffer */
+       /* RegSetKeyValue would have been better... */
+       rc = RegOpenKeyEx(
+               HKEY_LOCAL_MACHINE,
+               REGSTR_PATH_SETUP REGSTR_KEY_SETUP,
+               0,
+               KEY_SET_VALUE,
+               &hKey);
+       if (rc != ERROR_SUCCESS)
+       {
+               TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc);
+               goto cleanup;
+       }
+       rc = RegSetValueEx(
+               hKey,
+               _T("Installation Sources"),
+               0,
+               REG_MULTI_SZ,
+               (const BYTE*)Buffer,
+               TotalLength * sizeof(TCHAR));
+       if (rc != ERROR_SUCCESS)
+       {
+               TRACE("RegSetValueEx() failed with error 0x%lx\n", rc);
+               goto cleanup;
+       }
+
+cleanup:
+       if (hKey != NULL)
+               RegCloseKey(hKey);
+       HeapFree(GetProcessHeap(), 0, CustomPath);
+       HeapFree(GetProcessHeap(), 0, Buffer);
 }
 
 static INT_PTR CALLBACK
@@ -494,7 +483,12 @@ WelcomeDlgProc(
                                case PSN_WIZNEXT:
                                        /* Handle a Next button click, if necessary */
                                        if (SendDlgItemMessage(hwndDlg, IDC_RADIO_AUTO, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED)
-                                               PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV);
+                                       {
+                                               if (PrepareFoldersToScan(DevInstData, TRUE, FALSE, NULL))
+                                                       PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV);
+                                               else
+                                                       PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED);
+                                       }
                                        return TRUE;
 
                                default:
@@ -514,7 +508,7 @@ static void
 IncludePath(HWND Dlg, BOOL Enabled)
 {
        EnableWindow(GetDlgItem(Dlg, IDC_COMBO_PATH), Enabled);
-       EnableWindow(GetDlgItem(Dlg, IDC_BROWSE), /*FIXME: Enabled*/ FALSE);
+       EnableWindow(GetDlgItem(Dlg, IDC_BROWSE), Enabled);
 }
 
 static void
@@ -591,9 +585,35 @@ CHSourceDlgProc(
                                        return TRUE;
 
                                case IDC_BROWSE:
-                                       /* FIXME: set the IDC_COMBO_PATH text */
-                                       FIXME("Should display browse folder dialog\n");
-                                       return FALSE;
+                               {
+                                       BROWSEINFO bi = { 0, };
+                                       LPITEMIDLIST pidl;
+
+                                       bi.hwndOwner = hwndDlg;
+                                       bi.ulFlags = BIF_RETURNONLYFSDIRS;
+                                       pidl = SHBrowseForFolder(&bi);
+                                       if (pidl)
+                                       {
+                                               TCHAR Directory[MAX_PATH];
+                                               IMalloc* malloc;
+
+                                               if (SHGetPathFromIDList(pidl, Directory))
+                                               {
+                                                       /* Set the IDC_COMBO_PATH text */
+                                                       ComboBox_SetText(GetDlgItem(hwndDlg, IDC_COMBO_PATH), Directory);
+                                               }
+
+                                               /* Free memory, if possible */
+                                               if (SUCCEEDED(SHGetMalloc(&malloc)))
+                                               {
+                                                       FIXME("Memory leak!\n");
+                                                       //malloc->Free(pidl);
+                                                       //malloc->Release();
+                                               }
+                                               return TRUE;
+                                       }
+                                       break;
+                               }
                        }
                        break;
                }
@@ -616,10 +636,18 @@ CHSourceDlgProc(
                                                SaveCustomPath(GetDlgItem(hwndDlg, IDC_COMBO_PATH));
                                                HeapFree(GetProcessHeap(), 0, DevInstData->CustomSearchPath);
                                                DevInstData->CustomSearchPath = NULL;
-                                               if (PrepareFoldersToScan(DevInstData, hwndDlg))
+                                               if (PrepareFoldersToScan(
+                                                       DevInstData,
+                                                       IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEDIA),
+                                                       IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH),
+                                                       GetDlgItem(hwndDlg, IDC_COMBO_PATH)))
+                                               {
                                                        PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV);
+                                               }
                                                else
+                                               {
                                                        PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED);
+                                               }
                                        }
                                        else
                                                /* FIXME */;
@@ -700,6 +728,11 @@ SearchDrvDlgProc(
                        {
                                case PSN_SETACTIVE:
                                        PropSheet_SetWizButtons(GetParent(hwndDlg), !PSWIZB_NEXT | !PSWIZB_BACK);
+                                       /* Yes, we can safely ignore the problem (if any) */
+                                       SetupDiDestroyDriverInfoList(
+                                               DevInstData->hDevInfo,
+                                               &DevInstData->devInfoData,
+                                               SPDIT_COMPATDRIVER);
                                        hThread = CreateThread(NULL, 0, FindDriverProc, DevInstData, 0, &dwThreadId);
                                        break;
 
@@ -826,6 +859,7 @@ NoDriverDlgProc(
        IN LPARAM lParam)
 {
        PDEVINSTDATA DevInstData;
+       HWND hwndControl;
 
        /* Get pointer to the global setup data */
        DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWL_USERDATA);
@@ -834,7 +868,6 @@ NoDriverDlgProc(
        {
                case WM_INITDIALOG:
                {
-                       HWND hwndControl;
                        BOOL DisableableDevice = FALSE;
 
                        DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam;
@@ -877,6 +910,9 @@ NoDriverDlgProc(
 
                                case PSN_WIZBACK:
                                        /* Handle a Back button click, if necessary */
+                                       hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
+                                       ShowWindow(hwndControl, SW_SHOW);
+                                       EnableWindow(hwndControl, TRUE);
                                        PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_CHSOURCE);
                                        return TRUE;