Hi, i think i have a pretty random question here and something i thought i would be able to do but unfortunately im struggling. I have an example I have found on the msdn website. It works fine however i want to move all the code so that it just works in main without having the passing between the functions. I will paste the example below. I dont expect anyone to do it for me but i would appreciate advice on how to go about this. I know it mite sound strange doing this and not the best way to go about things but i need to attempt this. I think by doing this it will imporve my coding knowledge

* The code of interest is in the subroutine GetDriveGeometry. The 
   code in main shows how to interpret the results of the call. */

#include <windows.h>
#include <winioctl.h>
#include <stdio.h>

BOOL GetDriveGeometry(DISK_GEOMETRY *pdg)
{
  HANDLE hDevice;               // handle to the drive to be examined 
  BOOL bResult;                 // results flag
  DWORD junk;                   // discard results

  hDevice = CreateFile(TEXT("\\\\.\\PhysicalDrive0"),  // drive 
                    0,                // no access to the drive
                    FILE_SHARE_READ | // share mode
                    FILE_SHARE_WRITE, 
                    NULL,             // default security attributes
                    OPEN_EXISTING,    // disposition
                    0,                // file attributes
                    NULL);            // do not copy file attributes

  if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
  {
    return (FALSE);
  }

  bResult = DeviceIoControl(hDevice,  // device to be queried
      IOCTL_DISK_GET_DRIVE_GEOMETRY,  // operation to perform
                             NULL, 0, // no input buffer
                            pdg, sizeof(*pdg),     // output buffer
                            &junk,                 // # bytes returned
                            (LPOVERLAPPED) NULL);  // synchronous I/O

  CloseHandle(hDevice);

  return (bResult);
}

int main(int argc, char *argv[])
{
  DISK_GEOMETRY pdg;            // disk drive geometry structure
  BOOL bResult;                 // generic results flag
  ULONGLONG DiskSize;           // size of the drive, in bytes

  bResult = GetDriveGeometry (&pdg);

  if (bResult) 
  {
    printf("Cylinders = %I64d\n", pdg.Cylinders);
    printf("Tracks/cylinder = %ld\n", (ULONG) pdg.TracksPerCylinder);
    printf("Sectors/track = %ld\n", (ULONG) pdg.SectorsPerTrack);
    printf("Bytes/sector = %ld\n", (ULONG) pdg.BytesPerSector);

    DiskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder *
      (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;
    printf("Disk size = %I64d (Bytes) = %I64d (Gb)\n", DiskSize,
           DiskSize / (1024 * 1024 * 1024));
  } 
  else 
  {
    printf ("GetDriveGeometry failed. Error %ld.\n", GetLastError ());
  }

  return ((int)bResult);
}

thankyou

Recommended Answers

All 9 Replies

Member Avatar for iamthwee

>I think by doing this it will imporve my coding knowledge

I can tell you right now, that is nonsense.

yer i thought people would think doing this would be stupid. I thought the way this would work would be removing the GetDriveGeometery function and define everything in there, in main. Then if i made sure the code processed in a logical order then bingo! but this did not work. I thought the whole idea of a function in partiular this case is to do the processing in there then pass everything back to main to print out. I know its not the proper coding practice but I just wanted to do it all in main

This trivial excersise (most likely it's a classic monkey job) will never improve your coding skill. I'm absolutely convinced of this.

its not a "Monkey Job" whatever that is. I wanted to try and place this function into a simple GUI so that when someone presses a button it would show the disk information. Im pretty new to the GUI stuff so when i paste the example into the button function in borland builder

void __fastcall TForm1::Button1Click(TObject *Sender)
{



HANDLE hDevice;               // handle to the drive to be examined
  BOOL bResult;                 // results flag
  DWORD junk;                   // discard results

  hDevice = CreateFile(TEXT("\\\\.\\PhysicalDrive0"),  // drive
                    0,                // no access to the drive
                    FILE_SHARE_READ | // share mode
                    FILE_SHARE_WRITE,
                    NULL,             // default security attributes
                    OPEN_EXISTING,    // disposition
                    0,                // file attributes
                    NULL);            // do not copy file attributes

  if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
  {
  
  }




DISK_GEOMETRY pdg;
ULONGLONG DiskSize;

  bResult = DeviceIoControl(hDevice,  // device to be queried
      IOCTL_DISK_GET_DRIVE_GEOMETRY,  // operation to perform
                             NULL, 0, // no input buffer
                            pdg, sizeof(pdg),     // output buffer
                            &junk,                 // # bytes returned
                            (LPOVERLAPPED) NULL);  // synchronous I/O



    printf("Cylinders = %I64d\n", pdg.Cylinders);
    printf("Tracks/cylinder = %ld\n", (ULONG) pdg.TracksPerCylinder);
    printf("Sectors/track = %ld\n", (ULONG) pdg.SectorsPerTrack);
    printf("Bytes/sector = %ld\n", (ULONG) pdg.BytesPerSector);

    DiskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder *
      (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;
    printf("Disk size = %I64d (Bytes) = %I64d (Gb)\n", DiskSize,
           DiskSize / (1024 * 1024 * 1024));







}

to execute the code when the user presses it, it throws up loads of errors. I think this is mainly due to the fact of how main and the function are passing variables in the example. If i just had the example in the simplistic of forms, ie just all happening in main i think it might just work in the button component of my GUI. Again i didnt ask for you to do it only advice on how to. If i am wrong and there is another way around this then i am certainly open for suggestions!

Alot of errors i seem to involve the DISK_GEOMETRY but they seemed to dissapear with a bit of tinkering with the 'pdg' variable. My last 2 errors now involves the (LPOVERLAPPED) NULL) line and Cannot convert DISK_GEOMETRY to void.

You need to pass in the address of the DISK_GEOMETRY struct, not the struct itself.

Hi, thank you for your quick reply. Im not sure what you mean by passing the address of the structure, and not the struct itself?

I thought i was by passing it the 'pdg'?

sorry i bet im sounding a bit stupid there

edit: - do you me prefixing it with the '&'? Ive tried pdg, sizeof(&pdg) but still no joy

How Borland C++ Builder interfered with function call in a buttom function or wherever else?

sorry im just not following totally. Can DISK_GEOMETRY not just be called by

DISK_GEOMETRY jdg;

striaght in the code for the button without placing it in a seperate function and calling that? This is the problem I had in the first place as i cant figure out the way borland uses function in the button operator so i just wanted to write the code without the use of functions and just throw it all in there. I know its not the proper way

Im not sure what you mean by passing the address of the structure, and not the struct itself?

You are missing ...

bResult = DeviceIoControl(hDevice,  // device to be queried
      IOCTL_DISK_GET_DRIVE_GEOMETRY,  // operation to perform
                             NULL, 0, // no input buffer
                            & pdg, sizeof(pdg),     // output buffer
                            &junk,                 // # bytes returned
                            (LPOVERLAPPED) NULL);  // synchronous I/O
commented: thank you for your help +1
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.