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
23
24 #define _WIN32_WINNT 0x0401
25
26 #ifdef _MSC_VER
27 #pragma warning(push, 1) /* disable warnings within system headers */
28 #endif
29 #define WIN32_LEAN_AND_MEAN
30 #include <windows.h>
31 #include <msiquery.h>
32 #ifdef _MSC_VER
33 #pragma warning(pop)
34 #endif
35
36 #include <malloc.h>
37 #include <assert.h>
38
39 #ifdef UNICODE
40 #define _UNICODE
41 #define _tstring wstring
42 #else
43 #define _tstring string
44 #endif
45 #include <tchar.h>
46 #include <string>
47 #include <queue>
48 #include <stdio.h>
49 #include <strsafe.h>
50
51 #include <systools/win32/uwinapi.h>
52 #include <../tools/seterror.hxx>
53
54 //----------------------------------------------------------
55 #ifdef DEBUG
OutputDebugStringFormat(LPCSTR pFormat,...)56 inline void OutputDebugStringFormat( LPCSTR pFormat, ... )
57 {
58 CHAR buffer[1024];
59 va_list args;
60
61 va_start( args, pFormat );
62 StringCchVPrintfA( buffer, sizeof(buffer), pFormat, args );
63 OutputDebugStringA( buffer );
64 }
65 #else
OutputDebugStringFormat(LPCSTR,...)66 static inline void OutputDebugStringFormat( LPCSTR, ... )
67 {
68 }
69 #endif
70
71
GetMsiProperty(MSIHANDLE handle,const std::_tstring & sProperty)72 static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
73 {
74 std::_tstring result;
75 TCHAR szDummy[1] = TEXT("");
76 DWORD nChars = 0;
77
78 if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
79 {
80 DWORD nBytes = ++nChars * sizeof(TCHAR);
81 LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
82 ZeroMemory( buffer, nBytes );
83 MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
84 result = buffer;
85 }
86
87 return result;
88 }
89
RemoveCompleteDirectory(std::_tstring sPath)90 static BOOL RemoveCompleteDirectory( std::_tstring sPath )
91 {
92 bool bDirectoryRemoved = true;
93
94 std::_tstring mystr;
95 std::_tstring sPattern = sPath + TEXT("\\") + TEXT("*.*");
96 WIN32_FIND_DATA aFindData;
97
98 // Finding all content in sPath
99
100 HANDLE hFindContent = FindFirstFile( sPattern.c_str(), &aFindData );
101
102 if ( hFindContent != INVALID_HANDLE_VALUE )
103 {
104 bool fNextFile = false;
105 std::_tstring sCurrentDir = TEXT(".");
106 std::_tstring sParentDir = TEXT("..");
107
108 do
109 {
110 std::_tstring sFileName = aFindData.cFileName;
111
112 mystr = "Current short file: " + sFileName;
113 // MessageBox(NULL, mystr.c_str(), "Current Content", MB_OK);
114
115 if (( strcmp(sFileName.c_str(),sCurrentDir.c_str()) != 0 ) &&
116 ( strcmp(sFileName.c_str(),sParentDir.c_str()) != 0 ))
117 {
118 std::_tstring sCompleteFileName = sPath + TEXT("\\") + sFileName;
119
120 if ( aFindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )
121 {
122 bool fSuccess = RemoveCompleteDirectory(sCompleteFileName);
123 if ( fSuccess )
124 {
125 mystr = "Successfully removed content of dir " + sCompleteFileName;
126 // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
127 }
128 else
129 {
130 mystr = "An error occurred during removing content of " + sCompleteFileName;
131 // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
132 }
133 }
134 else
135 {
136 bool fSuccess = DeleteFile( sCompleteFileName.c_str() );
137 if ( fSuccess )
138 {
139 mystr = "Successfully removed file " + sCompleteFileName;
140 // MessageBox(NULL, mystr.c_str(), "Removed File", MB_OK);
141 }
142 else
143 {
144 mystr = "An error occurred during removal of file " + sCompleteFileName;
145 // MessageBox(NULL, mystr.c_str(), "Error removing file", MB_OK);
146 }
147 }
148 }
149
150 fNextFile = FindNextFile( hFindContent, &aFindData );
151
152 } while ( fNextFile );
153
154 FindClose( hFindContent );
155
156 // empty directory can be removed now
157 // RemoveDirectory is only successful, if the last handle to the directory is closed
158 // -> first removing content -> closing handle -> remove empty directory
159
160 bool fRemoveDirSuccess = RemoveDirectory(sPath.c_str());
161
162 if ( fRemoveDirSuccess )
163 {
164 mystr = "Successfully removed dir " + sPath;
165 // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
166 }
167 else
168 {
169 mystr = "An error occurred during removal of empty directory " + sPath;
170 // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
171 bDirectoryRemoved = false;
172 }
173 }
174
175 return bDirectoryRemoved;
176 }
177
178
179
RenamePrgFolder(MSIHANDLE handle)180 extern "C" UINT __stdcall RenamePrgFolder( MSIHANDLE handle )
181 {
182 std::_tstring sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
183
184 std::_tstring sRenameSrc = sOfficeInstallPath + TEXT("program");
185 std::_tstring sRenameDst = sOfficeInstallPath + TEXT("program_old");
186
187 // MessageBox(NULL, sRenameSrc.c_str(), "INSTALLLOCATION", MB_OK);
188
189 bool bSuccess = MoveFile( sRenameSrc.c_str(), sRenameDst.c_str() );
190 if ( !bSuccess )
191 {
192 TCHAR sAppend[2] = TEXT("0");
193 for ( int i = 0; i < 10; i++ )
194 {
195 sRenameDst = sOfficeInstallPath + TEXT("program_old") + sAppend;
196 bSuccess = MoveFile( sRenameSrc.c_str(), sRenameDst.c_str() );
197 if ( bSuccess )
198 break;
199 sAppend[0] += 1;
200 }
201 }
202
203 #if 0
204 if ( !bSuccess )
205 MessageBox(NULL, "Renaming folder failed", "RenamePrgFolder", MB_OK);
206 else
207 MessageBox(NULL, "Renaming folder successful", "RenamePrgFolder", MB_OK);
208 #endif
209
210 return ERROR_SUCCESS;
211 }
212
RemovePrgFolder(MSIHANDLE handle)213 extern "C" UINT __stdcall RemovePrgFolder( MSIHANDLE handle )
214 {
215 std::_tstring sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
216 std::_tstring sRemoveDir = sOfficeInstallPath + TEXT("program_old");
217
218 // MessageBox(NULL, sRemoveDir.c_str(), "REMOVING OLD DIR", MB_OK);
219
220 bool bSuccess = RemoveCompleteDirectory( sRemoveDir );
221
222 TCHAR sAppend[2] = TEXT("0");
223 for ( int i = 0; i < 10; i++ )
224 {
225 sRemoveDir = sOfficeInstallPath + TEXT("program_old") + sAppend;
226 bSuccess = RemoveCompleteDirectory( sRemoveDir );
227 sAppend[0] += 1;
228 }
229
230 #if 0
231 if ( bSuccess )
232 MessageBox(NULL, "Removing folder successful", "RemovePrgFolder", MB_OK);
233 else
234 MessageBox(NULL, "Removing folder failed", "RemovePrgFolder", MB_OK);
235 #endif
236
237 return ERROR_SUCCESS;
238 }
239