[SERVICES] Set default status to SERVICE_START_PENDING when starting a service.
[reactos.git] / reactos / dll / win32 / syssetup / install.c
index c2ce03c..b3bd427 100644 (file)
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 /*
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS system libraries
  * PURPOSE:           System setup
- * FILE:              lib/syssetup/install.c
+ * FILE:              dll/win32/syssetup/install.c
  * PROGRAMER:         Eric Kohl
  */
 
@@ -473,30 +473,100 @@ InstallSysSetupInfComponents(VOID)
 static BOOL
 EnableUserModePnpManager(VOID)
 {
+    SERVICE_STATUS_PROCESS ServiceStatus;
     SC_HANDLE hSCManager = NULL;
     SC_HANDLE hService = NULL;
+    DWORD dwStartTickCount;
+    DWORD dwOldCheckPoint;
+    DWORD BytesNeeded = 0;
+    DWORD dwWaitTime;
+    DWORD dwMaxWait;
     BOOL ret = FALSE;
 
     hSCManager = OpenSCManager(NULL, NULL, 0);
     if (hSCManager == NULL)
         goto cleanup;
 
-    hService = OpenServiceW(hSCManager, L"PlugPlay", SERVICE_CHANGE_CONFIG | SERVICE_START);
+    hService = OpenServiceW(hSCManager,
+                            L"PlugPlay",
+                            SERVICE_CHANGE_CONFIG | SERVICE_START | SERVICE_QUERY_STATUS);
     if (hService == NULL)
         goto cleanup;
 
-    ret = ChangeServiceConfigW(
-        hService,
-        SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE,
-        NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+    ret = ChangeServiceConfigW(hService,
+                               SERVICE_NO_CHANGE,
+                               SERVICE_AUTO_START,
+                               SERVICE_NO_CHANGE,
+                               NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL);
     if (!ret)
         goto cleanup;
 
     ret = StartServiceW(hService, 0, NULL);
+    if (!ret)
+    {
+        /* If the service is already running, just return TRUE */
+        ret = GetLastError() == ERROR_SERVICE_ALREADY_RUNNING;
+        goto cleanup;
+    }
+
+    ret = QueryServiceStatusEx(hService,
+                               SC_STATUS_PROCESS_INFO,
+                               (LPBYTE)&ServiceStatus,
+                               sizeof(SERVICE_STATUS_PROCESS),
+                               &BytesNeeded);
     if (!ret)
         goto cleanup;
 
-    ret = TRUE;
+    /* We don't want to wait for more than 30 seconds */
+    dwMaxWait = 30000;
+    dwStartTickCount = GetTickCount();
+
+    /* Loop until it's running */
+    while (ServiceStatus.dwCurrentState != SERVICE_RUNNING)
+    {
+        dwOldCheckPoint = ServiceStatus.dwCheckPoint;
+        dwWaitTime = ServiceStatus.dwWaitHint / 10;
+
+        /* Get the latest status info */
+        if (!QueryServiceStatusEx(hService,
+                                  SC_STATUS_PROCESS_INFO,
+                                  (LPBYTE)&ServiceStatus,
+                                  sizeof(SERVICE_STATUS_PROCESS),
+                                  &BytesNeeded))
+        {
+            /* Something went wrong... */
+            break;
+        }
+
+        /* Is the service making progress? */
+        if (ServiceStatus.dwCheckPoint > dwOldCheckPoint)
+        {
+            /* It is, get the latest tickcount to reset the max wait time */
+            dwStartTickCount = GetTickCount();
+            dwOldCheckPoint = ServiceStatus.dwCheckPoint;
+        }
+        else
+        {
+            /* It's not, make sure we haven't exceeded our wait time */
+            if (GetTickCount() >= dwStartTickCount + dwMaxWait)
+            {
+                /* We have, give up */
+                break;
+            }
+        }
+
+        /* Adjust the wait hint times */
+        if (dwWaitTime < 200)
+            dwWaitTime = 200;
+        else if (dwWaitTime > 10000)
+            dwWaitTime = 10000;
+
+        /* Wait before trying again */
+        Sleep(dwWaitTime);
+    }
+
+    ret = ServiceStatus.dwCurrentState == SERVICE_RUNNING;
 
 cleanup:
     if (hSCManager != NULL)
@@ -759,7 +829,7 @@ CreateShortcuts(VOID)
 
     /* Create program startmenu shortcuts */
     CreateShortcut(CSIDL_PROGRAMS, NULL, IDS_SHORT_EXPLORER, _T("%SystemRoot%\\explorer.exe"), IDS_CMT_EXPLORER, TRUE);
-    CreateShortcut(CSIDL_PROGRAMS, NULL, IDS_SHORT_DOWNLOADER, _T("%SystemRoot%\\system32\\downloader.exe"), IDS_CMT_DOWNLOADER, TRUE);
+    CreateShortcut(CSIDL_PROGRAMS, NULL, IDS_SHORT_DOWNLOADER, _T("%SystemRoot%\\system32\\rapps.exe"), IDS_CMT_DOWNLOADER, TRUE);
 
     /* Create administrative tools startmenu shortcuts */
     CreateShortcut(CSIDL_COMMON_ADMINTOOLS, NULL, IDS_SHORT_SERVICE, _T("%SystemRoot%\\system32\\servman.exe"), IDS_CMT_SERVMAN, TRUE);
@@ -773,9 +843,10 @@ CreateShortcuts(VOID)
         CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_CALC, _T("%SystemRoot%\\system32\\calc.exe"), IDS_CMT_CALC, TRUE);
         CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_CMD, _T("%SystemRoot%\\system32\\cmd.exe"), IDS_CMT_CMD, TRUE);
         CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_NOTEPAD, _T("%SystemRoot%\\system32\\notepad.exe"), IDS_CMT_NOTEPAD, TRUE);
-        CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_WORDPAD, _T("%SystemRoot%\\system32\\wordpad.exe"), IDS_CMT_WORDPAD, TRUE);
-        CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_SNAP, _T("%SystemRoot%\\system32\\screenshot.exe"), IDS_CMT_SCREENSHOT, TRUE);
         CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_RDESKTOP, _T("%SystemRoot%\\system32\\mstsc.exe"), IDS_CMT_RDESKTOP, TRUE);
+        CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_SNAP, _T("%SystemRoot%\\system32\\screenshot.exe"), IDS_CMT_SCREENSHOT, TRUE);
+        CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_WORDPAD, _T("%SystemRoot%\\system32\\wordpad.exe"), IDS_CMT_WORDPAD, TRUE);
+        CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_PAINT, _T("%SystemRoot%\\system32\\paint.exe"), IDS_CMT_PAINT, TRUE);
     }
 
     /* Create System Tools subfolder and fill if the exe is available */
@@ -784,6 +855,7 @@ CreateShortcuts(VOID)
         CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_CHARMAP, _T("%SystemRoot%\\system32\\charmap.exe"), IDS_CMT_CHARMAP, TRUE);
         CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_KBSWITCH, _T("%SystemRoot%\\system32\\kbswitch.exe"), IDS_CMT_KBSWITCH, TRUE);
         CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_REGEDIT, _T("%SystemRoot%\\regedit.exe"), IDS_CMT_REGEDIT, TRUE);
+        CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_DXDIAG, _T("%SystemRoot%\\system32\\dxdiag.exe"), IDS_CMT_DXDIAG, TRUE);
     }
 
     /* Create Accessibility subfolder and fill if the exe is available */
@@ -792,11 +864,20 @@ CreateShortcuts(VOID)
         CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_MAGNIFY, _T("%SystemRoot%\\system32\\magnify.exe"), IDS_CMT_MAGNIFY, TRUE);
     }
 
+    /* Create Entertainment subfolder and fill if the exe is available */
+    if (CreateShortcutFolder(CSIDL_PROGRAMS, IDS_SYS_ENTERTAINMENT, szFolder, sizeof(szFolder)/sizeof(szFolder[0])))
+    {
+        CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_MPLAY32, _T("%SystemRoot%\\system32\\mplay32.exe"), IDS_CMT_MPLAY32, TRUE);
+        CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_SNDVOL32, _T("%SystemRoot%\\system32\\sndvol32.exe"), IDS_CMT_SNDVOL32, TRUE);
+        CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_SNDREC32, _T("%SystemRoot%\\system32\\sndrec32.exe"), IDS_CMT_SNDREC32, TRUE);
+    }
+
     /* Create Games subfolder and fill if the exe is available */
     if (CreateShortcutFolder(CSIDL_PROGRAMS, IDS_GAMES, szFolder, sizeof(szFolder)/sizeof(szFolder[0])))
     {
         CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_SOLITAIRE, _T("%SystemRoot%\\system32\\sol.exe"), IDS_CMT_SOLITAIRE, TRUE);
         CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_WINEMINE, _T("%SystemRoot%\\system32\\winemine.exe"), IDS_CMT_WINEMINE, TRUE);
+        CreateShortcut(CSIDL_PROGRAMS, szFolder, IDS_SHORT_SPIDER, _T("%SystemRoot%\\system32\\spider.exe"), IDS_CMT_SPIDER, TRUE);
     }
 
     CoUninitialize();
@@ -881,6 +962,21 @@ InstallReactOS(HINSTANCE hInstance)
     /* Append the Admin-RID */
     AppendRidToSid(&AdminSid, DomainSid, DOMAIN_USER_RID_ADMIN);
 
+    CreateTempDir(L"TEMP");
+    CreateTempDir(L"TMP");
+
+    if (GetWindowsDirectory(szBuffer, sizeof(szBuffer) / sizeof(TCHAR)))
+    {
+        PathAddBackslash(szBuffer);
+        _tcscat(szBuffer, _T("system"));
+        CreateDirectory(szBuffer, NULL);
+    }
+
+    if (!CommonInstall())
+        return 0;
+
+    InstallWizard();
+
     /* Create the Administrator account */
     if (!SamCreateUser(L"Administrator", L"", AdminSid))
     {
@@ -932,21 +1028,6 @@ InstallReactOS(HINSTANCE hInstance)
     }
     /* END OF ROS HACK */
 
-    CreateTempDir(L"TEMP");
-    CreateTempDir(L"TMP");
-
-    if (GetWindowsDirectory(szBuffer, sizeof(szBuffer) / sizeof(TCHAR)))
-    {
-        PathAddBackslash(szBuffer);
-        _tcscat(szBuffer, _T("system"));
-        CreateDirectory(szBuffer, NULL);
-    }
-
-    if (!CommonInstall())
-        return 0;
-
-    InstallWizard();
-
     SetupCloseInfFile(hSysSetupInf);
     SetSetupType(0);
 
@@ -997,3 +1078,27 @@ SetupChangeFontSize(
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     return FALSE;
 }
+
+/*
+ * @unimplemented
+ */
+DWORD WINAPI
+SetupChangeLocaleEx(HWND hWnd,
+                    LCID Lcid,
+                    LPCWSTR lpSrcRootPath,
+                    char Unknown,
+                    DWORD dwUnused1,
+                    DWORD dwUnused2)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+/*
+ * @implemented
+ */
+DWORD WINAPI
+SetupChangeLocale(HWND hWnd, LCID Lcid)
+{
+    return SetupChangeLocaleEx(hWnd, Lcid, NULL, 0, 0, 0);
+}