April 09, 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
}