xref: /AOO41X/main/sal/systools/win32/uwinapi/MoveFileExA.cpp (revision fc0bc00825ec02ef04af0b032f1c57b312b79937)
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 #include "macros.h"
25 
26 #define WININIT_FILENAME    "wininit.ini"
27 #define RENAME_SECTION      "rename"
28 
29 IMPLEMENT_THUNK( kernel32, WINDOWS, BOOL, WINAPI, MoveFileExA, ( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, DWORD dwFlags ) )
30 {
31     BOOL    fSuccess = FALSE;   // assume failure
32 
33     // Windows 9x has a special mechanism to move files after reboot
34 
35     if ( dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT )
36     {
37         CHAR    szExistingFileNameA[MAX_PATH];
38         CHAR    szNewFileNameA[MAX_PATH] = "NUL";
39 
40         // Path names in WININIT.INI must be in short path name form
41 
42         if (
43             GetShortPathNameA( lpExistingFileNameA, szExistingFileNameA, MAX_PATH ) &&
44             (!lpNewFileNameA || GetShortPathNameA( lpNewFileNameA, szNewFileNameA, MAX_PATH ))
45             )
46         {
47             CHAR    szBuffer[32767];    // The buffer size must not exceed 32K
48             DWORD   dwBufLen = GetPrivateProfileSectionA( RENAME_SECTION, szBuffer, elementsof(szBuffer), WININIT_FILENAME );
49 
50             CHAR    szRename[MAX_PATH]; // This is enough for at most to times 67 chracters
51             strcpy( szRename, szNewFileNameA );
52             strcat( szRename, "=" );
53             strcat( szRename, szExistingFileNameA );
54             size_t  lnRename = strlen(szRename);
55 
56             if ( dwBufLen + lnRename + 2 <= elementsof(szBuffer) )
57             {
58                 CopyMemory( &szBuffer[dwBufLen], szRename, lnRename );
59                 szBuffer[dwBufLen + lnRename ] = 0;
60                 szBuffer[dwBufLen + lnRename + 1 ] = 0;
61 
62                 fSuccess = WritePrivateProfileSectionA( RENAME_SECTION, szBuffer, WININIT_FILENAME );
63             }
64             else
65                 SetLastError( ERROR_BUFFER_OVERFLOW );
66         }
67     }
68     else
69     {
70 
71         fSuccess = MoveFileA( lpExistingFileNameA, lpNewFileNameA );
72 
73         if ( !fSuccess && 0 != (dwFlags & (MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)) )
74         {
75             BOOL    bFailIfExist = 0 == (dwFlags & MOVEFILE_REPLACE_EXISTING);
76 
77             fSuccess = CopyFileA( lpExistingFileNameA, lpNewFileNameA, bFailIfExist );
78 
79             // In case of successfull copy do not return FALSE if delete fails.
80             // Error detection is done by GetLastError()
81 
82             if ( fSuccess )
83             {
84                 SetLastError( NO_ERROR );
85                 DeleteFileA( lpExistingFileNameA );
86             }
87         }
88 
89     }
90 
91     return fSuccess;
92 }
93 
94