Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1348
  • Last Modified:

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

0
pushpop
Asked:
pushpop
1 Solution
 
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

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

Featured Post

[Webinar] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now