// // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. // #include "standardpch.h" #include "verbconcat.h" #include "simpletimer.h" #include "logging.h" #define BUFFER_SIZE 0xFFFFFF int verbConcat::DoWork(const char *nameOfFile1, const char *nameOfFile2) { SimpleTimer st1; LogVerbose("Concatenating '%s'+'%s' into %s", nameOfFile1, nameOfFile2, nameOfFile1); LARGE_INTEGER DataTemp1; LARGE_INTEGER DataTemp2; HANDLE hFileIn1 = CreateFileA(nameOfFile1, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL); if(hFileIn1 == INVALID_HANDLE_VALUE) { LogError("Failed to open input 1 '%s'. GetLastError()=%u", nameOfFile1, GetLastError()); return -1; } if(GetFileSizeEx(hFileIn1, &DataTemp1)==0) { LogError("GetFileSizeEx failed. GetLastError()=%u", GetLastError()); return -1; } LONG highDWORD = 0; DWORD dwPtr = SetFilePointer(hFileIn1, 0, &highDWORD, FILE_END); if (dwPtr == INVALID_SET_FILE_POINTER) { LogError("Failed to SetFilePointer on input 1 '%s'. GetLastError()=%u", nameOfFile1, GetLastError()); return -1; } HANDLE hFileIn2 = CreateFileA(nameOfFile2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL); if(hFileIn2 == INVALID_HANDLE_VALUE) { LogError("Failed to open input 2 '%s'. GetLastError()=%u", nameOfFile2, GetLastError()); return -1; } if(GetFileSizeEx(hFileIn2, &DataTemp2)==0) { LogError("2nd GetFileSizeEx failed. GetLastError()=%u", GetLastError()); return -1; } unsigned char* buffer = new unsigned char[BUFFER_SIZE]; st1.Start(); for(LONGLONG offset = 0; offset < DataTemp2.QuadPart; offset += BUFFER_SIZE) { DWORD bytesRead = -1; BOOL res = ReadFile(hFileIn2, buffer, BUFFER_SIZE, &bytesRead, nullptr); if(res == 0) { LogError("Failed to read '%s' from offset %lld. GetLastError()=%u", nameOfFile2, offset, GetLastError()); return -1; } DWORD bytesWritten = -1; BOOL res2 = WriteFile(hFileIn1, buffer, bytesRead, &bytesWritten, nullptr); if(res2 == 0) { LogError("Failed to write '%s' at offset %lld. GetLastError()=%u", nameOfFile1, offset, GetLastError()); return -1; } if(bytesRead!=bytesWritten) { LogError("Failed to read/write matching bytes %u!=%u", bytesRead, bytesWritten); return -1; } } st1.Stop(); delete[] buffer; if(CloseHandle(hFileIn1)==0) { LogError("CloseHandle failed. GetLastError()=%u", GetLastError()); return -1; } if(CloseHandle(hFileIn2)==0) { LogError("2nd CloseHandle failed. GetLastError()=%u", GetLastError()); return -1; } LogInfo("Read/Wrote %lld MB @ %4.2f MB/s.\n", DataTemp2.QuadPart/(1000*1000), (((double)DataTemp2.QuadPart)/(1000*1000))/st1.GetSeconds()); //yes yes.. http://en.wikipedia.org/wiki/Megabyte_per_second#Megabyte_per_second return 0; }