code to get LCN from filename
Jay Norwood
jayn at prismnet.com
Sun Apr 8 18:20:28 PDT 2012
I hacked up one of the file.d functions to create a function that
returns the first Logical Cluster Number for a regular file.
I've tested it on the 2GB layout that has been defragged with the
myDefrag sortByName() operation, and it works as expected.
Values of 0 mean the file was small enough to fit in the MFT.
The LCN numbers would be a good thing to sort by before doing
accesses on entries coming from any large directory operations
... for example zip, copy, delete of directories.
enum {
FILE_DEVICE_FILE_SYSTEM = 9,
METHOD_NEITHER = 3,
FILE_ANY_ACCESS = 0
}
uint CTL_CODE(uint t, uint f, uint m, uint a) {
return (t << 16) | (a << 14) | (f << 2) | m;
}
const FSCTL_GET_RETRIEVAL_POINTERS =
CTL_CODE(FILE_DEVICE_FILE_SYSTEM,28,METHOD_NEITHER,FILE_ANY_ACCESS);
/*********************************************
extern (Windows) int DeviceIoControl(void *, uint, void *, uint,
void *, uint, uint *, _OVERLAPPED *);
from WinIoCtl.h in SDK
#define FSCTL_GET_RETRIEVAL_POINTERS
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 28, METHOD_NEITHER,
FILE_ANY_ACCESS) // STARTING_VCN_INPUT_BUFFER,
RETRIEVAL_POINTERS_BUFFER
*/
struct RETRIEVAL_POINTERS_BUFFER{
}
ulong getStartLCN (in char[] name)
{
int[] buffer = [ 0 ];
version(Windows)
{
alias TypeTuple!(GENERIC_READ, FILE_SHARE_READ, null,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
HANDLE.init)
defaults;
auto h = useWfuncs
? CreateFileW(std.utf.toUTF16z(name), defaults)
: CreateFileA(toMBSz(name), defaults);
cenforce(h != INVALID_HANDLE_VALUE, name);
scope(exit) cenforce(CloseHandle(h), name);
alias long LARGE_INTEGER ;
struct STARTING_VCN_INPUT_BUFFER {
LARGE_INTEGER StartingVcn;
}
STARTING_VCN_INPUT_BUFFER inputVcn;
inputVcn.StartingVcn = 0;
struct RPExtents{
LARGE_INTEGER NextVcn;
LARGE_INTEGER Lcn;
}
struct RETRIEVAL_POINTERS_BUFFER {
DWORD ExtentCount;
LARGE_INTEGER StartingVcn;
RPExtents rpExtents[1];
}
RETRIEVAL_POINTERS_BUFFER rpBuf;
DWORD numBytes;
//expect only a partial return of one rpExtent
DeviceIoControl(
h, FSCTL_GET_RETRIEVAL_POINTERS,
cast(void*)&inputVcn, inputVcn.sizeof,
cast(void*)&rpBuf, rpBuf.sizeof,
&numBytes, null
);
return cast(ulong)rpBuf.rpExtents[0].Lcn;
}
else version(Posix)
return 0; // not implemented
}
More information about the Digitalmars-d-announce
mailing list