Exemplo n.º 1
0
        public void DrawBlocks()
        {
            if (!Volume.BitmapLoaded)
            {
                return;
            }

            //if (Drawing.IsDrawing)
            //    return;

            // Wait until width is not NaN
            while (double.IsNaN(GetWidth()))
            {
            }

            ThreadSafeWidth = GetWidth();

            int currentX = 0;
            int currentY = 0;

            uint BytesReturned = 0;

            uint BitmapSize = (65536 + 2 * sizeof(ulong));

            int err;

            ulong currLcn       = 0;
            ulong?lastLcn       = 0;
            ulong lastCluster   = 0;
            ulong?cluster       = null;
            ulong?cluster2      = null;
            ulong clusterCount  = 0;
            ulong clusterCount2 = 0;
            ulong numFree       = 0;
            ulong numFree2      = 0;
            ulong numFree3      = 0;

            int[] BitShift = { 1, 2, 4, 8, 16, 32, 64, 128 };

            ulong Max = Utils.Min(Volume.PartInfo.ClusterCount, 8 * 65536);

            do
            {
                if (_cancellationTokenSource.IsCancellationRequested)
                {
                    break;
                }

                GCHandle handle        = GCHandle.Alloc(currLcn, GCHandleType.Pinned);
                var      CurrentLCNPtr = handle.AddrOfPinnedObject();

                var pDest = Marshal.AllocHGlobal((int)BitmapSize);

                PInvoke.DeviceIoControl(
                    Volume.Handle,
                    PInvoke.FSConstants.FSCTL_GET_VOLUME_BITMAP,
                    CurrentLCNPtr,
                    (uint)Marshal.SizeOf(currLcn),
                    pDest,
                    BitmapSize,
                    ref BytesReturned,
                    IntPtr.Zero);

                err = Marshal.GetLastWin32Error();

                if (err != PInvoke.ERROR_MORE_DATA && err != PInvoke.ERROR_HANDLE_EOF)
                {
                    break;
                }

                PInvoke.VOLUME_BITMAP_BUFFER BitmapBuffer = new PInvoke.VOLUME_BITMAP_BUFFER(pDest, (int)BitmapSize);

                ulong i;
                for (i = 0; i < Max; i++)
                {
                    if (_cancellationTokenSource.IsCancellationRequested)
                    {
                        break;
                    }

                    if ((BitmapBuffer.Buffer[i / 8] & BitShift[i % 8]) > 0)
                    {
                        // Cluster is used
                        if (cluster.HasValue)
                        {
                            if ((lastLcn.HasValue) && cluster.Value == lastLcn.Value)
                            {
                                lastLcn = null;
                            }
                            else
                            {
                                numFree2 += numFree;
                                //cFreeSpaceGaps++;
                                if (BlockSize == 1)
                                {
                                    DrawBlocks(cluster2.Value, cluster2.Value + numFree2, 0xFFFFFF);
                                }

                                lastCluster   = cluster2.Value + numFree2;
                                lastLcn       = cluster;
                                numFree       = 0;
                                numFree2      = 0;
                                clusterCount2 = 0;
                                cluster       = null;
                                cluster2      = null;
                            }
                        }
                    }
                    else
                    {
                        // Cluster is free
                        if (!cluster.HasValue)
                        {
                            cluster = currLcn + i;

                            if (BlockSize == 1)
                            {
                                DrawBlocks(lastCluster, cluster.Value, ColFile);
                            }

                            cluster2 = cluster;

                            numFree = 1;
                            numFree3++;
                        }
                        else
                        {
                            numFree++;
                            numFree3++;
                        }
                    }

                    clusterCount++;

                    if (clusterCount == clustersPerBlock)
                    {
                        clusterCount2 += clustersPerBlock;
                    }

                    // prevent drawing as one big block
                    if (clusterCount2 >= clustersPerLine && BlockSize == 1)
                    {
                        if (cluster2.HasValue && numFree > clustersPerLine)
                        {
                            DrawBlocks(cluster2.Value, cluster2.Value + numFree, ColWhite);
                        }
                        else if (numFree == 0)
                        {
                            DrawBlocks(currLcn + i - clustersPerLine, currLcn + i, ColFile);
                        }
                        clusterCount2 = 0;
                    }

                    // draw the shit
                    if (clusterCount >= clustersPerBlock)
                    {
                        if (BlockSize != 1)
                        {
                            DrawNoBlockBound(currentX, currentY); // just make sure all is new
                            if (numFree3 >= clustersPerBlock)
                            {
                                DrawBlockAt(currentX, currentY, ColWhite);
                            }
                            else if (numFree3 == 0)
                            {
                                DrawBlockAt(currentX, currentY, ColFile);
                            }
                            else if (numFree3 >= (clustersPerBlock / colorSteps) * 4)
                            {
                                DrawBlockAt(currentX, currentY, ColF5);
                            }
                            else if (numFree3 >= (clustersPerBlock / colorSteps) * 3)
                            {
                                DrawBlockAt(currentX, currentY, ColF4);
                            }
                            else if (numFree3 >= (clustersPerBlock / colorSteps) * 2)
                            {
                                DrawBlockAt(currentX, currentY, ColF3);
                            }
                            else if (numFree3 >= (clustersPerBlock / colorSteps))
                            {
                                DrawBlockAt(currentX, currentY, ColF2);
                            }
                            else
                            {
                                DrawBlockAt(currentX, currentY, ColF1);
                            }

                            /*
                             * else
                             *  for (j=colorsteps-1; j>0; j--)
                             *      if (numFree3 >= (int)(clustersPB/colorsteps)*j || j==1) {
                             *          DrawBlockAt(x, y, LighterVal(ColFile, 256/(colorsteps-j+1)-(colorsteps-j)  ));
                             *          break;
                             *      }
                             */

                            currentX += BlockSize;
                            if (currentX > (int)(ThreadSafeWidth - BlockSize))
                            {
                                // move to next y-line
                                currentX  = 0;
                                currentY += BlockSize;
                            }
                            numFree3 = 0;
                        }

                        clusterCount = 0;
                    }
                } // for all clusters in this pair

                // Move to the next block
                currLcn = BitmapBuffer.StartingLcn.QuadPart + i;
            } while ((err == PInvoke.ERROR_MORE_DATA) && (currLcn < Volume.PartInfo.ClusterCount));

            if (clusterCount > 0)
            {
                //cFreeSpaceGaps++;

                // draw last cluster
                if (BlockSize > 1)
                {
                    DrawNoBlockBound(currentX, currentY);
                    if (numFree3 == clusterCount)
                    {
                        DrawBlockAt(currentX, currentY, ColWhite);
                    }
                    else
                    {
                        if (numFree3 > 0)
                        {
                            uint col = Utils.LighterVal(ColFile, (int)(((float)((int)(clustersPerBlock - (clustersPerBlock - numFree3))) / (int)clustersPerBlock) * 255.0));
                            DrawBlockAt(currentX, currentY, col);
                        }
                        else
                        {
                            DrawBlockAt(currentX, currentY, ColFile);
                        }
                    }
                }
                else
                {
                    if (cluster2.HasValue)
                    {
                        if (numFree > 0)
                        {
                            DrawBlocks(cluster2.Value, cluster2.Value + numFree, ColWhite);
                        }
                        else
                        {
                            DrawBlocks(lastCluster, currLcn, ColFile);
                        }
                    }
                }
            }

            // Update window
            if (Dispatcher.Thread != Thread.CurrentThread)
            {
                Dispatcher.Invoke(() => draw.InvalidateVisual());
            }
            else
            {
                draw.InvalidateVisual();
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Gets drive bitmap
        /// </summary>
        /// <returns></returns>
        public bool GetBitmap()
        {
            Int64 StartingLCN   = 0;
            uint  BytesReturned = 0;

            GCHandle handle         = GCHandle.Alloc(StartingLCN, GCHandleType.Pinned);
            var      StartingLCNPtr = handle.AddrOfPinnedObject();

            //BitmapSize = (uint)Marshal.SizeOf(typeof(PInvoke.VOLUME_BITMAP_BUFFER)) + 4;
            uint BitmapSize = 28;

            var pDest = Marshal.AllocHGlobal((int)BitmapSize);

            var Result = PInvoke.DeviceIoControl(
                Handle,
                PInvoke.FSConstants.FSCTL_GET_VOLUME_BITMAP,
                StartingLCNPtr,
                (uint)Marshal.SizeOf(StartingLCN),
                pDest,
                BitmapSize,
                ref BytesReturned,
                IntPtr.Zero);

            // Bad result?
            if (Result == false && Marshal.GetLastWin32Error() != PInvoke.ERROR_MORE_DATA)
            {
                Marshal.FreeHGlobal(pDest);
                return(false);
            }

            var Bitmap = new PInvoke.VOLUME_BITMAP_BUFFER(pDest, false);

            BitmapSize = (uint)Marshal.SizeOf(typeof(PInvoke.VOLUME_BITMAP_BUFFER)) + ((uint)Bitmap.BitmapSize.QuadPart / 8) + 1;
            pDest      = Marshal.ReAllocHGlobal(pDest, (IntPtr)BitmapSize);

            Result = PInvoke.DeviceIoControl(
                Handle,
                PInvoke.FSConstants.FSCTL_GET_VOLUME_BITMAP,
                StartingLCNPtr,
                (uint)Marshal.SizeOf(StartingLCN),
                pDest,
                BitmapSize,
                ref BytesReturned,
                IntPtr.Zero);

            if (Result == false)
            {
                Debug.WriteLine("Couldn't properly read volume bitmap");
                Marshal.FreeHGlobal(pDest);
                return(false);
            }

            Bitmap = new PInvoke.VOLUME_BITMAP_BUFFER(pDest, true);

/*
 *          BitmapSize = (uint)Marshal.SizeOf(typeof(PInvoke.VOLUME_BITMAP_BUFFER)) + ((uint)Bitmap.BitmapSize.QuadPart / 8) + 1;
 */

            PartInfo.ClusterCount = Bitmap.BitmapSize.QuadPart;

            BitmapDetail = Bitmap.Buffer;

            Marshal.FreeHGlobal(pDest);

            return(true);
        }