/************************************************************** * * 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 #include #include #include #include #include #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 ] -p -e -t -S -P " 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; }