digitalmars.D.announce - code to get LCN from filename
- Jay Norwood (73/73) Apr 08 2012 I hacked up one of the file.d functions to create a function that
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 }
Apr 08 2012