1*fc0bc008SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*fc0bc008SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*fc0bc008SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*fc0bc008SAndrew Rist * distributed with this work for additional information 6*fc0bc008SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*fc0bc008SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*fc0bc008SAndrew Rist * "License"); you may not use this file except in compliance 9*fc0bc008SAndrew Rist * with the License. You may obtain a copy of the License at 10*fc0bc008SAndrew Rist * 11*fc0bc008SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*fc0bc008SAndrew Rist * 13*fc0bc008SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*fc0bc008SAndrew Rist * software distributed under the License is distributed on an 15*fc0bc008SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*fc0bc008SAndrew Rist * KIND, either express or implied. See the License for the 17*fc0bc008SAndrew Rist * specific language governing permissions and limitations 18*fc0bc008SAndrew Rist * under the License. 19*fc0bc008SAndrew Rist * 20*fc0bc008SAndrew Rist *************************************************************/ 21*fc0bc008SAndrew Rist 22*fc0bc008SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include "macros.h" 25cdf0e10cSrcweir 26cdf0e10cSrcweir #define WININIT_FILENAME "wininit.ini" 27cdf0e10cSrcweir #define RENAME_SECTION "rename" 28cdf0e10cSrcweir 29cdf0e10cSrcweir IMPLEMENT_THUNK( kernel32, WINDOWS, BOOL, WINAPI, MoveFileExA, ( LPCSTR lpExistingFileNameA, LPCSTR lpNewFileNameA, DWORD dwFlags ) ) 30cdf0e10cSrcweir { 31cdf0e10cSrcweir BOOL fSuccess = FALSE; // assume failure 32cdf0e10cSrcweir 33cdf0e10cSrcweir // Windows 9x has a special mechanism to move files after reboot 34cdf0e10cSrcweir 35cdf0e10cSrcweir if ( dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT ) 36cdf0e10cSrcweir { 37cdf0e10cSrcweir CHAR szExistingFileNameA[MAX_PATH]; 38cdf0e10cSrcweir CHAR szNewFileNameA[MAX_PATH] = "NUL"; 39cdf0e10cSrcweir 40cdf0e10cSrcweir // Path names in WININIT.INI must be in short path name form 41cdf0e10cSrcweir 42cdf0e10cSrcweir if ( 43cdf0e10cSrcweir GetShortPathNameA( lpExistingFileNameA, szExistingFileNameA, MAX_PATH ) && 44cdf0e10cSrcweir (!lpNewFileNameA || GetShortPathNameA( lpNewFileNameA, szNewFileNameA, MAX_PATH )) 45cdf0e10cSrcweir ) 46cdf0e10cSrcweir { 47cdf0e10cSrcweir CHAR szBuffer[32767]; // The buffer size must not exceed 32K 48cdf0e10cSrcweir DWORD dwBufLen = GetPrivateProfileSectionA( RENAME_SECTION, szBuffer, elementsof(szBuffer), WININIT_FILENAME ); 49cdf0e10cSrcweir 50cdf0e10cSrcweir CHAR szRename[MAX_PATH]; // This is enough for at most to times 67 chracters 51cdf0e10cSrcweir strcpy( szRename, szNewFileNameA ); 52cdf0e10cSrcweir strcat( szRename, "=" ); 53cdf0e10cSrcweir strcat( szRename, szExistingFileNameA ); 54cdf0e10cSrcweir size_t lnRename = strlen(szRename); 55cdf0e10cSrcweir 56cdf0e10cSrcweir if ( dwBufLen + lnRename + 2 <= elementsof(szBuffer) ) 57cdf0e10cSrcweir { 58cdf0e10cSrcweir CopyMemory( &szBuffer[dwBufLen], szRename, lnRename ); 59cdf0e10cSrcweir szBuffer[dwBufLen + lnRename ] = 0; 60cdf0e10cSrcweir szBuffer[dwBufLen + lnRename + 1 ] = 0; 61cdf0e10cSrcweir 62cdf0e10cSrcweir fSuccess = WritePrivateProfileSectionA( RENAME_SECTION, szBuffer, WININIT_FILENAME ); 63cdf0e10cSrcweir } 64cdf0e10cSrcweir else 65cdf0e10cSrcweir SetLastError( ERROR_BUFFER_OVERFLOW ); 66cdf0e10cSrcweir } 67cdf0e10cSrcweir } 68cdf0e10cSrcweir else 69cdf0e10cSrcweir { 70cdf0e10cSrcweir 71cdf0e10cSrcweir fSuccess = MoveFileA( lpExistingFileNameA, lpNewFileNameA ); 72cdf0e10cSrcweir 73cdf0e10cSrcweir if ( !fSuccess && 0 != (dwFlags & (MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)) ) 74cdf0e10cSrcweir { 75cdf0e10cSrcweir BOOL bFailIfExist = 0 == (dwFlags & MOVEFILE_REPLACE_EXISTING); 76cdf0e10cSrcweir 77cdf0e10cSrcweir fSuccess = CopyFileA( lpExistingFileNameA, lpNewFileNameA, bFailIfExist ); 78cdf0e10cSrcweir 79cdf0e10cSrcweir // In case of successfull copy do not return FALSE if delete fails. 80cdf0e10cSrcweir // Error detection is done by GetLastError() 81cdf0e10cSrcweir 82cdf0e10cSrcweir if ( fSuccess ) 83cdf0e10cSrcweir { 84cdf0e10cSrcweir SetLastError( NO_ERROR ); 85cdf0e10cSrcweir DeleteFileA( lpExistingFileNameA ); 86cdf0e10cSrcweir } 87cdf0e10cSrcweir } 88cdf0e10cSrcweir 89cdf0e10cSrcweir } 90cdf0e10cSrcweir 91cdf0e10cSrcweir return fSuccess; 92cdf0e10cSrcweir } 93cdf0e10cSrcweir 94