merge the formfield patch from ooo-build
[ooovba.git] / setup_native / source / win32 / customactions / shellextensions / copyeditiondata.cxx
blob67b3bff07f27052fb316310c3bd99cf079b60d99
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: copyeditiondata.cxx,v $
10 * $Revision: 1.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 #include "sal/config.h"
33 #include <cstddef>
34 #include <new>
35 #include <string.h> // <cstring> not supported by old MSC versions
37 #define WIN32_LEAN_AND_MEAN
38 #if defined _MSC_VER
39 #pragma warning(push, 1)
40 #endif
41 #include <windows.h>
42 #include <msiquery.h>
43 #include <shellapi.h>
44 #if defined _MSC_VER
45 #pragma warning(pop)
46 #endif
48 #include "boost/scoped_array.hpp"
50 #define LCL_LENGTH0(s) (sizeof (s) / sizeof *(s))
51 #define LCL_STRING0(s) (s), LCL_LENGTH0(s)
53 namespace {
55 enum Status { STATUS_NO, STATUS_YES, STATUS_ERROR };
57 Status fileExists(wchar_t const * path) {
58 return GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES
59 ? GetLastError() == ERROR_FILE_NOT_FOUND ? STATUS_NO : STATUS_ERROR
60 : STATUS_YES;
63 wchar_t * getProperty(
64 MSIHANDLE install, wchar_t const * name, wchar_t const * suffix,
65 std::size_t suffixLength, wchar_t ** end = NULL)
67 DWORD n = 0;
68 UINT err = MsiGetPropertyW(install, name, L"", &n);
69 if (err != ERROR_SUCCESS && err != ERROR_MORE_DATA) {
70 return NULL;
72 DWORD n2 = n + suffixLength; //TODO: overflow
73 wchar_t * data = new(std::nothrow) wchar_t[n2];
74 if (data == NULL) {
75 return NULL;
77 if (MsiGetPropertyW(install, name, data, &n2) != ERROR_SUCCESS || n2 != n) {
78 delete[] data;
79 return NULL;
81 memcpy(data + n, suffix, suffixLength * sizeof (wchar_t)); //TODO: overflow
82 if (end != NULL) {
83 *end = data + n + suffixLength;
85 return data;
90 extern "C" UINT __stdcall copyEditionData(MSIHANDLE install) {
91 boost::scoped_array<wchar_t> from(
92 getProperty(install, L"SourceDir", LCL_STRING0(L"edition\0")));
93 if (!from) {
94 return ERROR_INSTALL_FAILURE;
96 Status stat = fileExists(from.get());
97 if (stat == STATUS_ERROR) {
98 return ERROR_INSTALL_FAILURE;
100 if (stat == STATUS_NO) {
101 return ERROR_SUCCESS;
103 wchar_t * end;
104 boost::scoped_array<wchar_t> to(
105 getProperty(
106 install, L"OFFICEINSTALLLOCATION",
107 LCL_STRING0(L"program\\edition\0"), &end));
108 if (!to) {
109 return ERROR_INSTALL_FAILURE;
111 stat = fileExists(to.get());
112 if (stat == STATUS_ERROR) {
113 return ERROR_INSTALL_FAILURE;
115 if (stat == STATUS_YES) {
116 SHFILEOPSTRUCTW opDelete = {
117 NULL, FO_DELETE, to.get(), NULL, FOF_NOCONFIRMATION | FOF_SILENT,
118 FALSE, NULL, NULL }; //TODO: non-NULL hwnd
119 if (SHFileOperationW(&opDelete) != 0) {
120 return ERROR_INSTALL_FAILURE;
123 *(end - LCL_LENGTH0(L"\\edition\0")) = L'\0';
124 *(end - LCL_LENGTH0(L"\\edition\0") + 1) = L'\0';
125 SHFILEOPSTRUCTW opCopy = {
126 NULL, FO_COPY, from.get(), to.get(),
127 FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_SILENT, FALSE, NULL,
128 NULL }; //TODO: non-NULL hwnd
129 if (SHFileOperationW(&opCopy) != 0) {
130 return ERROR_INSTALL_FAILURE;
132 return ERROR_SUCCESS;