merge the formfield patch from ooo-build
[ooovba.git] / setup_native / source / win32 / stwrapper / stwrapper.cxx
blob85992b9cf16af17930ff06a8562f9cc4c747ccf0
1 #define WIN32_LEAN_AND_MEAN
3 #ifdef _MSC_VER
4 #pragma warning(disable:4668 4917) // disable warnings for system headers
5 #endif
7 #include <windows.h>
8 #include <windowsx.h>
9 #include <shellapi.h>
10 #include <shlobj.h>
11 #include <tchar.h>
13 #include <stdio.h>
15 #define elementsof(buf) (sizeof(buf) / sizeof(buf[0]))
17 enum PathResult
19 PATHRESULT_OK,
20 PATHRESULT_API_NOT_SUPPORTED,
21 PATHRESULT_EXE_NOT_FOUND
24 const int MAXCMDLINELEN = 32768;
26 static TCHAR g_szSTInstallationPath[MAX_PATH] = TEXT("");
27 static TCHAR g_szOperatingSystem[256] = TEXT("");
29 static const TCHAR g_szSTExecutable[256] = TEXT("stclient.exe");
31 //***************************************************************************
33 LONG RegReadValue( HKEY hBaseKey, LPCTSTR lpSubKey, LPCTSTR lpValueName, LPVOID lpData, DWORD cbData )
35 HKEY hKey = NULL;
36 LONG lResult( 0 );
38 lResult = RegOpenKeyEx( hBaseKey, lpSubKey, 0, KEY_QUERY_VALUE, &hKey );
40 if ( ERROR_SUCCESS == lResult )
42 lResult = RegQueryValueEx( hKey, lpValueName, NULL, NULL, (LPBYTE)lpData, &cbData );
43 RegCloseKey( hKey );
46 return lResult;
49 //***************************************************************************
51 static LPTSTR *GetCommandArgs( int *pArgc )
53 #ifdef UNICODE
54 return CommandLineToArgvW( GetCommandLineW(), pArgc );
55 #else
56 *pArgc = __argc;
57 return __argv;
58 #endif
61 //***************************************************************************
63 static bool IsSupportedPlatform()
65 OSVERSIONINFO aOsVersion;
67 ZeroMemory( &aOsVersion, sizeof( OSVERSIONINFO ));
68 aOsVersion.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
70 // Try to determine OS version
71 if ( GetVersionEx( &aOsVersion ))
73 switch ( aOsVersion.dwPlatformId )
75 case VER_PLATFORM_WIN32_NT: // Windows NT based
76 return true;
78 case VER_PLATFORM_WIN32_WINDOWS: // Windows Me/98/95.
79 case VER_PLATFORM_WIN32s: // Win32s
80 return false;
82 default:
83 return false;
87 return false;
90 //***************************************************************************
92 static LPCTSTR GetOperatingSystemString()
94 OSVERSIONINFO aOsVersion;
96 ZeroMemory( &aOsVersion, sizeof( OSVERSIONINFO ));
97 aOsVersion.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
99 _tcscpy( g_szOperatingSystem, TEXT( "Microsoft Windows" ));
101 // Try to determine OS version
102 if ( GetVersionEx( &aOsVersion ))
104 switch ( aOsVersion.dwPlatformId )
106 // Test for the Windows NT product family.
107 case VER_PLATFORM_WIN32_NT:
109 if ( aOsVersion.dwMajorVersion == 3 )
111 _tcscat( g_szOperatingSystem, TEXT( " NT 3." ));
112 if ( aOsVersion.dwMinorVersion == 0 )
113 _tcscat( g_szOperatingSystem, TEXT( "0" ));
114 else if ( aOsVersion.dwMinorVersion == 5 )
115 _tcscat( g_szOperatingSystem, TEXT( "5" ));
116 else if ( aOsVersion.dwMinorVersion == 51 )
117 _tcscat( g_szOperatingSystem, TEXT( "51" ));
119 else if ( aOsVersion.dwMajorVersion == 4 )
120 _tcscat( g_szOperatingSystem, TEXT( " NT 4.0" ));
121 else if ( aOsVersion.dwMajorVersion == 5 )
123 if ( aOsVersion.dwMinorVersion == 0 )
124 _tcscat( g_szOperatingSystem, TEXT( " 2000" ));
125 else if ( aOsVersion.dwMinorVersion == 1 )
126 _tcscat( g_szOperatingSystem, TEXT( " XP" ));
127 else if ( aOsVersion.dwMinorVersion == 2 )
128 _tcscat( g_szOperatingSystem, TEXT( " Server 2003" ));
130 else if ( aOsVersion.dwMajorVersion == 6 )
132 if ( aOsVersion.dwMinorVersion == 0 )
133 _tcscat( g_szOperatingSystem, " Vista" );
136 break;
138 // Test for the Windows Me/98/95.
139 case VER_PLATFORM_WIN32_WINDOWS:
141 if ( aOsVersion.dwMinorVersion == 0 )
142 _tcscat( g_szOperatingSystem, TEXT( " 95" ));
143 else if ( aOsVersion.dwMinorVersion == 10 )
144 _tcscat( g_szOperatingSystem, TEXT( " 98" ));
145 else if ( aOsVersion.dwMinorVersion == 90 )
146 _tcscat( g_szOperatingSystem, TEXT( " Me" ));
148 break;
152 return g_szOperatingSystem;
155 //***************************************************************************
157 static bool FileExists( LPCTSTR lpPathToFile )
159 bool bResult = false;
160 HANDLE hFind;
161 WIN32_FIND_DATA FindFileData;
163 hFind = FindFirstFile( lpPathToFile, &FindFileData );
165 if ( hFind != INVALID_HANDLE_VALUE )
167 FindClose( hFind );
168 bResult = true;
171 return bResult;
174 //***************************************************************************
176 static bool GetProgramFilesFolder( LPTSTR strPath )
178 bool bRet = false;
179 HINSTANCE hLibrary;
181 if (( hLibrary = LoadLibrary( "shell32.dll" )) != NULL )
183 BOOL (WINAPI *pSHGetSpecialFolderPathA)( HWND, LPSTR, int, BOOL );
185 pSHGetSpecialFolderPathA = (BOOL (WINAPI *)(HWND, LPSTR, int, BOOL))GetProcAddress( hLibrary, "SHGetSpecialFolderPathA" );
187 if ( pSHGetSpecialFolderPathA )
189 if ( pSHGetSpecialFolderPathA( NULL, strPath, CSIDL_PROGRAM_FILES, TRUE ))
190 bRet = true;
194 FreeLibrary( hLibrary );
196 return ( bRet );
199 //***************************************************************************
201 static PathResult RetrieveExecutablePath( LPTSTR szExecutablePath )
203 PathResult eRet = PATHRESULT_API_NOT_SUPPORTED;
204 TCHAR szProgramFilesFolder[MAX_PATH];
206 if ( GetProgramFilesFolder( szProgramFilesFolder ))
208 size_t nLen = _tcslen( szProgramFilesFolder );
209 if ( nLen > 0 )
211 _tcscpy( szExecutablePath, szProgramFilesFolder );
212 if ( szProgramFilesFolder[nLen-1] != '\\' )
213 _tcscat( szExecutablePath, TEXT( "\\" ));
214 _tcscat( szExecutablePath, TEXT( "Sun\\servicetag\\" ));
215 _tcscat( szExecutablePath, g_szSTExecutable );
216 eRet = FileExists( szExecutablePath ) ? PATHRESULT_OK : PATHRESULT_EXE_NOT_FOUND;
220 return eRet;
223 //***************************************************************************
225 static void SafeCopy( LPTSTR lpTarget, LPCSTR lpSource, size_t nMaxLen )
227 size_t nLen = _tcslen( lpSource );
228 size_t nCopy = ( nLen < size_t( nMaxLen-1 )) ? nLen : nMaxLen-1;
229 _tcsncpy( lpTarget, lpSource, nMaxLen-1 );
230 *(lpTarget+nCopy) = 0;
233 //***************************************************************************
235 int WINAPI _tWinMain( HINSTANCE /*hInstance*/, HINSTANCE, LPTSTR, int )
237 const DWORD ERR_NO_RECORDS_FOUND = 225;
238 const DWORD ERR_DUP_RECORD = 226;
240 DWORD dwExitCode = (DWORD)1;
242 int nArgs = 0;
243 LPTSTR* lpArgs = GetCommandArgs( &nArgs );
245 if ( !IsSupportedPlatform() )
247 // Return 0 for a successful run on not supported platforms
248 // We don't want that the Office tries to start us forever.
249 return 0;
252 if ( nArgs >= 11 )
254 TCHAR szTargetURN[1024] = {0};
255 TCHAR szProductName[1024] = {0};
256 TCHAR szProductVersion[1024] = {0};
257 TCHAR szParentProductName[1024] = {0};
258 TCHAR szProductSource[1024] = {0};
259 TCHAR szInstanceURN[1024] = {0};
261 // -i) INSTANCE_URN="$2"; shift;;
262 // -t) TARGET_URN="$2"; shift;;
263 // -p) PRODUCT_NAME="$2"; shift;;
264 // -e) PRODUCT_VERSION="$2"; shift;;
265 // -P) PARENT_PRODUCT_NAME="$2"; shift;;
266 // -S) PRODUCT_SOURCE="$2"; shift;;
267 // "usage: $0 [-i <instance urn>] -p <product name> -e <product version> -t <urn> -S <source> -P <parent product name>"
269 int i = 1;
270 while ( i < nArgs )
272 LPTSTR lpArg = lpArgs[i];
273 if ( _tcslen( lpArg ) >= 2 )
275 if ( lpArg[0] == '-' )
277 switch ( lpArg[1] )
279 case 'i':
281 if ( i < nArgs )
282 ++i;
283 SafeCopy( szInstanceURN, lpArgs[i], elementsof( szInstanceURN ));
284 break;
287 case 't':
289 if ( i < nArgs )
290 ++i;
291 SafeCopy( szTargetURN, lpArgs[i], elementsof( szTargetURN ));
292 break;
294 case 'p':
296 if ( i < nArgs )
297 ++i;
298 SafeCopy( szProductName, lpArgs[i], elementsof( szProductName ));
299 break;
301 case 'e':
303 if ( i < nArgs )
304 ++i;
305 SafeCopy( szProductVersion, lpArgs[i], elementsof( szProductVersion ));
306 break;
308 case 'P':
310 if ( i < nArgs )
311 ++i;
312 SafeCopy( szParentProductName, lpArgs[i], elementsof( szParentProductName ));
313 break;
315 case 'S':
317 if ( i < nArgs )
318 ++i;
319 SafeCopy( szProductSource, lpArgs[i], elementsof( szProductSource ));
320 break;
323 default:
324 break;
325 } // switch
329 ++i;
332 if ( RetrieveExecutablePath( g_szSTInstallationPath ) == PATHRESULT_OK )
334 BOOL bSuccess = TRUE;
335 BOOL bProcessStarted = FALSE;
337 STARTUPINFO aStartupInfo;
338 PROCESS_INFORMATION aProcessInfo;
339 LPTSTR lpCommandLine = 0;
341 ZeroMemory( &aStartupInfo, sizeof( aStartupInfo ));
342 aStartupInfo.cb = sizeof( aStartupInfo );
343 ZeroMemory( &aProcessInfo, sizeof( aProcessInfo ));
345 if ( _tcslen( szInstanceURN ) == 0 )
347 // TEST=`${STCLIENT} -f -t ${TARGET_URN}`
348 lpCommandLine = new TCHAR[MAXCMDLINELEN];
350 _tcscpy( lpCommandLine, TEXT( "\"" ));
351 _tcscat( lpCommandLine, g_szSTInstallationPath );
352 _tcscat( lpCommandLine, TEXT( "\"" ));
353 _tcscat( lpCommandLine, TEXT( " -f" ));
354 _tcscat( lpCommandLine, TEXT( " -t "));
355 _tcscat( lpCommandLine, TEXT( "\"" ));
356 _tcscat( lpCommandLine, szTargetURN );
357 _tcscat( lpCommandLine, TEXT( "\"" ));
359 bSuccess = CreateProcess(
360 NULL,
361 lpCommandLine,
362 NULL,
363 NULL,
364 TRUE,
365 CREATE_NO_WINDOW,
366 NULL,
367 NULL,
368 &aStartupInfo,
369 &aProcessInfo );
371 bProcessStarted = TRUE;
373 // wait until process ends to receive exit code
374 WaitForSingleObject( aProcessInfo.hProcess, INFINITE );
376 delete []lpCommandLine;
379 if ( bSuccess )
381 DWORD dwSTClientExitCode( ERR_NO_RECORDS_FOUND );
382 if ( bProcessStarted )
384 GetExitCodeProcess( aProcessInfo.hProcess, &dwSTClientExitCode );
385 dwSTClientExitCode &= 0x000000ff;
387 CloseHandle( aProcessInfo.hProcess );
388 CloseHandle( aProcessInfo.hThread );
391 if ( dwSTClientExitCode == ERR_NO_RECORDS_FOUND )
393 // 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`
394 lpCommandLine = new TCHAR[MAXCMDLINELEN];
396 _tcscpy( lpCommandLine, TEXT( "\"" ));
397 _tcscat( lpCommandLine, g_szSTInstallationPath );
398 _tcscat( lpCommandLine, TEXT( "\"" ));
399 _tcscat( lpCommandLine, TEXT( " -a" ));
400 if ( _tcslen( szInstanceURN ) > 0 )
402 _tcscat( lpCommandLine, TEXT( " -i " ));
403 _tcscat( lpCommandLine, TEXT( "\"" ));
404 _tcscat( lpCommandLine, szInstanceURN );
405 _tcscat( lpCommandLine, TEXT( "\"" ));
407 _tcscat( lpCommandLine, TEXT( " -p " ));
408 _tcscat( lpCommandLine, TEXT( "\"" ));
409 _tcscat( lpCommandLine, szProductName );
410 _tcscat( lpCommandLine, TEXT( "\"" ));
411 _tcscat( lpCommandLine, TEXT( " -e " ));
412 _tcscat( lpCommandLine, TEXT( "\"" ));
413 _tcscat( lpCommandLine, szProductVersion );
414 _tcscat( lpCommandLine, TEXT( "\"" ));
415 _tcscat( lpCommandLine, TEXT( " -t " ));
416 _tcscat( lpCommandLine, TEXT( "\"" ));
417 _tcscat( lpCommandLine, szTargetURN );
418 _tcscat( lpCommandLine, TEXT( "\"" ));
419 _tcscat( lpCommandLine, TEXT( " -S " ));
420 _tcscat( lpCommandLine, TEXT( "\"" ));
421 _tcscat( lpCommandLine, szProductSource );
422 _tcscat( lpCommandLine, TEXT( "\"" ));
423 _tcscat( lpCommandLine, TEXT( " -P " ));
424 _tcscat( lpCommandLine, TEXT( "\"" ));
425 _tcscat( lpCommandLine, szParentProductName );
426 _tcscat( lpCommandLine, TEXT( "\"" ));
427 _tcscat( lpCommandLine, TEXT( " -m \"Sun Microsystems, Inc.\"" ));
428 _tcscat( lpCommandLine, TEXT( " -A " ));
429 _tcscat( lpCommandLine, TEXT( "\"" ));
430 _tcscat( lpCommandLine, GetOperatingSystemString() );
431 _tcscat( lpCommandLine, TEXT( "\"" ));
432 _tcscat( lpCommandLine, TEXT( " -z global" ));
434 ZeroMemory( &aStartupInfo, sizeof( aStartupInfo ));
435 aStartupInfo.cb = sizeof(aStartupInfo);
436 ZeroMemory( &aProcessInfo, sizeof( aProcessInfo ));
438 bSuccess = CreateProcess(
439 NULL,
440 lpCommandLine,
441 NULL,
442 NULL,
443 TRUE,
444 CREATE_NO_WINDOW,
445 NULL,
446 NULL,
447 &aStartupInfo,
448 &aProcessInfo );
450 delete []lpCommandLine;
452 // wait until process ends to receive exit code
453 WaitForSingleObject( aProcessInfo.hProcess, INFINITE );
455 dwSTClientExitCode = 0;
456 GetExitCodeProcess( aProcessInfo.hProcess, &dwSTClientExitCode );
457 dwSTClientExitCode &= 0x000000ff;
459 CloseHandle( aProcessInfo.hProcess );
460 CloseHandle( aProcessInfo.hThread );
462 if ( !bSuccess )
463 dwExitCode = 1; // couldn't start stclient process
464 else
466 if ( _tcslen( szInstanceURN ) > 0 )
468 // don't register again if we registered in a previous run
469 // or we called stclient successfully.
470 if (( dwSTClientExitCode == ERR_DUP_RECORD ) ||
471 ( dwSTClientExitCode == 0 ))
472 dwExitCode = 0;
473 else
474 dwExitCode = 1; // other errors
476 else
477 dwExitCode = ( dwSTClientExitCode == 0 ) ? 0 : 1;
480 else if ( dwSTClientExitCode == 0 )
481 dwExitCode = 0; // already registered
482 else
483 dwExitCode = 1; // other errors
485 else
486 dwExitCode = 1; // couldn't start stclient
488 else
489 dwExitCode = 1; // no executable found
491 else
492 dwExitCode = 0; // wrong number of arguments
494 return dwExitCode;