Link to home
Start Free TrialLog in
Avatar of pushpop
pushpop

asked on

ReadFile() problem

Hi,

I'm writing a win32 program which will display the contents of the master boot record of a disk.
However, I'm new to WIN32 and whenever i use the readFile command, it fails.

Below is my code, excuse the errors:

//filename: main.cpp
//function: draws the main program window
//author:  

#include <windows.h>
#include "Resource.h"
#include <iostream.h>

//---------------------------------------------------------------------------
HWND hWnd;
LRESULT CALLBACK DlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
void read_mbr();

char * drive = "\\\\.\\PhysicalDrive0";
char buffer[20];
HWND hWndJump;
HANDLE hfile;

//---------------------------------------------------------------------------
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                           LPSTR lpCmdLine, int nCmdShow)
{
      DialogBox(hInstance, MAKEINTRESOURCE(IDD_DLGFIRST),
                hWnd, reinterpret_cast<DLGPROC>(DlgProc));
      read_mbr();

      return FALSE;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{

      switch(Msg)
      {
      case WM_INITDIALOG:   //when the dialog box is instantiated..
      
      hfile = CreateFile(drive,GENERIC_READ,
                     FILE_SHARE_READ|FILE_SHARE_WRITE,
                     NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
                     NULL);
      if(hfile==INVALID_HANDLE_VALUE)
      {
            
            MessageBox(hWnd,"Error opening drive","Error!",MB_OK);
            return FALSE;
      }
   
      
      hWndJump = GetDlgItem(hWndDlg,IDJUMPINSTR);  /*Get text box handle*/

   
      if(ReadFile(hfile,buffer,20,NULL,NULL)==FALSE)  /*read first 20 bytes of MBR*/
      {
            
                  MessageBox(hWnd,"error reading file","Error!",MB_OK);
      }
      
      SetWindowText(hWndJump,buffer);
            return TRUE;

            case WM_COMMAND:      // command received?
            switch(wParam)
            {
                  case IDOK:        //finished
                  EndDialog(hWndDlg, 0);
                  return TRUE;
                  break;
            
                  case IDCANCEL:// i want out
                  EndDialog(hWndDlg, 0);
                  return TRUE;
                  break;

                  case IDABOUT:// about the program
                  MessageBox(hWndDlg, "BlackLight for Windows v 0.1\n"
                                                "Written By \n"
                                                "Compiled using MS Visual C++ 6.0\n"
                                                "Please note the developer offers no warranty\n"
                                                "implied or otherwise as regards the use of this program\n"
                                                "This program was written in the hope of it being useful\n"
                                                "but there are NO guarantees offered in terms of performance\n"
                                                "safety, reliability or otherwise",
                                                "About BlackLight", MB_OK);
                  
                  return TRUE;
                  break;
            }
      }

      return FALSE;
}

Avatar of ikework
ikework
Flag of Germany image

retreive the error with GetLastError()

look at this:

http://www.microsoft.com/whdc/driver/tips/OverlappedIo.mspx

ike
Avatar of pushpop
pushpop

ASKER

Thanks,

Unfortunately, as i said I'm new to this. It all seems unnecessarily complicated to be honest; i was able to accomplish this with 7 lines of code in C, and yet, with WIN32, it requires non-intuitive functions with a ludicrous amount of parameters, all of which are microsoft proprietary datatypes. You cant just call GetLastError(), you need to parse the output using another function, FormatMessage. I thought APIs were supposed to make life easier as opposed to harder??
FYI:
>>#include <iostream.h>

iostream.h is not part of the C++ standard, and should not be used in any new code.  It's not portable, and will not compile on modern compilers like VC++ 7.x and 8.0.

You should use the extensionless version which is part of the C++ standard, and it is portable.
#include <iostream>
using namespace std;

Some STL *.h libraries have bugs in them, because these libraries are no longer being maintained by the compiler manufature.
Avatar of pushpop

ASKER

Update: GetLastError() is returning error "the parameter is incorrect" - anybody know what could cause this

rgds
pushpop
Two things:

You have to specify LPDWORD bytesRead and you have to read at least the sector size (512 bytes for example)

This works for me:

...
if(ReadFile(hDevice, buffer, 512, &dwBytesRead, NULL)==FALSE)  /*read first 20 bytes of MBR*/
...

Dont forge to increase your buffer size.

Bernd
Avatar of pushpop

ASKER

Bernd: Thanks for that! I tried reading data in sector-sized chunks, but it didn't work, but I didn't specify LPDWORD bytesRead, so i'll try that and let you know how I'm getting on. I'm using Visual C++ 6.0, if that makes a difference, thougl I wouldnt expect it to!

Thanks to everyone for your help so far :-)

rgds

pushpop
Avatar of pushpop

ASKER

Ok, I got that working, but now I'm having another problem. The buffer is being prematurely truncated, and I think it's because there are 0-value bytes that the program is mistaking for null-terminators. Could anyone offer any help?

here is the code:

//filename: main.cpp
//function: draws the main program window
//author:  

#include <windows.h>
#include "Resource.h"
#include <cstring>                                                //header file which contains message values
#include <iostream>
#include <cstring>
using namespace std;
#include <string.h>

//---------------------------------------------------------------------------
HWND hWnd;
LRESULT CALLBACK DlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK AboutProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam);

char * drive ="\\\\.\\PhysicalDrive0";
char * temp;
BYTE buffer[513];
HWND hWndJump;
HWND hWndEdit;
HANDLE hfile;
LPVOID lpMsgBuf;
DWORD bytesRead;
HINSTANCE hInst;
//---------------------------------------------------------------------------
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                           LPSTR lpCmdLine, int nCmdShow)
{
      DialogBox(hInstance, MAKEINTRESOURCE(IDD_DLGFIRST),                              //make the dialog
                hWnd, reinterpret_cast<DLGPROC>(DlgProc));



      hInst = hInstance;
      return FALSE;

      
}
//---------------------------------------------------------------------------
LRESULT CALLBACK AboutProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
            HWND textBoxHandle = GetDlgItem(hWndDlg,IDD_ABOUTTEXT);
            char * aboutMsg =   "Copyright \251 2006 Eric Chubb\n\n"
            "THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT "
            "WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, "
            "INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF "
            "MERCHANTABILITY, FITNESS FOR A PARTICULAR "
            "PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE "
            "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES "
            "OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, "
            "TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN "
            "CONNECTION WITH THE SOFTWARE OR THE USE OR "
            "OTHER DEALINGS IN THE SOFTWARE.\n\n"
            "Version history: 0.1 - Basic disk analysis implemented - "
            "Master boot record only";
      switch(Msg)
            {
                  case WM_INITDIALOG:      
                        
                        SetWindowText(textBoxHandle,aboutMsg);
                        return TRUE;
                  
                  case WM_COMMAND:
                        
                        switch(wParam)
                        {
                              case IDC_OKBUTT:      
                        
                              EndDialog(hWndDlg,0);
                              return TRUE;
                        }

                        
            }
            return FALSE;
                  
}



LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
      hWndEdit = GetDlgItem(hWndDlg,IDC_EDIT1);
      switch(Msg)
      {
            case WM_INITDIALOG:      
                              
                              //when the dialog box is instantiated..

                  return TRUE;
                  
            
                  
                  case WM_COMMAND:      // command received?
                  
                  
                        switch(wParam)
                        {
                              case IDD_ABOUTBUTTON:// about the program
                  
                            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUT),
                              hWnd, (DLGPROC)AboutProc);
                                                
                                            return FALSE;
                              
                        case IDOK:       
                              hfile = CreateFile(drive,GENERIC_READ,                   //open drive
                     FILE_SHARE_READ|FILE_SHARE_WRITE,
                     NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
                     NULL);
      
      
                  if(hfile==INVALID_HANDLE_VALUE)                                          //if the device cant be mounted
                                                                                                      //print why
                  {
                  
                              FormatMessage(                                                      //woeful formatting prerequisite
                              FORMAT_MESSAGE_ALLOCATE_BUFFER |                        //converts the DWORD error value
                                                                                                      //returned by GetLastError()
                            FORMAT_MESSAGE_FROM_SYSTEM |                              //into a string and prints it
                              FORMAT_MESSAGE_IGNORE_INSERTS,
                              NULL,
                              GetLastError(),
                              0, // Default language
                              (LPTSTR) &lpMsgBuf,
                              0,
                              NULL );
                              MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error opening device", MB_OK | MB_ICONWARNING );

                  
                        return FALSE;
                        break;
                        
                        
                  }
   
            
                  hWndJump = GetDlgItem(hWndDlg,IDJUMPINSTR);                        //Get text box handle

                  if(ReadFile(hfile,buffer,512,&bytesRead,NULL)==FALSE)                        //read first 512 bytes of MBR or say whats wrong
                  {
                              FormatMessage(
                              FORMAT_MESSAGE_ALLOCATE_BUFFER |
                            FORMAT_MESSAGE_FROM_SYSTEM |
                              FORMAT_MESSAGE_IGNORE_INSERTS,
                              NULL,
                              GetLastError(),
                              0, // Default language
                              (LPTSTR) &lpMsgBuf,
                              0,
                              NULL );
                              MessageBox( NULL, (LPCSTR)lpMsgBuf, "Disk read error", MB_OK | MB_ICONWARNING );
                              SetWindowText(hWndJump,"device error");
                              return FALSE;
                        
                  }
      
      
                  //SetWindowText(hWndJump,buffer);
                  temp = reinterpret_cast<TCHAR *>(buffer);
                  SetWindowText(hWndEdit,temp);
                  return TRUE;
            
                  
            
                  case IDCANCEL:// i want out
                        EndDialog(hWndDlg, 0);
                        return TRUE;

                        break;
                        

                  
            }
      }
      return FALSE;

      
}


//---------------------------------------------------------------------------
ASKER CERTIFIED SOLUTION
Avatar of bholz
bholz

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of pushpop

ASKER

Ok thanks I'll try it this evening and let you know how I got on
Avatar of pushpop

ASKER

Thanks for your answer, it worked a treat!