Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / rosapps / applications / fraginator / DriveVolume.cpp
diff --git a/rosapps/applications/fraginator/DriveVolume.cpp b/rosapps/applications/fraginator/DriveVolume.cpp
deleted file mode 100644 (file)
index 4c8f005..0000000
+++ /dev/null
@@ -1,806 +0,0 @@
-#include "DriveVolume.h"\r
-\r
-\r
-DriveVolume::DriveVolume ()\r
-{\r
-    Handle = INVALID_HANDLE_VALUE;\r
-    BitmapDetail = NULL;\r
-    return;\r
-}\r
-\r
-\r
-DriveVolume::~DriveVolume ()\r
-{\r
-    Close ();\r
-    Directories.clear ();\r
-    Files.clear ();\r
-    return;\r
-}\r
-\r
-\r
-void DriveVolume::Close (void)\r
-{\r
-    if (Handle != INVALID_HANDLE_VALUE)\r
-    {\r
-        CloseHandle (Handle);\r
-        Handle = INVALID_HANDLE_VALUE;\r
-    }\r
-\r
-    if (BitmapDetail != NULL)\r
-    {\r
-        free (BitmapDetail);\r
-        BitmapDetail = NULL;\r
-    }\r
-\r
-    return;\r
-}\r
-\r
-\r
-// "Name" should be the drive letter followed by a colon. ie, "c:"\r
-// It's a string to allow for further expansion (ie, defragging over the network?)\r
-// or some other baloney reason\r
-bool DriveVolume::Open (wstring Name)\r
-{\r
-    wchar_t FileName[100];\r
-    bool ReturnVal;\r
-\r
-    swprintf (FileName, L"\\\\.\\%s", Name.c_str());\r
-    RootPath = Name.c_str();\r
-    RootPath += L"\\";\r
-\r
-    Handle = CreateFileW\r
-    (\r
-        FileName,\r
-        MAXIMUM_ALLOWED,                          // access\r
-        FILE_SHARE_READ | FILE_SHARE_WRITE,       // share type\r
-        NULL,                                     // security descriptor\r
-        OPEN_EXISTING,                            // open type\r
-        0,                                     // attributes (none)\r
-        NULL                                      // template\r
-    );\r
-\r
-    if (Handle == INVALID_HANDLE_VALUE)\r
-        ReturnVal = false;\r
-    else\r
-    {\r
-        wchar_t  VolName[64];\r
-        DWORD VolSN;\r
-        DWORD VolMaxFileLen;\r
-        DWORD FSFlags;\r
-        wchar_t  FSName[64];\r
-        BOOL  Result;\r
-\r
-        ReturnVal = true;\r
-        Result = GetVolumeInformationW\r
-        (\r
-            RootPath.c_str(),\r
-            VolName,\r
-            sizeof (VolName),\r
-            &VolSN,\r
-            &VolMaxFileLen,\r
-            &FSFlags,\r
-            FSName,\r
-            sizeof (FSName)\r
-        );\r
-\r
-        if (Result)\r
-        {\r
-            wchar_t SerialText[10];\r
-\r
-            VolInfo.FileSystem = FSName;\r
-            VolInfo.MaxNameLen = VolMaxFileLen;\r
-            VolInfo.Name       = VolName;\r
-\r
-            swprintf (SerialText, L"%x-%x", (VolSN & 0xffff0000) >> 16,\r
-                VolSN & 0x0000ffff);\r
-\r
-            _wcsupr (SerialText);\r
-            VolInfo.Serial     = SerialText;\r
-        }\r
-        else\r
-        {\r
-            VolInfo.FileSystem = L"(Unknown)";\r
-            VolInfo.MaxNameLen = 255;\r
-            VolInfo.Name       = L"(Unknown)";\r
-            VolInfo.Serial     = L"(Unknown)";\r
-        }\r
-    }\r
-\r
-    return (ReturnVal);\r
-}\r
-\r
-\r
-bool DriveVolume::ObtainInfo (void)\r
-{\r
-    BOOL Result;\r
-    DWORD BytesGot;\r
-    uint64 nan;\r
-\r
-    BytesGot = 0;\r
-    ZeroMemory (&Geometry, sizeof (Geometry));\r
-    Result = DeviceIoControl\r
-    (\r
-        Handle,\r
-        IOCTL_DISK_GET_DRIVE_GEOMETRY,\r
-        NULL,\r
-        0,\r
-        &Geometry,\r
-        sizeof (Geometry),\r
-        &BytesGot,\r
-        NULL\r
-    );\r
-\r
-    // Call failed? Aww :(\r
-    if (!Result)\r
-        return (false);\r
-\r
-    // Get cluster size\r
-    DWORD SectorsPerCluster;\r
-    DWORD BytesPerSector;\r
-    DWORD FreeClusters;\r
-    DWORD TotalClusters;\r
-\r
-    Result = GetDiskFreeSpaceW\r
-    (\r
-        RootPath.c_str(),\r
-        &SectorsPerCluster,\r
-        &BytesPerSector,\r
-        &FreeClusters,\r
-        &TotalClusters\r
-    );\r
-\r
-    // Failed? Weird.\r
-    if (!Result)\r
-        return (false);\r
-\r
-    VolInfo.ClusterSize = SectorsPerCluster * BytesPerSector;\r
-\r
-    Result = GetDiskFreeSpaceExW\r
-    (\r
-        RootPath.c_str(),\r
-        (PULARGE_INTEGER)&nan,\r
-        (PULARGE_INTEGER)&VolInfo.TotalBytes,\r
-        (PULARGE_INTEGER)&VolInfo.FreeBytes\r
-    );\r
-\r
-    return (true);\r
-}\r
-\r
-\r
-// Get bitmap, several clusters at a time ...\r
-#define CLUSTERS 4096\r
-bool DriveVolume::GetBitmap (void)\r
-{\r
-    STARTING_LCN_INPUT_BUFFER StartingLCN;\r
-    VOLUME_BITMAP_BUFFER *Bitmap = NULL;\r
-    uint32 BitmapSize;\r
-    DWORD BytesReturned;\r
-    BOOL Result;\r
-\r
-    StartingLCN.StartingLcn.QuadPart = 0;\r
-\r
-    // Allocate buffer\r
-    // Call FSCTL_GET_VOLUME_BITMAP once with a very small buffer\r
-    // This will leave the total number of clusters in Bitmap->BitmapSize and we can\r
-    // then correctly allocate based off that\r
-    // I suppose this won't work if your drive has only 40 clusters on it or so :)\r
-    BitmapSize = sizeof (VOLUME_BITMAP_BUFFER) + 4;\r
-    Bitmap = (VOLUME_BITMAP_BUFFER *) malloc (BitmapSize);\r
-\r
-    Result = DeviceIoControl\r
-    (\r
-        Handle,\r
-        FSCTL_GET_VOLUME_BITMAP,\r
-        &StartingLCN,\r
-        sizeof (StartingLCN),\r
-        Bitmap,\r
-        BitmapSize,\r
-        &BytesReturned,\r
-        NULL\r
-    );\r
-\r
-    // Bad result?\r
-    if (Result == FALSE  &&  GetLastError () != ERROR_MORE_DATA)\r
-    {\r
-        //wprintf ("\nDeviceIoControl returned false, GetLastError() was not ERROR_MORE_DATA\n");\r
-        free (Bitmap);\r
-        return (false);\r
-    }\r
-\r
-    // Otherwise, we're good\r
-    BitmapSize = sizeof (VOLUME_BITMAP_BUFFER) + (Bitmap->BitmapSize.QuadPart / 8) + 1;\r
-    Bitmap = (VOLUME_BITMAP_BUFFER *) realloc (Bitmap, BitmapSize);\r
-    Result = DeviceIoControl\r
-    (\r
-        Handle,\r
-        FSCTL_GET_VOLUME_BITMAP,\r
-        &StartingLCN,\r
-        sizeof (StartingLCN),\r
-        Bitmap,\r
-        BitmapSize,\r
-        &BytesReturned,\r
-        NULL\r
-    );\r
-\r
-    //DWORD LastError = GetLastError ();\r
-\r
-    if (Result == FALSE)\r
-    {\r
-        wprintf (L"\nCouldn't properly read volume bitmap\n");\r
-        free (Bitmap);\r
-        return (false);\r
-    }\r
-\r
-    // Convert to a L'quick use' bitmap\r
-    //const int BitShift[] = { 1, 2, 4, 8, 16, 32, 64, 128 };\r
-\r
-    VolInfo.ClusterCount = Bitmap->BitmapSize.QuadPart;\r
-\r
-    if (BitmapDetail != NULL)\r
-        free (BitmapDetail);\r
-\r
-    BitmapDetail = (uint32 *) malloc (sizeof(uint32) * (1 + (VolInfo.ClusterCount / 32)));\r
-    memcpy (BitmapDetail, Bitmap->Buffer, sizeof(uint32) * (1 + (VolInfo.ClusterCount / 32)));\r
-\r
-    /*\r
-    BitmapDetail = (Cluster *) malloc (VolInfo.ClusterCount * sizeof (Cluster));\r
-    for (uint64 i = 0; i < VolInfo.ClusterCount; i++)\r
-    {\r
-        if (Bitmap->Buffer[i / 8] & BitShift[i % 8])\r
-            BitmapDetail[i].Allocated = true;\r
-        else\r
-            BitmapDetail[i].Allocated = false;\r
-    }\r
-    */\r
-\r
-    free (Bitmap);\r
-    return (true);\r
-}\r
-\r
-\r
-bool DriveVolume::IsClusterUsed (uint64 Cluster)\r
-{\r
-    return ((BitmapDetail[Cluster / 32] & (1 << (Cluster % 32))) ? true : false);\r
-    //return (BitmapDetail[Cluster].Allocated);\r
-}\r
-\r
-\r
-void DriveVolume::SetClusterUsed (uint64 Cluster, bool Used)\r
-{\r
-    if (Used)\r
-        BitmapDetail[Cluster / 32] |= (1 << (Cluster % 32));\r
-    else\r
-        BitmapDetail[Cluster / 32] &= ~(1 << (Cluster % 32));\r
-\r
-    return;\r
-}\r
-\r
-\r
-typedef struct\r
-{\r
-    DriveVolume *Volume;\r
-    double       *Percent;\r
-    bool        *QuitMonitor;\r
-    uint64       ClusterCount;\r
-    uint64       ClusterProgress;\r
-} BuildDBInfo;\r
-\r
-\r
-bool DriveVolume::BuildFileList (bool &QuitMonitor, double &Percent)\r
-{\r
-    BuildDBInfo Info;\r
-\r
-    Files.clear ();\r
-    Directories.clear ();\r
-    Directories.push_back (RootPath);\r
-\r
-    Info.Volume = this;\r
-    Info.QuitMonitor = &QuitMonitor;\r
-    Info.ClusterCount = (GetVolumeInfo().TotalBytes - GetVolumeInfo().FreeBytes) / (uint64)GetVolumeInfo().ClusterSize;\r
-    Info.ClusterProgress = 0;\r
-    Info.Percent = &Percent;\r
-\r
-    ScanDirectory (RootPath, BuildDBCallback, &Info);\r
-\r
-    if (QuitMonitor == true)\r
-    {\r
-        Directories.resize (0);\r
-        Files.resize (0);\r
-    }\r
-\r
-    return (true);\r
-}\r
-\r
-\r
-// UserData = pointer to BuildDBInfo instance\r
-bool BuildDBCallback (FileInfo &Info, HANDLE &FileHandle, void *UserData)\r
-{\r
-    BuildDBInfo *DBInfo = (BuildDBInfo *) UserData;\r
-    DriveVolume *Vol = DBInfo->Volume;\r
-\r
-    Vol->Files.push_back (Info);\r
-\r
-    if (*(DBInfo->QuitMonitor) == true)\r
-        return (false);\r
-\r
-    DBInfo->ClusterProgress += (uint64)Info.Clusters;\r
-    *(DBInfo->Percent) =\r
-        ((double)DBInfo->ClusterProgress / (double)DBInfo->ClusterCount) * 100.0f;\r
-\r
-    return (true);\r
-}\r
-\r
-\r
-wstring &DriveVolume::GetDBDir (uint32 Indice)\r
-{\r
-    return (Directories[Indice]);\r
-}\r
-\r
-\r
-uint32 DriveVolume::GetDBDirCount (void)\r
-{\r
-    return (Directories.size());\r
-}\r
-\r
-\r
-FileInfo &DriveVolume::GetDBFile (uint32 Indice)\r
-{\r
-    return (Files[Indice]);\r
-}\r
-\r
-\r
-uint32 DriveVolume::GetDBFileCount (void)\r
-{\r
-    return (Files.size());\r
-}\r
-\r
-\r
-uint32 DriveVolume::RemoveDBFile (uint32 Indice)\r
-{\r
-    vector<FileInfo>::iterator it;\r
-\r
-    it = Files.begin() + Indice;\r
-    Files.erase (it);\r
-    return (GetDBFileCount());\r
-}\r
-\r
-\r
-bool DriveVolume::ScanDirectory (wstring DirPrefix, ScanCallback Callback, void *UserData)\r
-{\r
-    WIN32_FIND_DATAW FindData;\r
-    HANDLE          FindHandle;\r
-    wstring          SearchString;\r
-    uint32          DirIndice;\r
-\r
-    DirIndice = Directories.size() - 1;\r
-\r
-    SearchString = DirPrefix;\r
-    SearchString += L"*.*";\r
-    ZeroMemory (&FindData, sizeof (FindData));\r
-    FindHandle = FindFirstFileW (SearchString.c_str(), &FindData);\r
-\r
-    if (FindHandle == INVALID_HANDLE_VALUE)\r
-        return (false);\r
-\r
-    do\r
-    {\r
-        FileInfo Info;\r
-        HANDLE   Handle;\r
-        bool     CallbackResult;\r
-\r
-        Handle = INVALID_HANDLE_VALUE;\r
-\r
-        // First copy over the easy stuff.\r
-        Info.Name = FindData.cFileName;\r
-\r
-        // DonLL't ever include '.L' and '..'\r
-        if (Info.Name == L"."  ||  Info.Name == L"..")\r
-            continue;\r
-\r
-        //Info.FullName = DirPrefix + Info.Name;\r
-        Info.Size      = (uint64)FindData.nFileSizeLow + ((uint64)FindData.nFileSizeHigh << (uint64)32);\r
-        Info.DirIndice = DirIndice;\r
-\r
-        Info.Attributes.Archive    = (FindData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)       ? 1 : 0;\r
-        Info.Attributes.Compressed = (FindData.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)    ? 1 : 0;\r
-        Info.Attributes.Directory  = (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)     ? 1 : 0;\r
-        Info.Attributes.Encrypted  = (FindData.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED)     ? 1 : 0;\r
-        Info.Attributes.Hidden     = (FindData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)        ? 1 : 0;\r
-        Info.Attributes.Normal     = (FindData.dwFileAttributes & FILE_ATTRIBUTE_NORMAL)        ? 1 : 0;\r
-        Info.Attributes.Offline    = (FindData.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE)       ? 1 : 0;\r
-        Info.Attributes.ReadOnly   = (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)      ? 1 : 0;\r
-        Info.Attributes.Reparse    = (FindData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) ? 1 : 0;\r
-        Info.Attributes.Sparse     = (FindData.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE)   ? 1 : 0;\r
-        Info.Attributes.System     = (FindData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)        ? 1 : 0;\r
-        Info.Attributes.Temporary  = (FindData.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY)     ? 1 : 0;\r
-        Info.Attributes.AccessDenied = 0;\r
-        Info.Attributes.Unmovable    = 0;\r
-        Info.Attributes.Process      = 1;\r
-\r
-        Info.Clusters = 0;\r
-        if (GetClusterInfo (Info, Handle))\r
-        {\r
-            uint64 TotalClusters = 0;\r
-\r
-            for (size_t i = 0; i < Info.Fragments.size(); i++)\r
-            {\r
-                TotalClusters += Info.Fragments[i].Length;\r
-            }\r
-\r
-            Info.Clusters = TotalClusters;\r
-        }\r
-        else\r
-        {\r
-            Info.Attributes.Unmovable = 1;\r
-            Info.Attributes.Process = 0;\r
-        }\r
-\r
-        if (Info.Attributes.Process == 1)\r
-            Info.Attributes.Process = ShouldProcess (Info.Attributes) ? 1 : 0;\r
-\r
-        // Run the user-defined callback function\r
-        CallbackResult = Callback (Info, Handle, UserData);\r
-\r
-        if (Handle != INVALID_HANDLE_VALUE)\r
-            CloseHandle (Handle);\r
-\r
-        if (!CallbackResult)\r
-            break;\r
-\r
-        // If directory, perform recursion\r
-        if (Info.Attributes.Directory == 1)\r
-        {\r
-            wstring Dir;\r
-\r
-            Dir = GetDBDir (Info.DirIndice);\r
-            Dir += Info.Name;\r
-            Dir += L"\\";\r
-\r
-            Directories.push_back (Dir);\r
-            ScanDirectory (Dir, Callback, UserData);\r
-        }\r
-\r
-    } while (FindNextFileW (FindHandle, &FindData) == TRUE);\r
-\r
-    FindClose (FindHandle);\r
-    return (false);\r
-}\r
-\r
-\r
-bool DriveVolume::ShouldProcess (FileAttr Attr)\r
-{\r
-    if (Attr.Offline == 1  ||  Attr.Reparse == 1  ||  Attr.Temporary == 1)\r
-    {\r
-        return (false);\r
-    }\r
-\r
-    return (true);\r
-}\r
-\r
-\r
-// Gets info on a file and returns a valid handle for read/write access\r
-// Name, FullName, Clusters, Attributes, and Size should already be filled out.\r
-// This function fills in the Fragments vector\r
-bool DriveVolume::GetClusterInfo (FileInfo &Info, HANDLE &HandleResult)\r
-{\r
-    BOOL     Result;\r
-    HANDLE   Handle;\r
-    wstring   FullName;\r
-    BY_HANDLE_FILE_INFORMATION FileInfo;\r
-\r
-    Info.Fragments.resize (0);\r
-\r
-    /*\r
-    if (Info.Attributes.Directory == 1)\r
-        return (false);\r
-    */\r
-\r
-    FullName = GetDBDir (Info.DirIndice) + Info.Name;\r
-\r
-    Handle = CreateFileW\r
-    (\r
-        FullName.c_str(),\r
-        0, //GENERIC_READ,\r
-        FILE_SHARE_READ,\r
-        NULL,\r
-        OPEN_EXISTING,\r
-        (Info.Attributes.Directory == 1) ? FILE_FLAG_BACKUP_SEMANTICS : 0,\r
-        NULL\r
-    );\r
-\r
-    if (Handle == INVALID_HANDLE_VALUE)\r
-    {\r
-           LPVOID lpMsgBuf;\r
-\r
-           FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,\r
-                                           NULL, GetLastError(),\r
-                                           MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\r
-                                           (LPTSTR) &lpMsgBuf, 0, NULL );\r
-\r
-\r
-        Info.Attributes.AccessDenied = 1;\r
-           LocalFree( lpMsgBuf );\r
-        return (false);\r
-    }\r
-\r
-    ZeroMemory (&FileInfo, sizeof (FileInfo));\r
-    Result = GetFileInformationByHandle (Handle, &FileInfo);\r
-\r
-    if (Result == FALSE)\r
-    {\r
-        Info.Attributes.AccessDenied = 1;\r
-        wprintf (L"GetFileInformationByHandle ('%s%s') failed\n", GetDBDir (Info.DirIndice).c_str(),\r
-            Info.Name.c_str());\r
-\r
-        CloseHandle (Handle);\r
-        return (false);\r
-    }\r
-\r
-    // Get cluster allocation information\r
-    STARTING_VCN_INPUT_BUFFER  StartingVCN;\r
-    RETRIEVAL_POINTERS_BUFFER *Retrieval;\r
-    uint64                     RetSize;\r
-    uint64                     Extents;\r
-    DWORD                      BytesReturned;\r
-\r
-    // Grab info one extent at a time, until it's done grabbing all the extent data\r
-    // Yeah, well it doesn't give us a way to ask L"how many extents?" that I know of ...\r
-    // btw, the Extents variable tends to only reflect memory usage, so when we have\r
-    // all the extents we look at the structure Win32 gives us for the REAL count!\r
-    Extents = 10;\r
-    Retrieval = NULL;\r
-    RetSize = 0;\r
-    StartingVCN.StartingVcn.QuadPart = 0;\r
-\r
-    do\r
-    {\r
-        Extents *= 2;\r
-        RetSize = sizeof (RETRIEVAL_POINTERS_BUFFER) + ((Extents - 1) * sizeof (LARGE_INTEGER) * 2);\r
-\r
-        if (Retrieval != NULL)\r
-            Retrieval = (RETRIEVAL_POINTERS_BUFFER *) realloc (Retrieval, RetSize);\r
-        else\r
-            Retrieval = (RETRIEVAL_POINTERS_BUFFER *) malloc (RetSize);\r
-\r
-        Result = DeviceIoControl\r
-        (\r
-            Handle,\r
-            FSCTL_GET_RETRIEVAL_POINTERS,\r
-            &StartingVCN,\r
-            sizeof (StartingVCN),\r
-            Retrieval,\r
-            RetSize,\r
-            &BytesReturned,\r
-            NULL\r
-        );\r
-\r
-        if (Result == FALSE)\r
-        {\r
-            if (GetLastError() != ERROR_MORE_DATA)\r
-            {\r
-                Info.Clusters = 0;\r
-                Info.Attributes.AccessDenied = 1;\r
-                Info.Attributes.Process = 0;\r
-                Info.Fragments.clear ();\r
-                CloseHandle (Handle);\r
-                free (Retrieval);\r
-\r
-                return (false);\r
-            }\r
-\r
-            Extents++;\r
-        }\r
-    } while (Result == FALSE);\r
-\r
-    // Readjust extents, as it only reflects how much memory was allocated and may not\r
-    // be accurate\r
-    Extents = Retrieval->ExtentCount;\r
-\r
-    // Ok, we have the info. Now translate it. hrmrmr\r
-    \r
-    Info.Fragments.clear ();\r
-    for (uint64 i = 0; i < Extents; i++)\r
-    {\r
-        Extent Add;\r
-\r
-        Add.StartLCN = Retrieval->Extents[i].Lcn.QuadPart;\r
-        if (i != 0)\r
-            Add.Length = Retrieval->Extents[i].NextVcn.QuadPart - Retrieval->Extents[i - 1].NextVcn.QuadPart;\r
-        else\r
-            Add.Length = Retrieval->Extents[i].NextVcn.QuadPart - Retrieval->StartingVcn.QuadPart;\r
-\r
-        Info.Fragments.push_back (Add);\r
-    }\r
-\r
-    free (Retrieval);\r
-    HandleResult = Handle;\r
-    return (true);\r
-}\r
-\r
-\r
-bool DriveVolume::FindFreeRange (uint64 StartLCN, uint64 ReqLength, uint64 &LCNResult)\r
-{\r
-    uint64 Max;\r
-    uint64 i;\r
-    uint64 j;\r
-\r
-    // Make sure we don't spill over our array\r
-    Max = VolInfo.ClusterCount - ReqLength;\r
-\r
-    for (i = StartLCN; i < Max; i++)\r
-    {\r
-        bool Found = true;\r
-\r
-        // First check the first cluster\r
-        if (IsClusterUsed (i))\r
-            Found = false;\r
-        else\r
-        // THen check the last cluster\r
-        if (IsClusterUsed (i + ReqLength - 1))\r
-            Found = false;\r
-        else\r
-        // Check the whole darn range.\r
-        for (j = (i + 1); j < (i + ReqLength - 2); j++)\r
-        {\r
-            if (IsClusterUsed (j) == true)\r
-            {\r
-                Found = false;\r
-                break;\r
-            }\r
-        }\r
-\r
-        if (!Found)\r
-            continue;\r
-        else\r
-        {\r
-            LCNResult = i;\r
-            return (true);\r
-        }\r
-    }\r
-\r
-    return (false);\r
-}\r
-\r
-\r
-// btw we have to move each fragment of the file, as per the Win32 API\r
-bool DriveVolume::MoveFileDumb (uint32 FileIndice, uint64 NewLCN)\r
-{\r
-    bool ReturnVal = false;\r
-    FileInfo Info;\r
-    HANDLE FileHandle;\r
-    wstring FullName;\r
-    MOVE_FILE_DATA MoveData;\r
-    uint64 CurrentLCN;\r
-    uint64 CurrentVCN;\r
-\r
-    // Set up variables\r
-    Info = GetDBFile (FileIndice);\r
-    FullName = GetDBDir (Info.DirIndice);\r
-    FullName += Info.Name;\r
-    CurrentLCN = NewLCN;\r
-    CurrentVCN = 0;\r
-\r
-    /*\r
-    if (Info.Attributes.Directory == 1)\r
-    {\r
-        //\r
-    }\r
-    */\r
-\r
-    // Open file\r
-    FileHandle = CreateFileW\r
-    (\r
-        FullName.c_str (),\r
-        GENERIC_READ,\r
-        FILE_SHARE_READ,\r
-        NULL,\r
-        OPEN_EXISTING,\r
-        (Info.Attributes.Directory == 1) ? FILE_FLAG_BACKUP_SEMANTICS : 0,\r
-        NULL\r
-    );\r
-\r
-    if (FileHandle == INVALID_HANDLE_VALUE)\r
-    {\r
-        //\r
-           LPVOID lpMsgBuf;\r
-\r
-           FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,\r
-                                           NULL, GetLastError(),\r
-                                           MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\r
-                                           (LPTSTR) &lpMsgBuf, 0, NULL );\r
-\r
-\r
-           LocalFree (lpMsgBuf);\r
-        //\r
-\r
-        ReturnVal = false;\r
-    }\r
-    else\r
-    {\r
-        ReturnVal = true; // innocent until proven guilty ...\r
-\r
-        for (uint32 i = 0; i < Info.Fragments.size(); i++)\r
-        {\r
-            BOOL Result;\r
-            DWORD BytesReturned;\r
-\r
-            //wprintf (L"%3u", i);\r
-\r
-            MoveData.ClusterCount = Info.Fragments[i].Length;\r
-            MoveData.StartingLcn.QuadPart = CurrentLCN;\r
-            MoveData.StartingVcn.QuadPart = CurrentVCN;\r
-\r
-            MoveData.FileHandle = FileHandle;\r
-\r
-            /*\r
-            wprintf (L"\n");\r
-            wprintf (L"StartLCN: %I64u\n", MoveData.StartingLcn.QuadPart);\r
-            wprintf (L"StartVCN: %I64u\n", MoveData.StartingVcn.QuadPart);\r
-            wprintf (L"Clusters: %u (%I64u-%I64u --> %I64u-%I64u)\n", MoveData.ClusterCount,\r
-                Info.Fragments[i].StartLCN,\r
-                Info.Fragments[i].StartLCN + MoveData.ClusterCount,\r
-                MoveData.StartingLcn.QuadPart,\r
-                MoveData.StartingLcn.QuadPart + MoveData.ClusterCount - 1);\r
-            wprintf (L"\n");\r
-            */\r
-\r
-            Result = DeviceIoControl\r
-            (\r
-                Handle,\r
-                FSCTL_MOVE_FILE,\r
-                &MoveData,\r
-                sizeof (MoveData),\r
-                NULL,\r
-                0,\r
-                &BytesReturned,\r
-                NULL\r
-            );\r
-\r
-            //wprintf (L"\b\b\b");\r
-\r
-            if (Result == FALSE)\r
-            {\r
-                //\r
-                   LPVOID lpMsgBuf;\r
-\r
-                   FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,\r
-                                                   NULL, GetLastError(),\r
-                                                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\r
-                                                   (LPTSTR) &lpMsgBuf, 0, NULL );\r
-\r
-\r
-                   LocalFree( lpMsgBuf );\r
-                //\r
-\r
-                ReturnVal = false;\r
-                goto FinishUp;  // yeah, bite me\r
-            }\r
-\r
-            // Ok good. Now update our drive bitmap and file infos.\r
-            uint64 j;\r
-            for (j = 0;\r
-                 j < Info.Fragments[i].Length;\r
-                 j++)\r
-            {\r
-                SetClusterUsed (Info.Fragments[i].StartLCN + j, false);\r
-                SetClusterUsed (CurrentLCN + j, true);\r
-                //BitmapDetail[Info.Fragments[i].StartLCN + j].Allocated = false;\r
-                //BitmapDetail[CurrentLCN + j].Allocated = true;\r
-            }\r
-\r
-            CurrentLCN += Info.Fragments[i].Length;\r
-            CurrentVCN += Info.Fragments[i].Length;\r
-        }\r
-\r
-        // Update file info either way\r
-    FinishUp:\r
-        CloseHandle (FileHandle);\r
-        FileHandle = INVALID_HANDLE_VALUE;\r
-        GetClusterInfo (Files[FileIndice], FileHandle);\r
-        CloseHandle (FileHandle);\r
-    }\r
-\r
-    return (ReturnVal);\r
-}\r
-\r
-\r