• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 371
  • Last Modified:

WIN32 char [] to hex issue

Hi all.

I'm writing an application to read the master boot record of a hard disk, using WIN32. This has proved problematic, but there is one issue that has me a bit confused. I am using the SetWindowText function to write the MBR values to an EditBox control. However, as this function only accepts cstrings it treats the values in the array as ascii values and displays the corresponding character. What I want it to do is display the ascii values themselves in hex, rather like WinHex or another hex editor. I have tried casting, strcpy, itoa etc etc. with no luck.

Could anyone shed some light on this issue?

Rgds

Eric
0
pushpop
Asked:
pushpop
  • 10
  • 10
1 Solution
 
pushpopAuthor Commented:
/*this is the program code - I didn't want to include it in the question as it would appear messy
 *all function and most variable declarations occur in the InSight.h header file, which is largely irrelevant to this question
 *so i didnt include it
 */



#include "InSight.h"
/*---------------------------------------------------------------------------*/
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,IDC_ABOUTTEXT);
            
                        /* \251 = copyright symbol*/
            char compiler[4];
            char * aboutMsg;
            itoa(_MSC_VER,compiler,10);
            HWND timeBoxHandle = GetDlgItem(hWndDlg,IDC_BUILD);
            HWND dateBoxHandle = GetDlgItem(hWndDlg,IDC_DATE);
            HWND compilerBoxHandle = GetDlgItem(hWndDlg,IDC_COMPILER);
            HWND aboutBoxHandle = GetDlgItem(hWndDlg,IDC_ABOUTTEXT);
            
            time(&now);
            switch(Msg)
            {
                  case WM_INITDIALOG:      
                        aboutMsg =   "Copyright \251 2006 Eric Chubb\n\n";
                        SetWindowText(timeBoxHandle,__TIME__);
                        SetWindowText(dateBoxHandle,__DATE__);
                        SetWindowText(compilerBoxHandle,compiler);
                        SetWindowText(aboutBoxHandle,aboutMsg);
                        return TRUE;
                  
                  case WM_COMMAND:
                        
                        switch(wParam)
                        {
                              case IDC_OKBUTT:                                                      /*finished with dialog*/
                              EndDialog(hWndDlg,0);
                              return TRUE;
                        }
            }
            return FALSE;                  
}

LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
      
      int i;
      hWndEdit = GetDlgItem(hWndDlg,IDC_EDIT1);
      switch(Msg)
      {
            case WM_INITDIALOG:      
                              
                  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 IDCANCEL:// i want out
                        EndDialog(hWndDlg, 0);
                        return TRUE;



                        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;
                  
                        
                        
                  }
   
                  
                  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;
                        
                  }
                  
                  for (i=0; i<bytesRead; i++)
                  {
                  
                        if (buffer[i] == 0x0)
                        {
                              buffer[i] = '.';
                        }
                        if(i % 16 == 0 &&i!=0)
                        {
                              buffer[i] = '\r';
                              buffer[i+1] = '\n';
                        }
                        bufferHex+= itoa(buffer[i],NULL,16);
                        
                  }
                  buffer[bytesRead+1] = '\0'; // Make sure we can print out a truncated string.
                  char *hex;
                  hex = new char[513];
                  strcpy(hex, bufferHex.c_str());
                  SetWindowText(hWndEdit,hex);
                  
      
                  return TRUE;
                  break;
            }
      }
      return FALSE;

      
}






//---------------------------------------------------------------------------
0
 
jkrCommented:
Use

char hexval[7];

               for (i=0; i<bytesRead; i++)
               {
               
                    if (buffer[i] == 0x0)
                    {
                         buffer[i] = '.';
                    }
                    if(i % 16 == 0 &&i!=0)
                    {
                         buffer[i] = '\r';
                         buffer[i+1] = '\n';
                    }
                    sprintf(hexval,"0x%2.2x",buffer[i]
                    bufferHex+= itoa(buffer[i],NULL,16);
                    bufferHexString += hexval;
                   
               }
0
 
jkrCommented:
Ooops, forgot the closing brace:

                    sprintf(hexval,"0x%2.2x",buffer[i]);
                    bufferHex+= itoa(buffer[i],NULL,16);
                    bufferHexString += hexval;
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
pushpopAuthor Commented:
Thank you so much for your quick reponse! I have it mostly working but a quick question! What type is bufferHexString? It wasn't in my original code so Is it a string, CString, char * etc?

Rgds

Eric
0
 
jkrCommented:
>>What type is bufferHexString? It wasn't in my original code

The same as 'bufferHex', which isn't declared in your code either ;o)

Actually, since I assumed 'bufferHex' to be a std::string, you can use the same for the 'translated' string.
0
 
pushpopAuthor Commented:
Right ok. Unfortunately SetWindowText doesn't accept strings, just char *. I have the error message to prove it

:\C++\WIN32D\main.CPP(152) : error C2664: 'SetWindowTextA' : cannot convert parameter 2 from 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' to 'const char *'
        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
0
 
jkrCommented:
Yes, so you'll have to use the same method that you already used for the other:

SetWindowText(hWndEdit,bufferHex.c_str());
0
 
pushpopAuthor Commented:
Ok i have tried that. But there are two problems: why do you use two strings bufferHex and bufferHexString instead of just bufferHexString, and also the program is now eating up CPU time and not responding.
0
 
jkrCommented:
>>But there are two problems: why do you use two strings

I thought you wanted to keep both. Well, then make that

char hexval[7];

               for (i=0; i<bytesRead; i++)
               {

                    sprintf(hexval,"0x%2.2x",buffer[i]);
                    bufferHex += hexval;
                   
                    if(i % 16 == 0 &&i!=0)
                    {
                        bufferHex += '\r';
                        bufferHex += '\n';
                    }
               }

              SetWindowText(hWndEdit,bufferHex.c_str());
0
 
pushpopAuthor Commented:
Ok thats fine, just wondering! the only remaining issue is that buffer is 513 bytes in size, but c_str() only returns the first 9 so it seems. is there another function one could use?
0
 
jkrCommented:
If 'c_str()' returns only 9 characters, there are only 9. Have you checked the value of 'bytesRead'?
0
 
pushpopAuthor Commented:
BytesRead is 512 according to my program. mystery problem!
0
 
jkrCommented:
OK, try the following

               for (i=0; i<bytesRead; i++)
               {

                    sprintf(hexval,"0x%2.2x",buffer[i]);
                    OutputDebugString(hexval);
                    bufferHex += hexval;
                   
                    if(i % 16 == 0 &&i!=0)
                    {
                        bufferHex += '\r';
                        bufferHex += '\n';
                    }
               }

and check the output with e.g. http://www.sysinternals.com/Utilities/DebugView.html
0
 
pushpopAuthor Commented:
Ok, 'I've done that, the for loop doesnt seem to be running more than once. I just get 0xFFFFFFEB in the debugger, which is the first byte of the MBR. thats it:
the loop looks like so :


      char hexval[7];
      string str="";

               for (i=0; i<512; i++)
               {

                              
                    if (buffer[i] == 0x0)
                    {
                         buffer[i] = '.';
                    }

                    if(i % 16 == 0 &&i!=0)
                    {
                        bufferHex += '\r';
                        bufferHex += '\n';
                    }
                              sprintf(hexval,"0x%X ",buffer[i]);
                    OutputDebugString();
                              str+= hexval;
                        }
                        
                    
                     SetWindowText(hWndEdit,str.c_str());
0
 
pushpopAuthor Commented:
Just checked now. when the sprintf statement is included the loop only runs once, yet when i take it out, it runs 512 times. weird huh?
0
 
jkrCommented:
Not weird, that should be

sprintf(hexval,"0x%2.2x",buffer[i]);

*exactly*

sprintf(hexval,"0x%X ",buffer[i]);

will cause a buffer overflow in 'hexval', since it is just 7 bytes and you're writing 10. There is no sense in using more than two characters to describe one byte in hex.
0
 
pushpopAuthor Commented:
ok, tried that again, still no luck, its not iterating through the string according to the debugger. Sorry to be a pain about this
0
 
jkrCommented:
>>OutputDebugString();

What is that? This should not even compile... Can you try the exact code above?
0
 
pushpopAuthor Commented:
:-S You told me about OutputDebugString ()! I downloaded the sysinternals utility. and0 xFFFFFFEB  is  what it has been returning
0
 
jkrCommented:
Yes, but definitely about the one with a parameter - without one, that should not compile.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

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