0

As the title suggests, I'm doing some low-level volume access (as close to C code as possible) to make a disk clone program, I want to set all the free clusters to zero to use a simple compression and keep the size small.

I've been beating my head off a wall forever trying to figure out why I can't get the FSCTL_GET_VOLUME_BITMAP function working properly... so if possible please don't link me to any external reading as I've probably already been there and its either been C#, invalid links, or has no explanation I am looking for.

I want to understand the buffer itself more than i need the actual code.

The simplest way I can ask is what is the proper way to read from an array with a length of [1] in C/C++ like the one used by VOLUME_BITMAP_BUFFER?

The only way I can even assign anything to it is by recreating it with my own huge buffer and I still end up with errors, even after locking the volume in Recovery mode. I do get all needed permissions to access the raw disk just on a side note.

I know I'm likely missing some fundamental basic in C++ that would allow me to read from the memory its stored in, but I just can't figure it out without getting errors.

In case I happen to be looping through the bytes wrong which is causing my error, I added how I was doing it...although that still leaves me with the Buffer question.

I know you can call multiple times, but I have to assume its not 8 bytes at a time.

Something like this (pardon my code..I typed this on my phone so it likely has errors)...I tried adding any relevant cause of failure in case, but the buffer is the real question.

#define BYTE_MASK = 0x80;
#define BITS_PER_BYTE = 8;

void function foo() {
const int BUFFER_SIZE = 268435456;

struct {
    LARGE_INTEGER StartingLcn;
    LARGE_INTEGER BitmapSize;
    BYTE Buffer[BUFF_SIZE];
} volBuff;
// I want to use VOLUME_BITMAP_BUFFER

/* Part of a larger loop checking for errors and more data

BYTE Mask = 1;

BOOL b = DeviceIoControl(vol, FSCTL_GET-VOLUME_BITMAP, &lcnStart, sizeof(STARTING_LCN_INPUT_BUFFER), &volBuff, sizeof(volBuff), &dwRet);

*/

for (x = 0; x < (bmpLen / BITS_PER_BYTE;) {
   if ((volBuff.Buffer[x] & Mask) != 0) {
      NotFree++;
   } else {
      FreeSpc++;
   }
   // I did try not dividing the size

   if (Mask == BYTE_MASK) {
      Mask = 1;
      x++;
   } else {
      Mask = (Mask << 1);
   }

}

return;

}

I've literally put an entire project on hold for I don't even know how long just being stubborn at this point...and I can't find any answer that actually explains the buffer, forget the rest of the process.

If someone wants to be more thorough I won't complain after all my attempts, but the buffer is driving me crazy at this point.

Any help would be greatly appreciated.

AleXelton
  • 767
  • 5
  • 27
BrainOverflow
  • 34
  • 1
  • 1
  • 7
  • _"...array with a length of [1]..."_ there is no way in Standard C++ of accessing the additional bytes. You can either: (a) pray that your compiler can do this (via an extension) or (b) write a `C` module (where this is well defined) that you can call from C++. – Richard Critten Jun 13 '21 at 14:44
  • I know I asked for no external links but do you possibly have one that would explain how I would go about implementing such a module? I never expected the API to use something there was no way to access via memory in some form or another. Are you saying the way I wrote my own buffer was actually one of the only methods? Or would my buffer still be returning bad information which seems to be the situation? – BrainOverflow Jun 15 '21 at 03:25
  • Update: The thought just occurred to me that I may not have been able to completely lock the disk while Windows was running (In WinRE it can't even tell there is a disk), or possibly by overwriting the information myself rather than using the MOVE_FILE device control with it, the information is being shifted as I'm writing causing errors. I am technically doing this in a .C file in Visual C++, using almost all C functions and defining everything myself if that makes a difference. Perhaps how i was able to use my own array instead. – BrainOverflow Jun 16 '21 at 12:01

1 Answers1

0

I can safely assume the one answer I was given

"...array with a length of [1]..." there is no way in Standard C++ of accessing the additional bytes. You can either: (a) pray that your compiler can do this (via an extension) or (b) write a C module (where this is well defined) that you can call from C++. - Richard Critton"

Was as correct of an answer I can expect after my extensive attempts to make this work any other way, especially since I was only able to make my own array work using standard C and not C++ directly.

I wanted to put a close on this since my computer is out of use for a bit.

If the problem continues after I dig through some examples for defragmenting in C that I FINALLY came across I'll ask a more direct question with full code to support it.

That answer was enough to remove the wall I had hit and get me thinking again. I thank you for that.

BrainOverflow
  • 34
  • 1
  • 1
  • 7