Thread: Where is my file on disk

  1. #1
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659

    Where is my file on disk

    Back in the old days of FAT, this was an easy thing to do, you simply looked at the directory entry and that told you where on disk the file was stored.

    Does anyone have an idea of how to find the physical sector where a file starts on disk (I know the file is contiguous), when the file system is NTFS and the OS is XP ?

    Ta muchly.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  2. #2
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Does anyone have an idea of how to find the physical sector where a file starts on disk (I know the file is contiguous), when the file system is NTFS and the OS is XP ?
    You'll probably need DDK to get down on the kernel level to start this task. A possible starting point would be DeviceIOContol using the FSCTL_GET_RETRIEVAL_POINTERS control code which gets the list of virtual clusters of the file in question and the related logical clusters of the volume that are mapped to the virtual clusters of the file.

    I've never done this type of file "conversion". But if I were to attempt it, the above would be my starting point.

  3. #3
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Listed below is a code snippet to find the physical starting point of a file. I'd like to verify the accuracy of this snippet with a freeware utility that illustrates the physical layout of files on a volume. Can anybody suggest a utility?

    Also, the initial call to DeviceIoContol function will generate a "Reached the end of the file" error message for any files less than approximately 1K in size. I'm not sure why this error occurs. It works fine with files over approximately 1K in size.

    Code:
    // Needs DDK installed
    // Compile: cl.exe test.cpp /IC:\WinDDK\3790.1830\inc\wxp /IC:\WinDDK\3790.1830\inc\crt
    #define _WIN32_WINNT 0x0500 
    #include <windows.h>
    #include <winioctl.h>
    #include <stdio.h>
    #include <ntddvol.h>
    
    char *ShowError(void) 
    { 
        static char szReturn[128] = {0};
        char *lpMsgBuf; 
        FormatMessage( 
            FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 
            NULL, 
            GetLastError(), 
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
            (LPTSTR) &lpMsgBuf, 
            0, 
            NULL 
            ); 
        memset(szReturn,0,  sizeof szReturn);
        strcpy(szReturn, lpMsgBuf);
        LocalFree( lpMsgBuf ); 
        return (char *) szReturn;
    }
    
    int main(void)
    {
        CHAR szDrive [] = {"C:\\"};
        CHAR szVolumeHandleName[] = { "\\\\.\\C:"};
        CHAR szFileName[] = {"C:\\test.txt"};
        CHAR szVolumeName [128] = {0};
        CHAR szFileSystemName [32] = {0};
        INT iExtentsBufferSize = 1024;
        DWORD dwBytesReturned;
        DWORD dwSectorsPerCluster;
        DWORD dwBytesPerSector;
        DWORD dwNumberFreeClusters;
        DWORD dwTotalNumberClusters;
        DWORD dwVolumeSerialNumber;
        DWORD dwMaxFileNameLength;
        DWORD dwFileSystemFlags;
        DWORD dwClusterSizeInBytes;
    
        STARTING_VCN_INPUT_BUFFER StartingPointInputBuffer;
        LARGE_INTEGER FileOffstFromBegDisk;
        VOLUME_LOGICAL_OFFSET VolumeLogicalOffset;
        LARGE_INTEGER  PhysicalOffsetReturnValue;
        VOLUME_PHYSICAL_OFFSETS VolumePhysicalOffsets;
    
        HANDLE hFile;
    
        hFile = CreateFile(
            szFileName,
            GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ|FILE_SHARE_WRITE,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL);
        if(INVALID_HANDLE_VALUE == hFile)
            return -1;
    
        // Buffer to hold the extents info
        PRETRIEVAL_POINTERS_BUFFER lpRetrievalPointersBuffer =
            (PRETRIEVAL_POINTERS_BUFFER) malloc(iExtentsBufferSize);
    
        //StartingVcn field is the virtual cluster number in file
        // It is not a file offset
    
        // FSCTL_GET_RETRIEVAL_POINTERS acquires a list of virtual clusters from the
        // file system driver that make up the file and the related set of
        // Logical Clusters that represent the volume storage for these Virtual
        // Clusters.  On a heavliy fragmented volume, the file may not necessarily
        // be stored in contiguous storage locations.  Thus, it would be advisable
        // to follow the mapping of virtual to logical clusters "chain" to find
        // the complete physical layout of the file.
    
        // We want to start at the first virtual cluster ZERO   
        StartingPointInputBuffer.StartingVcn.QuadPart = 0;  
        if (!DeviceIoControl(
            hFile,
            FSCTL_GET_RETRIEVAL_POINTERS,
            &StartingPointInputBuffer,
            sizeof(STARTING_VCN_INPUT_BUFFER),
            lpRetrievalPointersBuffer,
            iExtentsBufferSize,
            &dwBytesReturned,
            NULL))
        {
            printf("%s\n", ShowError());
            return -1;
        }
        CloseHandle(hFile);
    
        if (!GetDiskFreeSpace(
            szDrive,
            &dwSectorsPerCluster,
            &dwBytesPerSector,
            &dwNumberFreeClusters,
            &dwTotalNumberClusters))
        {
            return -1;
        }
        dwClusterSizeInBytes = dwSectorsPerCluster * dwBytesPerSector;
    
        if (!GetVolumeInformation(
            szDrive,
            szVolumeName,
            128,
            &dwVolumeSerialNumber,
            &dwMaxFileNameLength,
            &dwFileSystemFlags,
            szFileSystemName,
            32))
            return -1;
    
        HANDLE volumeHandle = CreateFile(
            szVolumeHandleName,
            GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ|FILE_SHARE_WRITE,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL);
    
        if (volumeHandle == INVALID_HANDLE_VALUE)
            return -1;
    
        else if (strcmp(szFileSystemName, "NTFS") == 0)
        {
            VolumeLogicalOffset.LogicalOffset = lpRetrievalPointersBuffer -> Extents [0].Lcn.QuadPart * dwClusterSizeInBytes;
            if (!DeviceIoControl(
                volumeHandle,
                IOCTL_VOLUME_LOGICAL_TO_PHYSICAL,
                &VolumeLogicalOffset,
                sizeof(VOLUME_LOGICAL_OFFSET),
                &VolumePhysicalOffsets,
                sizeof(VOLUME_PHYSICAL_OFFSETS),
                &dwBytesReturned,
                NULL))
            {
                CloseHandle(volumeHandle);
                return -1;
            }
            CloseHandle(volumeHandle);
            PhysicalOffsetReturnValue.QuadPart = 0;
            PhysicalOffsetReturnValue.QuadPart += VolumePhysicalOffsets.PhysicalOffset [0].Offset;
            if (PhysicalOffsetReturnValue.QuadPart != -1)
            {
                printf("%s starts at 0x%x%x from beginning of the disk\n\n",
                    szFileName,
                    PhysicalOffsetReturnValue.HighPart,
                    PhysicalOffsetReturnValue.LowPart);
                return 0;
            }
        }
        else 
        {
            printf("%s File system NOT supported\n",szFileSystemName);
            return  -1;
        }
        return 0;
    }

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Looks good - thanks.

    Now to tackle the problem of getting the DDK - there seems to be a lot of hoops to jump through
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    You can probaby get away with not using the DDK. I've been known to extract structures and constants from ReactOS sources

    http://www.reactos.org/generated/dox...8h-source.html

    gg

  6. #6
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    You can probaby get away with not using the DDK. I've been known to extract structures and constants from ReactOS sources
    That'll work. Normally, the ntddvol.h header file is in the DDK. But the ReactOS header works just fine. Thus, eliminating the need for the DDK.

  7. #7
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    I'd like to verify the accuracy of this snippet with a freeware utility that illustrates the physical layout of files on a volume. Can anybody suggest a utility?
    The DiskView utility can be used to verify the accuracy of the example code.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Looks good - many thanks for the help BobS0327.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need Help Fixing My C Program. Deals with File I/O
    By Matus in forum C Programming
    Replies: 7
    Last Post: 04-29-2008, 07:51 PM
  2. help with text input
    By Alphawaves in forum C Programming
    Replies: 8
    Last Post: 04-08-2007, 04:54 PM
  3. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  4. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM
  5. Need a suggestion on a school project..
    By Screwz Luse in forum C Programming
    Replies: 5
    Last Post: 11-27-2001, 02:58 AM