| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| #define WIN32_LEAN_AND_MEAN |
| |
| #ifdef _MSC_VER |
| #pragma warning(disable:4668 4917) // disable warnings for system headers |
| #endif |
| |
| #include <windows.h> |
| #include <windowsx.h> |
| #include <shellapi.h> |
| #include <shlobj.h> |
| #include <tchar.h> |
| |
| #include <stdio.h> |
| |
| #define elementsof(buf) (sizeof(buf) / sizeof(buf[0])) |
| |
| enum PathResult |
| { |
| PATHRESULT_OK, |
| PATHRESULT_API_NOT_SUPPORTED, |
| PATHRESULT_EXE_NOT_FOUND |
| }; |
| |
| const int MAXCMDLINELEN = 32768; |
| |
| static TCHAR g_szSTInstallationPath[MAX_PATH] = TEXT(""); |
| static TCHAR g_szOperatingSystem[256] = TEXT(""); |
| |
| static const TCHAR g_szSTExecutable[256] = TEXT("stclient.exe"); |
| |
| //*************************************************************************** |
| |
| LONG RegReadValue( HKEY hBaseKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, LPVOID lpData, DWORD cbData ) |
| { |
| HKEY hKey = NULL; |
| LONG lResult( 0 ); |
| |
| lResult = RegOpenKeyEx( hBaseKey, lpSubKey, 0, KEY_QUERY_VALUE, &hKey ); |
| |
| if ( ERROR_SUCCESS == lResult ) |
| { |
| lResult = RegQueryValueEx( hKey, lpValueName, NULL, NULL, (LPBYTE)lpData, &cbData ); |
| RegCloseKey( hKey ); |
| } |
| |
| return lResult; |
| } |
| |
| //*************************************************************************** |
| |
| static LPTSTR *GetCommandArgs( int *pArgc ) |
| { |
| #ifdef UNICODE |
| return CommandLineToArgvW( GetCommandLineW(), pArgc ); |
| #else |
| *pArgc = __argc; |
| return __argv; |
| #endif |
| } |
| |
| //*************************************************************************** |
| |
| static bool IsSupportedPlatform() |
| { |
| OSVERSIONINFO aOsVersion; |
| |
| ZeroMemory( &aOsVersion, sizeof( OSVERSIONINFO )); |
| aOsVersion.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); |
| |
| // Try to determine OS version |
| if ( GetVersionEx( &aOsVersion )) |
| { |
| switch ( aOsVersion.dwPlatformId ) |
| { |
| case VER_PLATFORM_WIN32_NT: // Windows NT based |
| return true; |
| |
| case VER_PLATFORM_WIN32_WINDOWS: // Windows Me/98/95. |
| case VER_PLATFORM_WIN32s: // Win32s |
| return false; |
| |
| default: |
| return false; |
| } |
| } |
| |
| return false; |
| } |
| |
| //*************************************************************************** |
| |
| static LPCTSTR GetOperatingSystemString() |
| { |
| OSVERSIONINFO aOsVersion; |
| |
| ZeroMemory( &aOsVersion, sizeof( OSVERSIONINFO )); |
| aOsVersion.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); |
| |
| _tcscpy( g_szOperatingSystem, TEXT( "Microsoft Windows" )); |
| |
| // Try to determine OS version |
| if ( GetVersionEx( &aOsVersion )) |
| { |
| switch ( aOsVersion.dwPlatformId ) |
| { |
| // Test for the Windows NT product family. |
| case VER_PLATFORM_WIN32_NT: |
| { |
| if ( aOsVersion.dwMajorVersion == 3 ) |
| { |
| _tcscat( g_szOperatingSystem, TEXT( " NT 3." )); |
| if ( aOsVersion.dwMinorVersion == 0 ) |
| _tcscat( g_szOperatingSystem, TEXT( "0" )); |
| else if ( aOsVersion.dwMinorVersion == 5 ) |
| _tcscat( g_szOperatingSystem, TEXT( "5" )); |
| else if ( aOsVersion.dwMinorVersion == 51 ) |
| _tcscat( g_szOperatingSystem, TEXT( "51" )); |
| } |
| else if ( aOsVersion.dwMajorVersion == 4 ) |
| _tcscat( g_szOperatingSystem, TEXT( " NT 4.0" )); |
| else if ( aOsVersion.dwMajorVersion == 5 ) |
| { |
| if ( aOsVersion.dwMinorVersion == 0 ) |
| _tcscat( g_szOperatingSystem, TEXT( " 2000" )); |
| else if ( aOsVersion.dwMinorVersion == 1 ) |
| _tcscat( g_szOperatingSystem, TEXT( " XP" )); |
| else if ( aOsVersion.dwMinorVersion == 2 ) |
| _tcscat( g_szOperatingSystem, TEXT( " Server 2003" )); |
| } |
| else if ( aOsVersion.dwMajorVersion == 6 ) |
| { |
| if ( aOsVersion.dwMinorVersion == 0 ) |
| _tcscat( g_szOperatingSystem, " Vista" ); |
| } |
| } |
| break; |
| |
| // Test for the Windows Me/98/95. |
| case VER_PLATFORM_WIN32_WINDOWS: |
| { |
| if ( aOsVersion.dwMinorVersion == 0 ) |
| _tcscat( g_szOperatingSystem, TEXT( " 95" )); |
| else if ( aOsVersion.dwMinorVersion == 10 ) |
| _tcscat( g_szOperatingSystem, TEXT( " 98" )); |
| else if ( aOsVersion.dwMinorVersion == 90 ) |
| _tcscat( g_szOperatingSystem, TEXT( " Me" )); |
| } |
| break; |
| } |
| } |
| |
| return g_szOperatingSystem; |
| } |
| |
| //*************************************************************************** |
| |
| static bool FileExists( LPCTSTR lpPathToFile ) |
| { |
| bool bResult = false; |
| HANDLE hFind; |
| WIN32_FIND_DATA FindFileData; |
| |
| hFind = FindFirstFile( lpPathToFile, &FindFileData ); |
| |
| if ( hFind != INVALID_HANDLE_VALUE ) |
| { |
| FindClose( hFind ); |
| bResult = true; |
| } |
| |
| return bResult; |
| } |
| |
| //*************************************************************************** |
| |
| static bool GetProgramFilesFolder( LPTSTR strPath ) |
| { |
| bool bRet = false; |
| HINSTANCE hLibrary; |
| |
| if (( hLibrary = LoadLibrary( "shell32.dll" )) != NULL ) |
| { |
| BOOL (WINAPI *pSHGetSpecialFolderPathA)( HWND, LPSTR, int, BOOL ); |
| |
| pSHGetSpecialFolderPathA = (BOOL (WINAPI *)(HWND, LPSTR, int, BOOL))GetProcAddress( hLibrary, "SHGetSpecialFolderPathA" ); |
| |
| if ( pSHGetSpecialFolderPathA ) |
| { |
| if ( pSHGetSpecialFolderPathA( NULL, strPath, CSIDL_PROGRAM_FILES, TRUE )) |
| bRet = true; |
| } |
| } |
| |
| FreeLibrary( hLibrary ); |
| |
| return ( bRet ); |
| } |
| |
| //*************************************************************************** |
| |
| static PathResult RetrieveExecutablePath( LPTSTR szExecutablePath ) |
| { |
| PathResult eRet = PATHRESULT_API_NOT_SUPPORTED; |
| TCHAR szProgramFilesFolder[MAX_PATH]; |
| |
| if ( GetProgramFilesFolder( szProgramFilesFolder )) |
| { |
| size_t nLen = _tcslen( szProgramFilesFolder ); |
| if ( nLen > 0 ) |
| { |
| _tcscpy( szExecutablePath, szProgramFilesFolder ); |
| if ( szProgramFilesFolder[nLen-1] != '\\' ) |
| _tcscat( szExecutablePath, TEXT( "\\" )); |
| _tcscat( szExecutablePath, TEXT( "Sun\\servicetag\\" )); |
| _tcscat( szExecutablePath, g_szSTExecutable ); |
| eRet = FileExists( szExecutablePath ) ? PATHRESULT_OK : PATHRESULT_EXE_NOT_FOUND; |
| } |
| } |
| |
| return eRet; |
| } |
| |
| //*************************************************************************** |
| |
| static void SafeCopy( LPTSTR lpTarget, LPCSTR lpSource, size_t nMaxLen ) |
| { |
| size_t nLen = _tcslen( lpSource ); |
| size_t nCopy = ( nLen < size_t( nMaxLen-1 )) ? nLen : nMaxLen-1; |
| _tcsncpy( lpTarget, lpSource, nMaxLen-1 ); |
| *(lpTarget+nCopy) = 0; |
| } |
| |
| //*************************************************************************** |
| |
| int WINAPI _tWinMain( HINSTANCE /*hInstance*/, HINSTANCE, LPTSTR, int ) |
| { |
| const DWORD ERR_NO_RECORDS_FOUND = 225; |
| const DWORD ERR_DUP_RECORD = 226; |
| |
| DWORD dwExitCode = (DWORD)1; |
| |
| int nArgs = 0; |
| LPTSTR* lpArgs = GetCommandArgs( &nArgs ); |
| |
| if ( !IsSupportedPlatform() ) |
| { |
| // Return 0 for a successful run on not supported platforms |
| // We don't want that the Office tries to start us forever. |
| return 0; |
| } |
| |
| if ( nArgs >= 11 ) |
| { |
| TCHAR szTargetURN[1024] = {0}; |
| TCHAR szProductName[1024] = {0}; |
| TCHAR szProductVersion[1024] = {0}; |
| TCHAR szParentProductName[1024] = {0}; |
| TCHAR szProductSource[1024] = {0}; |
| TCHAR szInstanceURN[1024] = {0}; |
| |
| // -i) INSTANCE_URN="$2"; shift;; |
| // -t) TARGET_URN="$2"; shift;; |
| // -p) PRODUCT_NAME="$2"; shift;; |
| // -e) PRODUCT_VERSION="$2"; shift;; |
| // -P) PARENT_PRODUCT_NAME="$2"; shift;; |
| // -S) PRODUCT_SOURCE="$2"; shift;; |
| // "usage: $0 [-i <instance urn>] -p <product name> -e <product version> -t <urn> -S <source> -P <parent product name>" |
| |
| int i = 1; |
| while ( i < nArgs ) |
| { |
| LPTSTR lpArg = lpArgs[i]; |
| if ( _tcslen( lpArg ) >= 2 ) |
| { |
| if ( lpArg[0] == '-' ) |
| { |
| switch ( lpArg[1] ) |
| { |
| case 'i': |
| { |
| if ( i < nArgs ) |
| ++i; |
| SafeCopy( szInstanceURN, lpArgs[i], elementsof( szInstanceURN )); |
| break; |
| } |
| |
| case 't': |
| { |
| if ( i < nArgs ) |
| ++i; |
| SafeCopy( szTargetURN, lpArgs[i], elementsof( szTargetURN )); |
| break; |
| } |
| case 'p': |
| { |
| if ( i < nArgs ) |
| ++i; |
| SafeCopy( szProductName, lpArgs[i], elementsof( szProductName )); |
| break; |
| } |
| case 'e': |
| { |
| if ( i < nArgs ) |
| ++i; |
| SafeCopy( szProductVersion, lpArgs[i], elementsof( szProductVersion )); |
| break; |
| } |
| case 'P': |
| { |
| if ( i < nArgs ) |
| ++i; |
| SafeCopy( szParentProductName, lpArgs[i], elementsof( szParentProductName )); |
| break; |
| } |
| case 'S': |
| { |
| if ( i < nArgs ) |
| ++i; |
| SafeCopy( szProductSource, lpArgs[i], elementsof( szProductSource )); |
| break; |
| } |
| |
| default: |
| break; |
| } // switch |
| } |
| } |
| |
| ++i; |
| } |
| |
| if ( RetrieveExecutablePath( g_szSTInstallationPath ) == PATHRESULT_OK ) |
| { |
| BOOL bSuccess = TRUE; |
| BOOL bProcessStarted = FALSE; |
| |
| STARTUPINFO aStartupInfo; |
| PROCESS_INFORMATION aProcessInfo; |
| LPTSTR lpCommandLine = 0; |
| |
| ZeroMemory( &aStartupInfo, sizeof( aStartupInfo )); |
| aStartupInfo.cb = sizeof( aStartupInfo ); |
| ZeroMemory( &aProcessInfo, sizeof( aProcessInfo )); |
| |
| if ( _tcslen( szInstanceURN ) == 0 ) |
| { |
| // TEST=`${STCLIENT} -f -t ${TARGET_URN}` |
| lpCommandLine = new TCHAR[MAXCMDLINELEN]; |
| |
| _tcscpy( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, g_szSTInstallationPath ); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, TEXT( " -f" )); |
| _tcscat( lpCommandLine, TEXT( " -t ")); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, szTargetURN ); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| |
| bSuccess = CreateProcess( |
| NULL, |
| lpCommandLine, |
| NULL, |
| NULL, |
| TRUE, |
| CREATE_NO_WINDOW, |
| NULL, |
| NULL, |
| &aStartupInfo, |
| &aProcessInfo ); |
| |
| bProcessStarted = TRUE; |
| |
| // wait until process ends to receive exit code |
| WaitForSingleObject( aProcessInfo.hProcess, INFINITE ); |
| |
| delete []lpCommandLine; |
| } |
| |
| if ( bSuccess ) |
| { |
| DWORD dwSTClientExitCode( ERR_NO_RECORDS_FOUND ); |
| if ( bProcessStarted ) |
| { |
| GetExitCodeProcess( aProcessInfo.hProcess, &dwSTClientExitCode ); |
| dwSTClientExitCode &= 0x000000ff; |
| |
| CloseHandle( aProcessInfo.hProcess ); |
| CloseHandle( aProcessInfo.hThread ); |
| } |
| |
| if ( dwSTClientExitCode == ERR_NO_RECORDS_FOUND ) |
| { |
| // output=`${STCLIENT} -a [-i "${INSTANCE_URN}"] -p "${PRODUCT_NAME}" -e "${PRODUCT_VERSION}" -t "${TARGET_URN}" -S "${PRODUCT_SOURCE}" -P "${PARENT_PRODUCT_NAME}" -m "Sun Microsystems, Inc." -A ${uname} -z global` |
| lpCommandLine = new TCHAR[MAXCMDLINELEN]; |
| |
| _tcscpy( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, g_szSTInstallationPath ); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, TEXT( " -a" )); |
| if ( _tcslen( szInstanceURN ) > 0 ) |
| { |
| _tcscat( lpCommandLine, TEXT( " -i " )); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, szInstanceURN ); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| } |
| _tcscat( lpCommandLine, TEXT( " -p " )); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, szProductName ); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, TEXT( " -e " )); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, szProductVersion ); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, TEXT( " -t " )); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, szTargetURN ); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, TEXT( " -S " )); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, szProductSource ); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, TEXT( " -P " )); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, szParentProductName ); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, TEXT( " -m \"Sun Microsystems, Inc.\"" )); |
| _tcscat( lpCommandLine, TEXT( " -A " )); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, GetOperatingSystemString() ); |
| _tcscat( lpCommandLine, TEXT( "\"" )); |
| _tcscat( lpCommandLine, TEXT( " -z global" )); |
| |
| ZeroMemory( &aStartupInfo, sizeof( aStartupInfo )); |
| aStartupInfo.cb = sizeof(aStartupInfo); |
| ZeroMemory( &aProcessInfo, sizeof( aProcessInfo )); |
| |
| bSuccess = CreateProcess( |
| NULL, |
| lpCommandLine, |
| NULL, |
| NULL, |
| TRUE, |
| CREATE_NO_WINDOW, |
| NULL, |
| NULL, |
| &aStartupInfo, |
| &aProcessInfo ); |
| |
| delete []lpCommandLine; |
| |
| // wait until process ends to receive exit code |
| WaitForSingleObject( aProcessInfo.hProcess, INFINITE ); |
| |
| dwSTClientExitCode = 0; |
| GetExitCodeProcess( aProcessInfo.hProcess, &dwSTClientExitCode ); |
| dwSTClientExitCode &= 0x000000ff; |
| |
| CloseHandle( aProcessInfo.hProcess ); |
| CloseHandle( aProcessInfo.hThread ); |
| |
| if ( !bSuccess ) |
| dwExitCode = 1; // couldn't start stclient process |
| else |
| { |
| if ( _tcslen( szInstanceURN ) > 0 ) |
| { |
| // don't register again if we registered in a previous run |
| // or we called stclient successfully. |
| if (( dwSTClientExitCode == ERR_DUP_RECORD ) || |
| ( dwSTClientExitCode == 0 )) |
| dwExitCode = 0; |
| else |
| dwExitCode = 1; // other errors |
| } |
| else |
| dwExitCode = ( dwSTClientExitCode == 0 ) ? 0 : 1; |
| } |
| } |
| else if ( dwSTClientExitCode == 0 ) |
| dwExitCode = 0; // already registered |
| else |
| dwExitCode = 1; // other errors |
| } |
| else |
| dwExitCode = 1; // couldn't start stclient |
| } |
| else |
| dwExitCode = 1; // no executable found |
| } |
| else |
| dwExitCode = 0; // wrong number of arguments |
| |
| return dwExitCode; |
| } |