1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
//
// 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;
}
|