1 #define WIN32_LEAN_AND_MEAN
4 #pragma warning(disable:4668 4917) // disable warnings for system headers
15 #define elementsof(buf) (sizeof(buf) / sizeof(buf[0]))
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
)
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
);
49 //***************************************************************************
51 static LPTSTR
*GetCommandArgs( int *pArgc
)
54 return CommandLineToArgvW( GetCommandLineW(), pArgc
);
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
78 case VER_PLATFORM_WIN32_WINDOWS
: // Windows Me/98/95.
79 case VER_PLATFORM_WIN32s
: // Win32s
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" );
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" ));
152 return g_szOperatingSystem
;
155 //***************************************************************************
157 static bool FileExists( LPCTSTR lpPathToFile
)
159 bool bResult
= false;
161 WIN32_FIND_DATA FindFileData
;
163 hFind
= FindFirstFile( lpPathToFile
, &FindFileData
);
165 if ( hFind
!= INVALID_HANDLE_VALUE
)
174 //***************************************************************************
176 static bool GetProgramFilesFolder( LPTSTR strPath
)
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
))
194 FreeLibrary( hLibrary
);
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
);
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
;
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;
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.
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>"
272 LPTSTR lpArg
= lpArgs
[i
];
273 if ( _tcslen( lpArg
) >= 2 )
275 if ( lpArg
[0] == '-' )
283 SafeCopy( szInstanceURN
, lpArgs
[i
], elementsof( szInstanceURN
));
291 SafeCopy( szTargetURN
, lpArgs
[i
], elementsof( szTargetURN
));
298 SafeCopy( szProductName
, lpArgs
[i
], elementsof( szProductName
));
305 SafeCopy( szProductVersion
, lpArgs
[i
], elementsof( szProductVersion
));
312 SafeCopy( szParentProductName
, lpArgs
[i
], elementsof( szParentProductName
));
319 SafeCopy( szProductSource
, lpArgs
[i
], elementsof( szProductSource
));
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(
371 bProcessStarted
= TRUE
;
373 // wait until process ends to receive exit code
374 WaitForSingleObject( aProcessInfo
.hProcess
, INFINITE
);
376 delete []lpCommandLine
;
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(
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
);
463 dwExitCode
= 1; // couldn't start stclient process
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 ))
474 dwExitCode
= 1; // other errors
477 dwExitCode
= ( dwSTClientExitCode
== 0 ) ? 0 : 1;
480 else if ( dwSTClientExitCode
== 0 )
481 dwExitCode
= 0; // already registered
483 dwExitCode
= 1; // other errors
486 dwExitCode
= 1; // couldn't start stclient
489 dwExitCode
= 1; // no executable found
492 dwExitCode
= 0; // wrong number of arguments