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;
}

pushpopAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ikeworkCommented:
retreive the error with GetLastError()

look at this:

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

ike
0
pushpopAuthor Commented:
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??
0
AxterCommented:
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.
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

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

rgds
pushpop
0
bholzCommented:
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
0
pushpopAuthor Commented:
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
0
pushpopAuthor Commented:
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;

      
}


//---------------------------------------------------------------------------
0
bholzCommented:
If you print out the data as string data, the NULL byte will of course truncate the string.

You may want to convert it to hex values or replace unprintable characters with dots for example...


for (i=0; i<bytesRead; i++)
{
  if (buffer[i] < 0x20)
    buffer[i] = '.';
}

buffer[bytesRead] = '\0'; // Make sure we can print out a truncated string.


0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
pushpopAuthor Commented:
Ok thanks I'll try it this evening and let you know how I got on
0
pushpopAuthor Commented:
Thanks for your answer, it worked a treat!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.