1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #define _WIN32_WINNT 0x0401
29 
30 #ifdef _MSC_VER
31 #pragma warning(push, 1) /* disable warnings within system headers */
32 #endif
33 #define WIN32_LEAN_AND_MEAN
34 #include <windows.h>
35 #include <msiquery.h>
36 #ifdef _MSC_VER
37 #pragma warning(pop)
38 #endif
39 
40 #include <malloc.h>
41 #include <assert.h>
42 
43 #ifdef UNICODE
44 #define _UNICODE
45 #define _tstring	wstring
46 #else
47 #define _tstring	string
48 #endif
49 #include <tchar.h>
50 #include <string>
51 #include <queue>
52 #include <stdio.h>
53 #include <strsafe.h>
54 
55 #include <systools/win32/uwinapi.h>
56 #include <../tools/seterror.hxx>
57 
58 //----------------------------------------------------------
59 #ifdef DEBUG
60 inline void OutputDebugStringFormat( LPCSTR pFormat, ... )
61 {
62 	CHAR    buffer[1024];
63 	va_list args;
64 
65 	va_start( args, pFormat );
66 	StringCchVPrintfA( buffer, sizeof(buffer), pFormat, args );
67 	OutputDebugStringA( buffer );
68 }
69 #else
70 static inline void OutputDebugStringFormat( LPCSTR, ... )
71 {
72 }
73 #endif
74 
75 
76 static std::_tstring GetMsiProperty( MSIHANDLE handle, const std::_tstring& sProperty )
77 {
78     std::_tstring result;
79     TCHAR szDummy[1] = TEXT("");
80     DWORD nChars = 0;
81 
82     if ( MsiGetProperty( handle, sProperty.c_str(), szDummy, &nChars ) == ERROR_MORE_DATA )
83     {
84         DWORD nBytes = ++nChars * sizeof(TCHAR);
85         LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
86         ZeroMemory( buffer, nBytes );
87         MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
88         result = buffer;
89     }
90 
91     return result;
92 }
93 
94 static BOOL RemoveCompleteDirectory( std::_tstring sPath )
95 {
96     bool bDirectoryRemoved = true;
97 
98     std::_tstring mystr;
99     std::_tstring sPattern = sPath + TEXT("\\") + TEXT("*.*");
100     WIN32_FIND_DATA aFindData;
101 
102     // Finding all content in sPath
103 
104     HANDLE hFindContent = FindFirstFile( sPattern.c_str(), &aFindData );
105 
106     if ( hFindContent != INVALID_HANDLE_VALUE )
107     {
108         bool fNextFile = false;
109         std::_tstring sCurrentDir = TEXT(".");
110         std::_tstring sParentDir = TEXT("..");
111 
112         do
113         {
114             std::_tstring sFileName = aFindData.cFileName;
115 
116             mystr = "Current short file: " + sFileName;
117             // MessageBox(NULL, mystr.c_str(), "Current Content", MB_OK);
118 
119             if (( strcmp(sFileName.c_str(),sCurrentDir.c_str()) != 0 ) &&
120                 ( strcmp(sFileName.c_str(),sParentDir.c_str()) != 0 ))
121             {
122                 std::_tstring sCompleteFileName = sPath + TEXT("\\") + sFileName;
123 
124                 if ( aFindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )
125                 {
126                     bool fSuccess = RemoveCompleteDirectory(sCompleteFileName);
127                     if ( fSuccess )
128                     {
129                         mystr = "Successfully removed content of dir " + sCompleteFileName;
130                         // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
131                     }
132                     else
133                     {
134                         mystr = "An error occured during removing content of " + sCompleteFileName;
135                         // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
136                     }
137                 }
138                 else
139                 {
140                     bool fSuccess = DeleteFile( sCompleteFileName.c_str() );
141                     if ( fSuccess )
142                     {
143                         mystr = "Successfully removed file " + sCompleteFileName;
144                         // MessageBox(NULL, mystr.c_str(), "Removed File", MB_OK);
145                     }
146                     else
147                     {
148                         mystr = "An error occured during removal of file " + sCompleteFileName;
149                         // MessageBox(NULL, mystr.c_str(), "Error removing file", MB_OK);
150                     }
151                 }
152             }
153 
154             fNextFile = FindNextFile( hFindContent, &aFindData );
155 
156         } while ( fNextFile );
157 
158         FindClose( hFindContent );
159 
160         // empty directory can be removed now
161         // RemoveDirectory is only successful, if the last handle to the directory is closed
162         // -> first removing content -> closing handle -> remove empty directory
163 
164         bool fRemoveDirSuccess = RemoveDirectory(sPath.c_str());
165 
166         if ( fRemoveDirSuccess )
167         {
168             mystr = "Successfully removed dir " + sPath;
169             // MessageBox(NULL, mystr.c_str(), "Removed Directory", MB_OK);
170         }
171         else
172         {
173             mystr = "An error occured during removal of empty directory " + sPath;
174             // MessageBox(NULL, mystr.c_str(), "Error removing directory", MB_OK);
175             bDirectoryRemoved = false;
176         }
177     }
178 
179     return bDirectoryRemoved;
180 }
181 
182 
183 
184 extern "C" UINT __stdcall RenamePrgFolder( MSIHANDLE handle )
185 {
186     std::_tstring sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
187 
188     std::_tstring sRenameSrc = sOfficeInstallPath + TEXT("program");
189     std::_tstring sRenameDst = sOfficeInstallPath + TEXT("program_old");
190 
191 //    MessageBox(NULL, sRenameSrc.c_str(), "INSTALLLOCATION", MB_OK);
192 
193     bool bSuccess = MoveFile( sRenameSrc.c_str(), sRenameDst.c_str() );
194     if ( !bSuccess )
195     {
196         TCHAR sAppend[2] = TEXT("0");
197         for ( int i = 0; i < 10; i++ )
198         {
199             sRenameDst = sOfficeInstallPath + TEXT("program_old") + sAppend;
200             bSuccess = MoveFile( sRenameSrc.c_str(), sRenameDst.c_str() );
201             if ( bSuccess )
202                 break;
203             sAppend[0] += 1;
204         }
205     }
206 
207 #if 0
208     if ( !bSuccess )
209         MessageBox(NULL, "Renaming folder failed", "RenamePrgFolder", MB_OK);
210     else
211         MessageBox(NULL, "Renaming folder successful", "RenamePrgFolder", MB_OK);
212 #endif
213 
214     return ERROR_SUCCESS;
215 }
216 
217 extern "C" UINT __stdcall RemovePrgFolder( MSIHANDLE handle )
218 {
219     std::_tstring sOfficeInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));
220     std::_tstring sRemoveDir = sOfficeInstallPath + TEXT("program_old");
221 
222 //    MessageBox(NULL, sRemoveDir.c_str(), "REMOVING OLD DIR", MB_OK);
223 
224     bool bSuccess = RemoveCompleteDirectory( sRemoveDir );
225 
226     TCHAR sAppend[2] = TEXT("0");
227     for ( int i = 0; i < 10; i++ )
228     {
229         sRemoveDir = sOfficeInstallPath + TEXT("program_old") + sAppend;
230         bSuccess = RemoveCompleteDirectory( sRemoveDir );
231         sAppend[0] += 1;
232     }
233 
234 #if 0
235     if ( bSuccess )
236         MessageBox(NULL, "Removing folder successful", "RemovePrgFolder", MB_OK);
237     else
238         MessageBox(NULL, "Removing folder failed", "RemovePrgFolder", MB_OK);
239 #endif
240 
241     return ERROR_SUCCESS;
242 }
243