Documente Academic
Documente Profesional
Documente Cultură
typedef struct
{
ULONG Type; /* Magic number 'FILE' */
USHORT UsaOffset; /* Offset to the update sequence */
USHORT UsaCount; /* Size in words of Update Sequence Number & Array (S)
*/
ULONGLONG Lsn; /* $LogFile Sequence Number (LSN) */
}
NTFS_RECORD_HEADER, *PNTFS_RECORD_HEADER;
typedef struct
{
NTFS_RECORD_HEADER RecHdr;
USHORT SequenceNumber; /* Sequence number */
USHORT LinkCount; /* Hard link count */
USHORT AttributeOffset; /* Offset to the first Attribute */
USHORT Flags; /* Flags */
ULONG BytesInUse; /* Real size of the FILE record */
ULONG BytesAllocated; /* Allocated size of the FILE record */
ULONGLONG BaseFileRecord; /* Reference to the base FILE record */
USHORT NextAttributeNumber; /* Next Attribute Id */
USHORT Pading; /* Align to 4 byte boundary (XP) */
ULONG MFTRecordNumber; /* Number of this MFT Record (XP) */
USHORT UpdateSeqNum;
}
FILE_RECORD_HEADER, *PFILE_RECORD_HEADER;
typedef enum
{
AttributeStandardInformation = 0x10,
AttributeAttributeList = 0x20,
AttributeFileName = 0x30,
AttributeObjectId = 0x40,
AttributeSecurityDescriptor = 0x50,
AttributeVolumeName = 0x60,
AttributeVolumeInformation = 0x70,
AttributeData = 0x80,
AttributeIndexRoot = 0x90,
AttributeIndexAllocation = 0xA0,
AttributeBitmap = 0xB0,
AttributeReparsePoint = 0xC0,
AttributeEAInformation = 0xD0,
AttributeEA = 0xE0,
AttributePropertySet = 0xF0,
AttributeLoggedUtilityStream = 0x100
}
ATTRIBUTE_TYPE, *PATTRIBUTE_TYPE;
typedef struct
{
ATTRIBUTE_TYPE AttributeType;
ULONG Length;
BOOLEAN Nonresident;
UCHAR NameLength;
USHORT NameOffset;
USHORT Flags;
USHORT AttributeNumber;
}
ATTRIBUTE, *PATTRIBUTE;
typedef struct
{
ATTRIBUTE Attribute;
ULONG ValueLength;
USHORT ValueOffset;
UCHAR Flags;
}
RESIDENT_ATTRIBUTE, *PRESIDENT_ATTRIBUTE;
CHAR szDrive[7];
wsprintf(szDrive, "%c:", *lpszSrc);
DWORD dwSectorPerCluster, dwBytesPerSector;
GetDiskFreeSpace(szDrive,
&dwSectorPerCluster,
&dwBytesPerSector,
NULL,
NULL);
DWORD dwClusterSize = (dwBytesPerSector * dwSectorPerCluster);
LARGE_INTEGER liFileSize;
liFileSize.LowPart = GetFileSize(hSrc, (LPDWORD)&liFileSize.HighPart);
//-------???
DWORD dwClusters = (liFileSize.QuadPart / dwClusterSize);
DWORD dwRead,dwWritten;
DWORD dwPointsSize = sizeof(RETRIEVAL_POINTERS_BUFFER) +
(dwClusters * (sizeof(LARGE_INTEGER) * 2));
PRETRIEVAL_POINTERS_BUFFER pPoints = (PRETRIEVAL_POINTERS_BUFFER) new
BYTE[dwPointsSize];
STARTING_VCN_INPUT_BUFFER vcnStart = { 0 };
if(DeviceIoControl(hSrc,
FSCTL_GET_RETRIEVAL_POINTERS,
&vcnStart,
sizeof(vcnStart),
pPoints,
dwPointsSize,
&dwWritten,
NULL))
{
wsprintf(szDrive, "\\\\.\\%c:", *lpszSrc);
SetEndOfFile(hDest);
ReadFile(hDrive,
lpCluster,
dwClusterSize,
&dwRead,
NULL);
SetFilePointer(hDest,
liDstPos.LowPart,
&liDstPos.HighPart,
FILE_BEGIN);
WriteFile(hDest,
lpCluster,
dwRead,
&dwWritten,
NULL);
liSrcPos.QuadPart += dwClusterSize;
liDstPos.QuadPart += dwClusterSize;
vcnPrev = pPoints->Extents[dwExtent].NextVcn;
}
delete lpCluster;
CloseHandle(hDest);
bResult = TRUE;
}
CloseHandle(hDrive);
}
else
{
// The file is too small to have a cluster assignment, so we need to
get the MFT record.
if(GetLastError() == ERROR_HANDLE_EOF)
{
CHAR szDrive[7];
wsprintf(szDrive, "\\\\.\\%c:", *lpszSrc);
{ bhFileInfo.nFileIndexLow,
bhFileInfo.nFileIndexHigh
}
};
PNTFS_FILE_RECORD_OUTPUT_BUFFER pmftRecordOutput
=(PNTFS_FILE_RECORD_OUTPUT_BUFFER)
new
BYTE[dwOuputSize];
if(DeviceIoControl(hDrive,
FSCTL_GET_NTFS_FILE_RECORD,
&mftRecordInput,
sizeof(mftRecordInput),
pmftRecordOutput,
dwOuputSize,
&dwWritten,
NULL))
{
PFILE_RECORD_HEADER pFileRecord =
(PFILE_RECORD_HEADER)pmftRecordOutput->FileRecordBuffer;
PATTRIBUTE pAttribute = (PATTRIBUTE)((LPBYTE)pFileRecord + pFileRecord-
>AttributeOffset);
LPBYTE lpData = NULL;
DWORD dwSize = 0;
if(pAttribute->AttributeType == AttributeData)
{
PRESIDENT_ATTRIBUTE pResAttrib = (PRESIDENT_ATTRIBUTE)pAttribute;
lpData = ((LPBYTE)pResAttrib + pResAttrib->ValueOffset);
dwSize = pResAttrib->ValueLength;
break;
}
pAttribute = (PATTRIBUTE)((LPBYTE)pAttribute + pAttribute->Length);
}
if(lpData != NULL){
HANDLE hDest = CreateFile(lpszDest, GENERIC_WRITE, 0, NULL, CREATE_NEW,
0, 0);
if(hDest != INVALID_HANDLE_VALUE){
WriteFile(hDest, lpData, dwSize, &dwWritten, NULL);
CloseHandle(hDest);
bResult = TRUE;
}
}
}
delete pmftRecordOutput;
}
}
CloseHandle(hDrive);
}
}
}
delete pPoints;
CloseHandle(hSrc);
}
return bResult;
}