[Commits] Rev 2943: Move common functionality (analyze service configuration) in file:///H:/bzr/5.2-windows-packaging-upgrade/

Vladislav Vaintroub wlad at montyprogram.com
Sun Jan 30 22:47:37 EET 2011


At file:///H:/bzr/5.2-windows-packaging-upgrade/

------------------------------------------------------------
revno: 2943
revision-id: wlad at montyprogram.com-20110130204745-m0sx0zf7i6uhej2o
parent: wlad at montyprogram.com-20110129230036-yv8rxvuemb8i52o6
committer: Vladislav Vaintroub <wlad at montyprogram.com>
branch nick: 5.2-windows-packaging-upgrade
timestamp: Sun 2011-01-30 21:47:45 +0100
message:
  Move common functionality (analyze service configuration)
  into winservice library.
  The exports (currently single function get_mysql_service_properties)
  are used in mysql_upgrade_service.exe, upgrade wizard and 
  inside the installer in a custom action.
-------------- next part --------------
=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt	2011-01-27 01:05:20 +0000
+++ b/sql/CMakeLists.txt	2011-01-30 20:47:45 +0000
@@ -186,10 +186,13 @@
     COMPONENT Server)
   TARGET_LINK_LIBRARIES(mysql_install_db mysys strings dbug)
 
+  ADD_LIBRARY(winservice STATIC winservice.c)
+  
   MYSQL_ADD_EXECUTABLE(mysql_upgrade_service
     mysql_upgrade_service.cc
     COMPONENT Server)
-  TARGET_LINK_LIBRARIES(mysql_upgrade_service mysys strings dbug)
+	
+  TARGET_LINK_LIBRARIES(mysql_upgrade_service mysys strings dbug winservice)
 
   # mysql_install_db should be in the same directory as mysqld
   # to work correctly

=== modified file 'sql/Makefile.am'
--- a/sql/Makefile.am	2011-01-27 01:05:20 +0000
+++ b/sql/Makefile.am	2011-01-30 20:47:45 +0000
@@ -153,6 +153,7 @@
 EXTRA_DIST =		udf_example.c udf_example.def $(BUILT_MAINT_SRC) \
 			nt_servc.cc nt_servc.h mysql_install_db.cc mysql_upgrade_service.cc \
 			message.mc  message.h message.rc MSG00001.bin \
+			winservice.c winservice.h
 			CMakeLists.txt
 
 CLEANFILES =        	lex_hash.h sql_yacc.output link_sources

=== modified file 'sql/mysql_upgrade_service.cc'
--- a/sql/mysql_upgrade_service.cc	2011-01-29 14:50:19 +0000
+++ b/sql/mysql_upgrade_service.cc	2011-01-30 20:47:45 +0000
@@ -26,6 +26,7 @@
 #include <my_sys.h>
 #include <m_string.h>
 #include <mysql_version.h>
+#include <winservice.h>
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -38,8 +39,8 @@
 static char mysqladmin_path[MAX_PATH];
 static char mysqlupgrade_path[MAX_PATH];
 
-static char defaults_file_param[FN_REFLEN];
-static char logfile_path[FN_REFLEN];
+static char defaults_file_param[MAX_PATH + 16]; /*--defaults-file=<path> */
+static char logfile_path[MAX_PATH];
 static char *opt_service;
 static SC_HANDLE service;
 static SC_HANDLE scm;
@@ -301,7 +302,7 @@
 /* 
   Shutdown mysql server. Not using mysqladmin, since 
   our --skip-grant-tables do not work anymore after mysql_upgrade
-  that does "flush privileges". Instead, the shutdown handle is set.
+  that does "flush privileges". Instead, the shutdown event  is set.
 */
 void initiate_mysqld_shutdown()
 {
@@ -327,8 +328,7 @@
 */
 static void change_service_config()
 {
-  wchar_t old_mysqld_path[MAX_PATH];
-  wchar_t *file_part;
+
   char defaults_file[MAX_PATH];
   char default_character_set[64];
 
@@ -346,59 +346,32 @@
   if (!QueryServiceConfigW(service, config, size, &needed))
     die("QueryServiceConfig failed with %d\n", GetLastError());
 
-  int numargs;
-  LPWSTR *args= CommandLineToArgvW(config->lpBinaryPathName, &numargs);
-
-  char commandline[3*FN_REFLEN +32];
-
-  /* Run some checks to ensure we're really upgrading mysql service */
-
-  if(numargs != 3)
-  {
-    die("Expected 3 parameters in service configuration binPath,"
-      "got %d parameters instead\n. binPath: %S", numargs, 
-      config->lpBinaryPathName);
-  }
-  if(wcsncmp(args[1], L"--defaults-file=", 16) != 0)
-  {
-    die("Unexpected service configuration, second parameter must start with "
-      "--defaults-file. binPath= %S", config->lpBinaryPathName);
-  }
-  GetFullPathNameW(args[0], MAX_PATH, old_mysqld_path, &file_part);
-
-  if(wcsicmp(file_part, L"mysqld.exe") != 0 && 
-    wcsicmp(file_part, L"mysqld") != 0)
-  {
-    die("The service executable is not mysqld. binPath: %S", 
-         config->lpBinaryPathName);
-  }
-
-  if(wcsicmp(file_part, L"mysqld") == 0)
-    wcscat_s(old_mysqld_path, L".exe");
-
-  int old_mysqld_major, old_mysqld_minor;
-  get_file_version(old_mysqld_path, &old_mysqld_major, &old_mysqld_minor);
+  mysqld_service_properties props;
+  if (get_mysql_service_properties(config->lpBinaryPathName, &props))
+  {
+    die("Not a valid MySQL service");
+  }
+
   int my_major= MYSQL_VERSION_ID/10000;
   int my_minor= (MYSQL_VERSION_ID - 10000*my_major)/100;
 
-  if(my_major < old_mysqld_major || 
-    (my_major == old_mysqld_major && my_minor < old_mysqld_minor))
+  if(my_major < props.version_major || 
+    (my_major == props.version_minor && my_minor < props.version_patch))
   {
     die("Can not downgrade, the service is currently running as version %d.%d"
-      ", my version is %d.%d", old_mysqld_major, old_mysqld_minor, my_major, 
-      my_minor);
+      ", my version is %d.%d", props.version_major, props.version_minor, 
+      my_major, my_minor);
   }
 
-  wcstombs(defaults_file, args[1] + 16, MAX_PATH);
   /*
     Remove basedir from defaults file, otherwise the service wont come up in 
     the new  version, and will complain about mismatched message file.
   */
-  WritePrivateProfileString("mysqld", "basedir",NULL, defaults_file);
+  WritePrivateProfileString("mysqld", "basedir",NULL, props.inifile);
 
 #ifdef _WIN64
   /* Currently, pbxt is non-functional on x64 */
-  WritePrivateProfileString("mysqld", "loose-skip-pbxt","1", defaults_file);
+  WritePrivateProfileString("mysqld", "loose-skip-pbxt","1", props.inifile);
 #endif
   /* 
     Replace default-character-set  with character-set-server, to avoid 
@@ -406,7 +379,7 @@
     message.
   */
   default_character_set[0]=0;
-  GetPrivateProfileStringA("mysqld", "default-character-set", NULL,
+  GetPrivateProfileString("mysqld", "default-character-set", NULL,
     default_character_set, sizeof(default_character_set), defaults_file);
   if(default_character_set[0])
   {
@@ -416,15 +389,16 @@
       default_character_set, defaults_file);
   }
 
-  sprintf_s(commandline, "\"%s\" \"%S\" \"%S\"", mysqld_path, args[1], args[2]);
+  sprintf(defaults_file_param,"--defaults-file=%s", props.inifile);
+  char commandline[3*MAX_PATH + 19];
+  sprintf_s(commandline, "\"%s\" \"%s\" \"%s\"", mysqld_path, 
+   defaults_file_param, opt_service);
   if (!ChangeServiceConfig(service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, 
          SERVICE_NO_CHANGE, commandline, NULL, NULL, NULL, NULL, NULL, NULL))
   {
     die("ChangeServiceConfigW failed with %d", GetLastError());
   }
 
-  sprintf_s(defaults_file_param, "%S", args[1]);
-  LocalFree(args);
 }
 
 
@@ -483,13 +457,13 @@
     for communication, for security reasons.
   */
   char socket_param[FN_REFLEN];
-  sprintf_s(socket_param,"--shared_memory_base_name=mysql_upgrade_service_%d", 
+  sprintf_s(socket_param,"--socket=mysql_upgrade_service_%d", 
     GetCurrentProcessId());
 
   log("Phase 3/8: Starting mysqld for upgrade");
   mysqld_process= (HANDLE)run_tool(P_NOWAIT, mysqld_path,
     defaults_file_param, "--skip-networking",  "--skip-grant-tables", 
-    "--enable-shared-memory",  socket_param, NULL);
+    "--enable-named-pipe",  socket_param, NULL);
 
   if(mysqld_process == INVALID_HANDLE_VALUE)
   {
@@ -503,7 +477,7 @@
     if (WaitForSingleObject(mysqld_process, 0) != WAIT_TIMEOUT)
       die("mysqld.exe did not start");
 
-    if (run_tool(P_WAIT, mysqladmin_path, "--protocol=memory",
+    if (run_tool(P_WAIT, mysqladmin_path, "--protocol=pipe",
       socket_param, "ping",  NULL) == 0)
     {
       break;
@@ -516,7 +490,7 @@
 
   log("Phase 5/8: Running mysql_upgrade");
   int upgrade_err = (int) run_tool(P_WAIT,  mysqlupgrade_path, 
-    "--protocol=memory", "--force",  socket_param,
+    "--protocol=pipe", "--force",  socket_param,
     NULL);
 
   log("Phase 6/8: Initiating server shutdown");

=== modified file 'win/packaging/CMakeLists.txt'
--- a/win/packaging/CMakeLists.txt	2011-01-29 14:50:19 +0000
+++ b/win/packaging/CMakeLists.txt	2011-01-30 20:47:45 +0000
@@ -23,6 +23,7 @@
    $ENV{ProgramFiles}/wix/bin
   "$ENV{ProgramFiles}/Windows Installer XML v3/bin"
   "$ENV{ProgramFiles}/Windows Installer XML v3.5/bin"
+  "$ENV{ProgramFiles}/Windows Installer XML v3.6/bin"
 )
 
 SET(CPACK_WIX_PACKAGE_BASE_NAME "MariaDB")

=== modified file 'win/packaging/ca/CMakeLists.txt'
--- a/win/packaging/ca/CMakeLists.txt	2011-01-29 14:50:19 +0000
+++ b/win/packaging/ca/CMakeLists.txt	2011-01-30 20:47:45 +0000
@@ -18,6 +18,7 @@
 
 SET(WIXCA_SOURCES CustomAction.cpp CustomAction.def)
 
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql)
 
 IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
   SET(WIX_ARCH_SUFFIX "_x64")
@@ -47,4 +48,4 @@
 ADD_VERSION_INFO(wixca SHARED WIXCA_SOURCES)
 ADD_LIBRARY(wixca SHARED EXCLUDE_FROM_ALL ${WIXCA_SOURCES})
 TARGET_LINK_LIBRARIES(wixca ${WIX_WCAUTIL_LIBRARY} ${WIX_DUTIL_LIBRARY} 
-  msi version)
+  msi version winservice)

=== modified file 'win/packaging/ca/CustomAction.cpp'
--- a/win/packaging/ca/CustomAction.cpp	2011-01-29 23:00:36 +0000
+++ b/win/packaging/ca/CustomAction.cpp	2011-01-30 20:47:45 +0000
@@ -27,6 +27,7 @@
 #include <strsafe.h>
 #include <assert.h>
 
+#include <winservice.h>
 
 UINT ExecRemoveDataDirectory(wchar_t *dir)
 {
@@ -467,8 +468,8 @@
     }
     if(CheckServiceExists(ServiceName))
     {
-      ErrorMsg= L"A service with the same name already exists." 
-        "Please use a different name.";
+      ErrorMsg=
+       L"A service with the same name already exists.Please use a different name.";
       goto err;
     }
   }
@@ -511,8 +512,7 @@
     short port = (short)_wtoi(Port);
     if (!IsPortFree(port))
     {
-      ErrorMsg = L"The TCP Port you selected is already in use. " 
-        "Please choose a different port.";
+      ErrorMsg = L"The TCP Port you selected is already in use. Please choose a different port.";
       goto err;
     }
   }
@@ -565,49 +565,6 @@
   return WcaFinalize(er); 
 }
 
-/* 
- Extract major and minor version from
- mysqld.exe, using commandline in service definition
-*/
-static void GetMySQLVersion(
-  wchar_t *cmdline,
-  wchar_t *programBuf,
-  bool *isMySQL, int *major, int *minor)
-{
-   *major= 0;
-   *minor= 0;
-   *isMySQL= false;
-   int argc;
-   wchar_t **wargv = CommandLineToArgvW(cmdline, &argc);
-   if(argc != 3)
-     return;
-
-   wchar_t path[MAX_PATH];
-   wchar_t *filepart;
-
-   wcscpy_s(programBuf, MAX_PATH, wargv[0]);
-   if(!wcsstr(programBuf, L".exe"))
-     wcscat_s(programBuf,MAX_PATH, L".exe");
-
-   GetFullPathNameW(programBuf,MAX_PATH, path, &filepart);
-   if(wcsicmp(filepart, L"mysqld.exe") == 0)
-   {
-      *isMySQL = true;
-      DWORD handle;
-      DWORD size = GetFileVersionInfoSizeW(path, &handle);
-      BYTE* versionInfo = new BYTE[size];
-      if (GetFileVersionInfo(path, handle, size, versionInfo))
-      {
-         UINT len = 0;
-         VS_FIXEDFILEINFO*   vsfi = NULL;
-         VerQueryValueW(versionInfo, L"\\", (void**)&vsfi, &len);
-        *major= HIWORD(vsfi->dwFileVersionMS); 
-        *minor= LOWORD(vsfi->dwFileVersionMS);
-      }
-      delete[] versionInfo; 
-   }
-}
-
 
 /*
   Enables/disables optional "Launch upgrade wizard" checkbox at the end of 
@@ -622,7 +579,7 @@
   wchar_t* service= 0;
   wchar_t* dir= 0;
   wchar_t installerVersion[MAX_VERSION_PROPERTY_SIZE];
-  wchar_t installDir[MAX_PATH];
+  char installDir[MAX_PATH];
   DWORD size =MAX_VERSION_PROPERTY_SIZE;
   int installerMajorVersion, installerMinorVersion, installerPatchVersion;
   bool upgradableServiceFound=false;
@@ -642,7 +599,7 @@
   }
 
   size= MAX_PATH;
-  if (MsiGetPropertyW(hInstall,L"INSTALLDIR", installDir, &size)
+  if (MsiGetPropertyA(hInstall,"INSTALLDIR", installDir, &size)
     != ERROR_SUCCESS)
   {
     hr = HRESULT_FROM_WIN32(GetLastError());
@@ -688,23 +645,21 @@
     CloseServiceHandle(service);
     if (ok)
     {
-      bool isMySQL;
-      int major;
-      int minor;
-      wchar_t program[MAX_PATH]={0};
-      GetMySQLVersion(config->lpBinaryPathName, program, &isMySQL, &major,
-        &minor);
-      
+      mysqld_service_properties props;
+      if (get_mysql_service_properties(config->lpBinaryPathName, &props))
+        continue;
+
       /* 
         Only look for services that have mysqld.exe outside of the current
         installation directory.
       */
-      if(isMySQL && (wcsstr(program,installDir) == 0))
+      if(strstr(props.mysqld_exe,installDir) == 0)
       {
          WcaLog(LOGMSG_STANDARD, "found service %S, major=%d, minor=%d",
-           info[i].lpServiceName, major, minor);
-        if(major < installerMajorVersion
-          || (major == installerMajorVersion && minor <= installerMinorVersion))
+           info[i].lpServiceName, props.version_major, props.version_minor);
+         if(props.version_major < installerMajorVersion
+           || (props.version_major == installerMajorVersion && 
+               props.version_minor <= installerMinorVersion))
         {
           upgradableServiceFound= true;
           break;

=== modified file 'win/upgrade_wizard/CMakeLists.txt'
--- a/win/upgrade_wizard/CMakeLists.txt	2011-01-27 23:47:30 +0000
+++ b/win/upgrade_wizard/CMakeLists.txt	2011-01-30 20:47:45 +0000
@@ -18,9 +18,11 @@
 # Enable exception handling (avoids warnings)
 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
 
-MYSQL_ADD_EXECUTABLE(upgrade_wizard upgrade.cpp upgradeDlg.cpp upgrade.rc
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql)
+MYSQL_ADD_EXECUTABLE(upgrade_wizard
+  upgrade.cpp upgradeDlg.cpp upgrade.rc
   COMPONENT Server)
-
+TARGET_LINK_LIBRARIES(upgrade_wizard winservice)
 # upgrade_wizard is Windows executable, set WIN32_EXECUTABLE so it does not
 # create a console.
 SET_TARGET_PROPERTIES(upgrade_wizard PROPERTIES WIN32_EXECUTABLE 1)

=== modified file 'win/upgrade_wizard/upgradeDlg.cpp'
--- a/win/upgrade_wizard/upgradeDlg.cpp	2011-01-29 14:50:19 +0000
+++ b/win/upgrade_wizard/upgradeDlg.cpp	2011-01-30 20:47:45 +0000
@@ -14,6 +14,8 @@
 #include <string>
 #include <vector>
 
+#include <winservice.h>
+
 using namespace std;
 
 #ifdef _DEBUG
@@ -75,7 +77,7 @@
   <unknown> , of executable does not have any version
   info embedded (like MySQL 5.1 for example)
 */
-string GetExeVersion(const string& filename, int *major, int *minor, int *patch)
+void GetExeVersion(const string& filename, int *major, int *minor, int *patch)
 {
   DWORD handle;
   *major= *minor= *patch= 0;
@@ -85,20 +87,17 @@
   if (!GetFileVersionInfo(filename.c_str(), handle, size, versionInfo))
   {
     delete[] versionInfo;
-    return "<unknown>";
+    return;
   }
   // we have version information
   UINT len = 0;
   VS_FIXEDFILEINFO*   vsfi = NULL;
   VerQueryValue(versionInfo, "\\", (void**)&vsfi, &len);
-  char arr[64];
 
   *major= (int)HIWORD(vsfi->dwFileVersionMS);
   *minor= (int)LOWORD(vsfi->dwFileVersionMS);
   *patch= (int)HIWORD(vsfi->dwFileVersionLS);
-  sprintf_s(arr,"%d.%d.%d", *major, *minor, *patch); 
   delete[] versionInfo;
-  return string(arr);
 }
 
 
@@ -122,19 +121,6 @@
 }
 
 
-/* Remove quotes from string */
-static char *RemoveQuotes(char *s)
-{
-  if(s[0]=='"')
-  {
-    s++;
-    char *p= strchr(s, '"');
-    if(p)
-      *p= 0;
-  }
-  return s;
-}
-
 
 /*
   Iterate over services, lookup for mysqld.exe ones.
@@ -157,8 +143,7 @@
 
   static BYTE buf[64*1024];
   static BYTE configBuffer[8*1024];
-  char datadirBuf[MAX_PATH];
-  char datadirNormalized[MAX_PATH];
+
   DWORD bufsize= sizeof(buf);
   DWORD bufneed;
   DWORD num_services;
@@ -184,70 +169,39 @@
     CloseServiceHandle(service);
     if (ok)
     {
-      int argc;
-      wchar_t **wargv = CommandLineToArgvW(config->lpBinaryPathName, &argc);
-
-      // We expect  path\to\mysqld --defaults-file=<path> <servicename>
-      if(argc == 3)  
+      mysqld_service_properties service_props;
+
+      if (get_mysql_service_properties(config->lpBinaryPathName, 
+          &service_props))
+        continue;
+
+      /* Check if service uses mysqld in installation directory */
+      if (_strnicmp(service_props.mysqld_exe, m_InstallDir.c_str(),
+            m_InstallDir.size()) == 0)
+        continue;
+
+      if(m_MajorVersion > service_props.version_major || 
+        (m_MajorVersion == service_props.version_major && m_MinorVersion >= 
+        service_props.version_minor))
       {
-        
-         // Convert wide strings to ANSI 
-        char *argv[3];
-        for(int k=0; k < 3;k++)
-        {
-          size_t nbytes = 2*wcslen(wargv[k])+1; 
-          argv[k]= new char[nbytes];
-          wcstombs(argv[k], wargv[k], nbytes);
-        }
-
-        size_t len= strlen(argv[0]);
-        char path[MAX_PATH]={0};
-        char *filepart;
-        GetFullPathName(argv[0],MAX_PATH, path, &filepart);
-        if(_stricmp(filepart, "mysqld.exe") == 0 ||
-          _stricmp(filepart, "mysqld") == 0)
-        {
-          if(_strnicmp(argv[1],"--defaults-file=",16) == 0)
-          {
-            /* Remove quotes around defaults-file */
-            char *inifile= argv[1] + 16;
-            inifile = RemoveQuotes(inifile);
-
-            char *datadir=datadirBuf;
-            GetPrivateProfileString("mysqld", "datadir", NULL, datadirBuf,
-              MAX_PATH, inifile);
-
-            /* Remove quotes from datadir */
-            datadir= RemoveQuotes(datadir);
-
-            GetFullPathName(datadir, MAX_PATH, datadirNormalized, NULL);
-            ServiceProperties props;
-
-            props.myini = inifile;
-            props.servicename = info[i].lpServiceName;
-            string exefilename(argv[0]);
-            if(!strstr(argv[0], ".exe"))
-              exefilename += ".exe";
-            int major, minor, patch;
-            props.version= GetExeVersion(exefilename, &major, &minor, &patch);
-            if(m_MajorVersion > major || 
-              (m_MajorVersion == major && m_MinorVersion >= minor))
-            {
-              if (_strnicmp(exefilename.c_str(), m_InstallDir.c_str(),
-                m_InstallDir.size()) != 0)
-              {
-                props.datadir = datadirNormalized;
-                index = m_Services.AddString(info[i].lpServiceName);
-                services.resize(index+1);
-                services[index] = props;
-              }
-            }
-          }
-        }
-        for(int k=0; k< 3;k++)
-          delete[] argv[k];
+        ServiceProperties props;
+        props.myini= service_props.inifile;
+        props.datadir= service_props.datadir;
+        props.servicename = info[i].lpServiceName;
+        if (service_props.version_major)
+        {
+          char ver[64];
+          sprintf(ver, "%d.%d.%d", service_props.version_major, 
+            service_props.version_minor, service_props.version_patch);
+          props.version= ver;
+        }
+        else
+          props.version= "<unknown>";
+
+        index = m_Services.AddString(info[i].lpServiceName);
+        services.resize(index+1);
+        services[index] = props;
       }
-      LocalFree((HLOCAL)wargv);
     }
     if (index != -1)
     {



More information about the commits mailing list