1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 //Implementierung der Klasse RegistrationContextInformation.
23 
24 #include <assert.h>
25 #include "registrationcontextinformation.hxx"
26 #include "msihelper.hxx"
27 
28 #define WINDOWS_LEAN_AND_MEAN
29 #include <windows.h>
30 #include <assert.h>
31 #include <algorithm>
32 
33 namespace /* private */
34 {
35 	const int MAX_REGKEY_LENGTH_WIN9X = 16300;
36 }
37 
38 RegistrationContextInformation::RegistrationContextInformation(MSIHANDLE hMsi, const std::wstring& OpenOfficeExecutablePath) :
39 	msihandle_(hMsi),
40 	m_IsWin9x(true),
41 	m_OOExecPath(OpenOfficeExecutablePath)
42 {
43 	OSVERSIONINFOA osverinfo;
44     ZeroMemory(&osverinfo, sizeof(osverinfo));
45     osverinfo.dwOSVersionInfoSize = sizeof(osverinfo);
46     GetVersionExA(&osverinfo);
47 
48     m_IsWin9x = (osverinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
49 	assert(m_OOExecPath.length());
50 	ExtractOpenOfficeExecNameFromPath();
51 }
52 
53 std::wstring RegistrationContextInformation::GetWordDocumentDisplayName() const
54 {
55 	std::wstring str;
56     GetMsiProp(msihandle_, TEXT("STR_MS_WORD_DOCUMENT"), str);
57 	if (m_IsWin9x && !IsConvertableToAnsi(str))
58 		str = TEXT("Microsoft Word Document");
59 	return str;
60 }
61 
62 std::wstring RegistrationContextInformation::GetWordDocumentFileExtension() const
63 {
64 	return std::wstring(TEXT(".doc"));
65 }
66 
67 std::wstring RegistrationContextInformation::GetWordDocumentDefaultIconEntry() const
68 {
69 	return m_OOExecPath + std::wstring(TEXT(",1"));
70 }
71 
72 std::wstring RegistrationContextInformation::GetWordDocumentDefaultShellCommand() const
73 {
74 	return std::wstring(TEXT("open"));
75 }
76 
77 std::wstring RegistrationContextInformation::GetWordTemplateDisplayName() const
78 {
79 	std::wstring str;
80     GetMsiProp(msihandle_, TEXT("STR_MS_WORD_TEMPLATE"), str);
81 	if (m_IsWin9x && !IsConvertableToAnsi(str))
82 		str = TEXT("Microsoft Word Template");
83 	return str;
84 }
85 
86 std::wstring RegistrationContextInformation::GetWordTemplateFileExtension() const
87 {
88 	return std::wstring(TEXT(".dot"));
89 }
90 
91 std::wstring RegistrationContextInformation::GetWordTemplateDefaultIconEntry() const
92 {
93 	return m_OOExecPath + std::wstring(TEXT(",2"));
94 }
95 
96 std::wstring RegistrationContextInformation::GetWordTemplateDefaultShellCommand() const
97 {
98 	return std::wstring(TEXT("new"));
99 }
100 
101 std::wstring RegistrationContextInformation::GetRtfDocumentDisplayName() const
102 {
103 	std::wstring str;
104     GetMsiProp(msihandle_, TEXT("STR_RTF_DOCUMENT"), str);
105 	if (m_IsWin9x && !IsConvertableToAnsi(str))
106 		str = TEXT("Rich Text Document");
107 	return str;
108 }
109 
110 std::wstring RegistrationContextInformation::GetRtfDocumentFileExtension() const
111 {
112 	return std::wstring(TEXT(".rtf"));
113 }
114 
115 std::wstring RegistrationContextInformation::GetRtfDocumentDefaultIconEntry() const
116 {
117 	return m_OOExecPath + std::wstring(TEXT(",1"));
118 }
119 
120 std::wstring RegistrationContextInformation::GetRtfDocumentDefaultShellCommand() const
121 {
122 	return std::wstring(TEXT("open"));
123 }
124 
125 std::wstring RegistrationContextInformation::GetExcelSheetDisplayName() const
126 {
127 	std::wstring str;
128     GetMsiProp(msihandle_, TEXT("STR_MS_EXCEL_WORKSHEET"), str);
129 	if (m_IsWin9x && !IsConvertableToAnsi(str))
130 		str = TEXT("Microsoft Excel Worksheet");
131 	return str;
132 }
133 
134 std::wstring RegistrationContextInformation::GetExcelSheetFileExtension() const
135 {
136 	return std::wstring(TEXT(".xls"));
137 }
138 
139 std::wstring RegistrationContextInformation::GetExcelSheetDefaultIconEntry() const
140 {
141 	return m_OOExecPath + std::wstring(TEXT(",3"));
142 }
143 
144 std::wstring RegistrationContextInformation::GetExcelSheetDefaultShellCommand() const
145 {
146 	return std::wstring(TEXT("open"));
147 }
148 
149 std::wstring RegistrationContextInformation::GetExcelTemplateDisplayName() const
150 {
151 	std::wstring str;
152     GetMsiProp(msihandle_, TEXT("STR_MS_EXCEL_TEMPLATE"), str);
153 	if (m_IsWin9x && !IsConvertableToAnsi(str))
154 		str = TEXT("Microsoft Excel Template");
155 	return str;
156 }
157 
158 std::wstring RegistrationContextInformation::GetExcelTemplateFileExtension() const
159 {
160 	return std::wstring(TEXT(".xlt"));
161 }
162 
163 std::wstring RegistrationContextInformation::GetExcelTemplateDefaultIconEntry() const
164 {
165 	return m_OOExecPath + std::wstring(TEXT(",4"));
166 }
167 
168 std::wstring RegistrationContextInformation::GetExcelTemplateDefaultShellCommand() const
169 {
170 	return std::wstring(TEXT("new"));
171 }
172 
173 std::wstring RegistrationContextInformation::GetPowerPointDocumentDisplayName() const
174 {
175 	std::wstring str;
176     GetMsiProp(msihandle_, TEXT("STR_MS_POWERPOINT_PRESENTATION"), str);
177 	if (m_IsWin9x && !IsConvertableToAnsi(str))
178 		str = TEXT("Microsoft PowerPoint Presentation");
179 	return str;
180 }
181 
182 std::wstring RegistrationContextInformation::GetPowerPointDocumentFileExtension() const
183 {
184 	return std::wstring(TEXT(".ppt"));
185 }
186 
187 std::wstring RegistrationContextInformation::GetPowerPointDocumentDefaultIconEntry() const
188 {
189 	return m_OOExecPath + std::wstring(TEXT(",7"));
190 }
191 
192 std::wstring RegistrationContextInformation::GetPowerPointDocumentDefaultShellCommand() const
193 {
194 	return std::wstring(TEXT("open"));
195 }
196 
197 std::wstring RegistrationContextInformation::GetPowerPointTemplateDisplayName() const
198 {
199 	std::wstring str;
200     GetMsiProp(msihandle_, TEXT("STR_MS_POWERPOINT_TEMPLATE"), str);
201 	if (m_IsWin9x && !IsConvertableToAnsi(str))
202 		str = TEXT("Microsoft PowerPoint Template");
203 	return str;
204 }
205 
206 std::wstring RegistrationContextInformation::GetPowerPointTemplateFileExtension() const
207 {
208 	return std::wstring(TEXT(".pot"));
209 }
210 
211 std::wstring RegistrationContextInformation::GetPowerPointTemplateDefaultIconEntry() const
212 {
213 	return m_OOExecPath + std::wstring(TEXT(",8"));
214 }
215 
216 std::wstring RegistrationContextInformation::GetPowerPointTemplateDefaultShellCommand() const
217 {
218 	return std::wstring(TEXT("new"));
219 }
220 
221 std::wstring RegistrationContextInformation::GetPowerPointShowDisplayName() const
222 {
223     std::wstring str;
224     GetMsiProp(msihandle_, TEXT("STR_MS_POWERPOINT_SHOW"), str);
225 	if (m_IsWin9x && !IsConvertableToAnsi(str))
226 		str = TEXT("Microsoft PowerPoint Show");
227 	return str;
228 }
229 
230 std::wstring RegistrationContextInformation::GetPowerPointShowFileExtension() const
231 {
232     return std::wstring(TEXT(".pps"));
233 }
234 
235 std::wstring RegistrationContextInformation::GetPowerPointShowDefaultIconEntry() const
236 {
237     return m_OOExecPath + std::wstring(TEXT(",7"));
238 }
239 
240 std::wstring RegistrationContextInformation::GetPowerPointShowDefaultShellCommand() const
241 {
242     return std::wstring(TEXT("open"));
243 }
244 
245 //----------------------------------------------
246 /** The string for the "New" command that should appear
247 	in the Explorer context menu when someone right
248 	clicks a Microsoft document
249 */
250 std::wstring RegistrationContextInformation::ShellNewCommandDisplayName() const
251 {
252 	std::wstring str;
253     GetMsiProp(msihandle_, TEXT("STR_NEW_DISPLAY_NAME"), str);
254 	std::wstring::size_type idx = str.find(TEXT("~"));
255 
256 	if(std::wstring::npos != idx)
257 		str.replace(idx, 1, TEXT("&"));
258 
259 	if (m_IsWin9x && !IsConvertableToAnsi(str))
260 		str = TEXT("&New");
261 
262 	return str;
263 }
264 
265 /** The string for the "Edit" command that should
266 	appear in the Explorer context menu when someone
267 	right clicks a document
268 */
269 std::wstring RegistrationContextInformation::ShellEditCommandDisplayName() const
270 {
271 	std::wstring str;
272     GetMsiProp(msihandle_, TEXT("STR_EDIT"), str);
273 	std::wstring::size_type idx = str.find(TEXT("~"));
274 
275 	if(std::wstring::npos != idx)
276 		str.replace(idx, 1, TEXT("&"));
277 
278 	if (m_IsWin9x && !IsConvertableToAnsi(str))
279 		str = TEXT("&Edit");
280 
281 	return str;
282 }
283 
284 std::wstring RegistrationContextInformation::GetOpenOfficeFriendlyAppName() const
285 {
286     std::wstring str;
287     GetMsiProp(msihandle_, TEXT("ProductName"), str);
288 	return str;
289 }
290 
291 std::wstring RegistrationContextInformation::GetOpenOfficeExecutablePath() const
292 {
293 	return m_OOExecPath;
294 }
295 
296 //----------------------------------------------
297 /** The name of the executable (currently "soffice.exe"
298 	but may change in the future, who knows) */
299 std::wstring RegistrationContextInformation::GetOpenOfficeExecutableName() const
300 {
301 	return m_OOExecName;
302 }
303 
304 /** A command line for the specified shell command */
305 std::wstring RegistrationContextInformation::GetOpenOfficeCommandline(SHELL_COMMAND ShellCommand,
306                                                                       OFFICE_APPLICATION OfficeApp) const
307 {
308 	// quote the path to OpenOffice, this is important
309 	// for Windows 9x
310 	std::wstring cmd_line = std::wstring(TEXT("\"")) + m_OOExecPath + std::wstring(TEXT("\""));
311 
312     switch( OfficeApp )
313     {
314 	case Writer:
315 		cmd_line += std::wstring( TEXT( " -writer" ) );
316 		break;
317 	case Calc:
318 		cmd_line += std::wstring( TEXT( " -calc" ) );
319 		break;
320 	case Impress:
321 		cmd_line += std::wstring( TEXT( " -impress" ) );
322 		break;
323     case Office: // default to std command line
324         break;
325 	// default: no default to find new added enums at compile time
326     }
327 	switch(ShellCommand)
328 	{
329     case New:
330         cmd_line += std::wstring(TEXT(" -n \"%1\""));
331         break;
332     case Open:
333         cmd_line += std::wstring(TEXT(" -o \"%1\""));
334         break;
335     case Print:
336         cmd_line += std::wstring(TEXT(" -p \"%1\""));
337         break;
338     case Printto:
339         cmd_line += std::wstring(TEXT(" -pt \"%2\" \"%1\""));
340         break;
341     // default: no default to find new added enums at compile time
342 	}
343 	return cmd_line;
344 }
345 
346 bool RegistrationContextInformation::IsConvertableToAnsi(const std::wstring& String) const
347 {
348 	char buff[MAX_REGKEY_LENGTH_WIN9X];
349 	BOOL bUsedDefChar = 0;
350 
351 	if (String.length() > 0)
352 	{
353         WideCharToMultiByte(
354 			CP_ACP,
355 			WC_COMPOSITECHECK | WC_DEFAULTCHAR,
356 			String.c_str(),
357 			static_cast<int>(String.length()),
358 			buff,
359 			sizeof(buff),
360 			NULL,
361 			&bUsedDefChar);
362 	}
363     return !bUsedDefChar;
364 }
365 
366 void RegistrationContextInformation::ExtractOpenOfficeExecNameFromPath()
367 {
368     std::wstring::size_type idx = m_OOExecPath.find_last_of(TEXT('\\'));
369     assert(idx != std::wstring::npos); // assert valid path
370 	m_OOExecName = m_OOExecPath.substr(idx + 1);
371 }
372 
373