1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: checkrunningofficelanguagepack.cxx,v $
10 * $Revision: 1.1.4.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #define _WIN32_WINDOWS 0x0410
34 #pragma warning(push, 1) /* disable warnings within system headers */
36 #define WIN32_LEAN_AND_MEAN
48 #define _tstring wstring
50 #define _tstring string
57 #include <systools/win32/uwinapi.h>
58 #include <../tools/seterror.hxx>
60 #define WININIT_FILENAME "wininit.ini"
61 #define RENAME_SECTION "rename"
64 inline void OutputDebugStringFormat( LPCTSTR pFormat
, ... )
69 va_start( args
, pFormat
);
70 _vsntprintf( buffer
, elementsof(buffer
), pFormat
, args
);
71 OutputDebugString( buffer
);
74 static inline void OutputDebugStringFormat( LPCTSTR
, ... )
79 static std::_tstring
GetMsiProperty( MSIHANDLE handle
, const std::_tstring
& sProperty
)
82 TCHAR szDummy
[1] = TEXT("");
85 if ( MsiGetProperty( handle
, sProperty
.c_str(), szDummy
, &nChars
) == ERROR_MORE_DATA
)
87 DWORD nBytes
= ++nChars
* sizeof(TCHAR
);
88 LPTSTR buffer
= reinterpret_cast<LPTSTR
>(_alloca(nBytes
));
89 ZeroMemory( buffer
, nBytes
);
90 MsiGetProperty(handle
, sProperty
.c_str(), buffer
, &nChars
);
97 static inline bool IsSetMsiProperty(MSIHANDLE handle
, const std::_tstring
& sProperty
)
99 std::_tstring value
= GetMsiProperty(handle
, sProperty
);
100 return (value
.length() > 0);
103 static inline void UnsetMsiProperty(MSIHANDLE handle
, const std::_tstring
& sProperty
)
105 MsiSetProperty(handle
, sProperty
.c_str(), NULL
);
108 static inline void SetMsiProperty(MSIHANDLE handle
, const std::_tstring
& sProperty
)
110 MsiSetProperty(handle
, sProperty
.c_str(), TEXT("1"));
113 static BOOL
MoveFileEx9x( LPCSTR lpExistingFileNameA
, LPCSTR lpNewFileNameA
, DWORD dwFlags
)
115 BOOL fSuccess
= FALSE
; // assume failure
117 // Windows 9x has a special mechanism to move files after reboot
119 if ( dwFlags
& MOVEFILE_DELAY_UNTIL_REBOOT
)
121 CHAR szExistingFileNameA
[MAX_PATH
];
122 CHAR szNewFileNameA
[MAX_PATH
] = "NUL";
124 // Path names in WININIT.INI must be in short path name form
127 GetShortPathNameA( lpExistingFileNameA
, szExistingFileNameA
, MAX_PATH
) &&
128 (!lpNewFileNameA
|| GetShortPathNameA( lpNewFileNameA
, szNewFileNameA
, MAX_PATH
))
131 CHAR szBuffer
[32767]; // The buffer size must not exceed 32K
132 DWORD dwBufLen
= GetPrivateProfileSectionA( RENAME_SECTION
, szBuffer
, elementsof(szBuffer
), WININIT_FILENAME
);
134 CHAR szRename
[MAX_PATH
]; // This is enough for at most to times 67 chracters
135 strcpy( szRename
, szNewFileNameA
);
136 strcat( szRename
, "=" );
137 strcat( szRename
, szExistingFileNameA
);
138 size_t lnRename
= strlen(szRename
);
140 if ( dwBufLen
+ lnRename
+ 2 <= elementsof(szBuffer
) )
142 CopyMemory( &szBuffer
[dwBufLen
], szRename
, lnRename
);
143 szBuffer
[dwBufLen
+ lnRename
] = 0;
144 szBuffer
[dwBufLen
+ lnRename
+ 1 ] = 0;
146 fSuccess
= WritePrivateProfileSectionA( RENAME_SECTION
, szBuffer
, WININIT_FILENAME
);
149 SetLastError( ERROR_BUFFER_OVERFLOW
);
155 fSuccess
= MoveFileA( lpExistingFileNameA
, lpNewFileNameA
);
157 if ( !fSuccess
&& GetLastError() != ERROR_ACCESS_DENIED
&&
158 0 != (dwFlags
& (MOVEFILE_COPY_ALLOWED
| MOVEFILE_REPLACE_EXISTING
)) )
160 BOOL bFailIfExist
= 0 == (dwFlags
& MOVEFILE_REPLACE_EXISTING
);
162 fSuccess
= CopyFileA( lpExistingFileNameA
, lpNewFileNameA
, bFailIfExist
);
165 fSuccess
= DeleteFileA( lpExistingFileNameA
);
173 static BOOL
MoveFileExImpl( LPCSTR lpExistingFileNameA
, LPCSTR lpNewFileNameA
, DWORD dwFlags
)
175 if ( 0 > ((LONG
)GetVersion())) // High order bit indicates Win 9x
176 return MoveFileEx9x( lpExistingFileNameA
, lpNewFileNameA
, dwFlags
);
178 return MoveFileExA( lpExistingFileNameA
, lpNewFileNameA
, dwFlags
);
181 extern "C" UINT __stdcall
IsOfficeRunning( MSIHANDLE handle
)
183 std::_tstring sInstDir
= GetMsiProperty( handle
, TEXT("BASISINSTALLLOCATION") );
184 std::_tstring sResourceDir
= sInstDir
+ TEXT("program\\resource\\");
185 std::_tstring sPattern
= sResourceDir
+ TEXT("vcl*.res");
187 WIN32_FIND_DATA aFindFileData
;
188 HANDLE hFind
= FindFirstFile( sPattern
.c_str(), &aFindFileData
);
190 if ( IsValidHandle(hFind
) )
192 BOOL fSuccess
= false;
193 bool fRenameSucceeded
;
197 std::_tstring sResourceFile
= sResourceDir
+ aFindFileData
.cFileName
;
198 std::_tstring sIntermediate
= sResourceFile
+ TEXT(".tmp");
200 fRenameSucceeded
= MoveFileExImpl( sResourceFile
.c_str(), sIntermediate
.c_str(), MOVEFILE_REPLACE_EXISTING
);
201 if ( fRenameSucceeded
)
203 MoveFileExImpl( sIntermediate
.c_str(), sResourceFile
.c_str(), 0 );
204 fSuccess
= FindNextFile( hFind
, &aFindFileData
);
206 } while ( fSuccess
&& fRenameSucceeded
);
208 if ( !fRenameSucceeded
)
210 MsiSetProperty(handle
, TEXT("OFFICERUNS"), TEXT("1"));
211 SetMsiErrorCode( MSI_ERROR_OFFICE_IS_RUNNING
);
217 return ERROR_SUCCESS
;