Skip to content

Commit a33801c

Browse files
committed
Raw Disk Copier v1.0.0
1 parent 6b8798f commit a33801c

File tree

15 files changed

+2894
-0
lines changed

15 files changed

+2894
-0
lines changed

RawDiskCopier.sln

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 9.00
3+
# Visual Studio 2005
4+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RawDiskCopier", "RawDiskCopier\RawDiskCopier.csproj", "{3D440C05-557B-4CAC-920D-1D11551FD8CD}"
5+
EndProject
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utilities", "..\DynamicDiskPartitioner\Utilities\Utilities.csproj", "{6E0F2D1E-6167-4032-BA90-DEE3A99207D0}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiskAccessLibrary", "..\DynamicDiskPartitioner\DiskAccessLibrary\DiskAccessLibrary.csproj", "{000D0367-63A1-475D-982D-67A0B93BABEB}"
9+
EndProject
10+
Global
11+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12+
Debug|Any CPU = Debug|Any CPU
13+
Release|Any CPU = Release|Any CPU
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{3D440C05-557B-4CAC-920D-1D11551FD8CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17+
{3D440C05-557B-4CAC-920D-1D11551FD8CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
18+
{3D440C05-557B-4CAC-920D-1D11551FD8CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
19+
{3D440C05-557B-4CAC-920D-1D11551FD8CD}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{6E0F2D1E-6167-4032-BA90-DEE3A99207D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{6E0F2D1E-6167-4032-BA90-DEE3A99207D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{6E0F2D1E-6167-4032-BA90-DEE3A99207D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{6E0F2D1E-6167-4032-BA90-DEE3A99207D0}.Release|Any CPU.Build.0 = Release|Any CPU
24+
{000D0367-63A1-475D-982D-67A0B93BABEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25+
{000D0367-63A1-475D-982D-67A0B93BABEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
26+
{000D0367-63A1-475D-982D-67A0B93BABEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
27+
{000D0367-63A1-475D-982D-67A0B93BABEB}.Release|Any CPU.Build.0 = Release|Any CPU
28+
EndGlobalSection
29+
GlobalSection(SolutionProperties) = preSolution
30+
HideSolutionNode = FALSE
31+
EndGlobalSection
32+
EndGlobal

RawDiskCopier/DiskCopier.cs

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/* Copyright (C) 2016-2017 Tal Aloni <[email protected]>. All rights reserved.
2+
*
3+
* You can redistribute this program and/or modify it under the terms of
4+
* the GNU Lesser Public License as published by the Free Software Foundation,
5+
* either version 3 of the License, or (at your option) any later version.
6+
*/
7+
using System;
8+
using System.Collections.Generic;
9+
using System.IO;
10+
using System.Threading;
11+
using DiskAccessLibrary;
12+
using Utilities;
13+
14+
namespace RawDiskCopier
15+
{
16+
public class DiskCopier : DiskReader
17+
{
18+
private Disk m_targetDisk;
19+
20+
public DiskCopier(Disk sourceDisk, Disk targetDisk) : base(sourceDisk)
21+
{
22+
m_targetDisk = targetDisk;
23+
}
24+
25+
public BlockStatus QuickCopy(long sectorIndex, long sectorCount, bool writeZeros)
26+
{
27+
bool crcErrorOccured = false;
28+
for (long sectorOffset = 0; sectorOffset < sectorCount; sectorOffset += PhysicalDisk.MaximumDirectTransferSizeLBA)
29+
{
30+
int leftToRead = (int)(sectorCount - sectorOffset);
31+
int sectorsToRead = (int)Math.Min(leftToRead, PhysicalDisk.MaximumDirectTransferSizeLBA);
32+
bool ioErrorOccured;
33+
// Clear allocations from previous iteration
34+
GC.Collect();
35+
GC.WaitForPendingFinalizers();
36+
byte[] data = ReadSectorsUnbuffered(sectorIndex + sectorOffset, sectorsToRead, out ioErrorOccured);
37+
if (Abort)
38+
{
39+
return BlockStatus.Untested;
40+
}
41+
42+
if (ioErrorOccured)
43+
{
44+
return BlockStatus.IOError;
45+
}
46+
47+
if (data == null)
48+
{
49+
crcErrorOccured = true;
50+
if (writeZeros)
51+
{
52+
data = new byte[sectorsToRead * m_targetDisk.BytesPerSector];
53+
}
54+
}
55+
56+
if (data != null)
57+
{
58+
try
59+
{
60+
WriteSectors(sectorIndex + sectorOffset, data);
61+
}
62+
catch (IOException)
63+
{
64+
return BlockStatus.WriteError;
65+
}
66+
}
67+
68+
if (Abort)
69+
{
70+
return BlockStatus.Untested;
71+
}
72+
}
73+
74+
if (crcErrorOccured)
75+
{
76+
return BlockStatus.Damaged;
77+
}
78+
else
79+
{
80+
return BlockStatus.OK;
81+
}
82+
}
83+
84+
public BlockStatus ThroughCopy(long sectorIndex, long sectorCount)
85+
{
86+
bool crcErrorOccured = false;
87+
for (long sectorOffset = 0; sectorOffset < sectorCount; sectorOffset += PhysicalDisk.MaximumDirectTransferSizeLBA)
88+
{
89+
int leftToRead = (int)(sectorCount - sectorOffset);
90+
int sectorsToRead = (int)Math.Min(leftToRead, PhysicalDisk.MaximumDirectTransferSizeLBA);
91+
List<long> damagedSectors;
92+
bool ioErrorOccured;
93+
// Clear allocations from previous iteration
94+
GC.Collect();
95+
GC.WaitForPendingFinalizers();
96+
byte[] data = ReadEverySector(sectorIndex + sectorOffset, sectorsToRead, out damagedSectors, out ioErrorOccured);
97+
if (Abort)
98+
{
99+
return BlockStatus.Untested;
100+
}
101+
102+
if (ioErrorOccured)
103+
{
104+
return BlockStatus.IOError;
105+
}
106+
107+
if (damagedSectors.Count > 0)
108+
{
109+
crcErrorOccured = true;
110+
}
111+
112+
try
113+
{
114+
WriteSectors(sectorIndex + sectorOffset, data);
115+
}
116+
catch (IOException)
117+
{
118+
return BlockStatus.WriteError;
119+
}
120+
121+
if (Abort)
122+
{
123+
return BlockStatus.Untested;
124+
}
125+
}
126+
127+
if (crcErrorOccured)
128+
{
129+
return BlockStatus.Damaged;
130+
}
131+
else
132+
{
133+
return BlockStatus.OK;
134+
}
135+
}
136+
137+
public void WriteSectors(long sectorIndex, byte[] data)
138+
{
139+
int sectorCount = data.Length / m_targetDisk.BytesPerSector;
140+
if (sectorCount > PhysicalDisk.MaximumDirectTransferSizeLBA)
141+
{
142+
// we must write one segment at the time
143+
for (int sectorOffset = 0; sectorOffset < sectorCount; sectorOffset += PhysicalDisk.MaximumDirectTransferSizeLBA)
144+
{
145+
int leftToWrite = sectorCount - sectorOffset;
146+
int sectorsToWrite = (int)Math.Min(leftToWrite, PhysicalDisk.MaximumDirectTransferSizeLBA);
147+
byte[] segment = new byte[sectorsToWrite * m_targetDisk.BytesPerSector];
148+
Array.Copy(data, sectorOffset * m_targetDisk.BytesPerSector, segment, 0, sectorsToWrite * m_targetDisk.BytesPerSector);
149+
m_targetDisk.WriteSectors(sectorIndex + sectorOffset, segment);
150+
}
151+
}
152+
else
153+
{
154+
m_targetDisk.WriteSectors(sectorIndex, data);
155+
}
156+
}
157+
158+
public Disk TargetDisk
159+
{
160+
get
161+
{
162+
return m_targetDisk;
163+
}
164+
}
165+
}
166+
}

0 commit comments

Comments
 (0)