Solved

SetWindowText with different number systems

Posted on 2006-06-10
7
515 Views
Last Modified: 2012-06-21
Hi all,

I'm trying to figure out how to display the contents of a BYTE array using SetWindowText in different number systems such as decimal, hex and binary.  I've used sprintf in this regard but with no success. As SetWindowText prefers char arrays, I'm trying to rack my brains for a way to accomodate it.  Could anyone help me?

Thanks

pushpop
0
Comment
Question by:pushpop
  • 2
  • 2
  • 2
  • +1
7 Comments
 

Expert Comment

by:sambitdash
ID: 16881197
My windows has gone a bit rusty but my understanding is

BYTE is defined as unsigned char.

While SetWindowText may be looking for a char* pointer. Just cast your BYTE array as (char*) everything will work fine.
0
 

Author Comment

by:pushpop
ID: 16881235
Hmmm, i tried that but to no avail! You'll probably get a better idea of what I'm doing wrong if I give you the source!


-------------------------------------------------------

#include <windows.h>                  /*defines all window related bits of code*/
#include <stdio.h>
#include "resource.h"                  /*defines the messages for the window*/
#define _WIN32_WINNT 0x0501

#define WIN32_LEAN_AND_MEAN

HWND wnd,fsbox,rawbox,drvlbl,serbox,mounted_drives,combo;   /*the various handles to our windows*/
HANDLE hfile;                            /*file descriptor/handle/whatever*/

HINSTANCE hInstance;                  /*program instance handle*/
BYTE buffer[513];                        /*temporary buffer*/
char * dest;
int bytesRead,i,NTFS,FAT;
LPVOID lpMsgBuf;
char * vp;
char tmp [5];
char * drive = "\\\\.\\C:";      /*the drive we want to examine*/
char mountedDrives[26];

LRESULT CALLBACK DlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

void readNTFS();
void readFAT();
void getDrives();


struct NTFSboot
{
            char jmp_instr [3];
            char byters_Per_Sector[2];
            char secs_Per_Cluster;
            char med_desc ;
            char total_secs [8];
            unsigned long serial_num;
            char MFT_start [8];
};                                                                        


typedef struct NTFSboot NTFSboot;
NTFSboot nb;


/*program entry point*/
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
{
    DialogBox(hInstance, MAKEINTRESOURCE(main_mnu),
                wnd, (DLGPROC)DlgProc);

    return 0;
}


LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
      switch(Msg)
      {
      case WM_INITDIALOG:
      
            dest = (char *)malloc(520);
            dest = (char *)buffer;
            fsbox = GetDlgItem(hWndDlg,fs_box);
            rawbox = GetDlgItem(hWndDlg,raw_box);
            drvlbl = GetDlgItem(hWndDlg,drv_lbl);
            serbox = GetDlgItem(hWndDlg,serial_box);
            combo = GetDlgItem(hWndDlg,combobox);
            mounted_drives = GetDlgItem(hWndDlg,mounted);
            getDrives();
            
            if((hfile = CreateFile(drive,GENERIC_READ,                                    /*get a handle to our drive*/
                     FILE_SHARE_READ|FILE_SHARE_WRITE,
                     NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
                     NULL))==NULL)
            {
                               FormatMessage(
                         FORMAT_MESSAGE_ALLOCATE_BUFFER |
                         FORMAT_MESSAGE_FROM_SYSTEM |
                         FORMAT_MESSAGE_IGNORE_INSERTS,
                         NULL,
                         GetLastError(),
                         0,
                         (LPTSTR) &lpMsgBuf,
                         0,
                         NULL );
                         MessageBox( NULL, (LPCSTR)lpMsgBuf, "Problem acquiring handle to disk", MB_OK | MB_ICONWARNING );
                         
                                     EndDialog(hWndDlg, 0);
                                   return FALSE;
            }

            if(ReadFile(hfile,buffer,512,&bytesRead,NULL)==FALSE)       /*read MBR or give err msg and die*/
               {
                         FormatMessage(
                         FORMAT_MESSAGE_ALLOCATE_BUFFER |
                         FORMAT_MESSAGE_FROM_SYSTEM |
                         FORMAT_MESSAGE_IGNORE_INSERTS,
                         NULL,
                         GetLastError(),
                         0,
                         (LPTSTR) &lpMsgBuf,
                         0,
                         NULL );
                         MessageBox( NULL, (LPCSTR)lpMsgBuf, "Disk read error!", MB_OK | MB_ICONWARNING );
                         EndDialog(hWndDlg, 0);
                                     return FALSE;
                                     
                   
               }

            for (i=0; i<bytesRead; i++)  /*zap any null terminators*/
            {
                  if (buffer[i] < 0x20)
                  buffer[i] = '.';
            }
            
            
            

            /* nice function which displays the filesystem as
             * FAT **correctly** regardless of which edition it is
             */
            if(vp = strstr(buffer,"FAT"))
            {
                  memcpy(tmp,vp,5);
                  SetWindowText(fsbox,tmp);
                  FAT = 1;
                  //readFAT();
                  
            }

            

            else if(strstr(buffer,"NTFS"))
            {
                  SetWindowText(fsbox,"NTFS");
                  NTFS = 1;
                  readNTFS();
                  
            }      
            else
            {
                  MessageBox( NULL, "DiskUtil doesn't recognise this type of disk\n"
                                            "continuing on with analysis will\n"
                                            "yield inaccurate results, so the program will now exit"
                                            ,"Disk read error!", MB_OK | MB_ICONWARNING );
                                            EndDialog(hWndDlg, 0);
                                            return TRUE;
            }

            sprintf(dest,"%x",dest);
            SetWindowText(rawbox,dest);
            SetWindowText(drvlbl,drive);
      case WM_COMMAND:
            switch(wParam)
            {
            case IDOK:
                  EndDialog(hWndDlg, 0);
                  return TRUE;
            }
            break;
      }

      return FALSE;
}


void readNTFS()
{
   


}

void readFAT()
{

}


void getDrives()    /*detect all the mounted drives in a system*/
{
      char root_path[8];
      char vol_name[MAX_PATH+1];
      DWORD max_comp_len;
      DWORD fs_flags;

      for(i = 'A';i < 'Z';i++)
      {
            sprintf(root_path,"%c:\\ ",i);
            if(GetVolumeInformation(root_path, vol_name, MAX_PATH, 0, &max_comp_len, &fs_flags, 0, 0))
                  strcat(mountedDrives,root_path);
            
                  SetWindowText(mounted_drives,mountedDrives);
            

            

      }
      
}
0
 

Expert Comment

by:sambitdash
ID: 16892080
your WM_INITDIALOG falls through WM_COMMAND as well. I guess there should be break. Is it intentional?
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 14

Accepted Solution

by:
wayside earned 63 total points
ID: 16893997
To convert a BYTE array of binary data into something human-readable, you have to interate over the array and convert each byte and put it into another buffer:

char outputstr[2000] = { 0 };

for (int i=0; i<bytesRead; i++) {
   int outlen = strlen(outputstr);
   sprintf(&outputstr[outlen], "%d ", buffer[i]; // decimal
   sprintf(&outputstr[outlen], "%x ", buffer[i]; // hex

   // binary is trickier
   sprintf(&outputstr[outlen], "%d%d%d%d%d%d%d%d ", (buffer[i] & 0x80) >> 7, (buffer[i] & 0x40) >> 6,
                                                                                    (buffer[i] & 0x20) >> 5, (buffer[i] & 0x10) >> 4,
                                                                                    (buffer[i] & 0x08) >> 3, (buffer[i] & 0x04) >> 2,
                                                                                    (buffer[i] & 0x02) >> 1, (buffer[i] & 0x01));
}

 SetWindowText(rawbox, outputStr);

BTW:

         sprintf(dest,"%x",dest);

It is generally a bad idea to overwrite the input buffer in sprintf. You can wind up crashing.
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 62 total points
ID: 16895732
>>>>          dest = (char *)malloc(520);

if you are allocating a char buffer by using malloc you shouldn't overwrite the only pointer to that piece of memory by

>>>>          dest = (char *)buffer;

cause the storage never can be used again (what is called a leak). I would say you should remove the malloc statement cause you don't need it.


>>>>                if (buffer[i] < 0x20)
>>>>                   buffer[i] = '.';
 
No!!! If you replace any non-printable char by a dot you'll never see a reasonable output beside of the few strings. Throw that loop away it's rubbish.

I know, you made that loop because strstr wouldn't find "FAT" or "NTFS" if the buffer contains binary zero characters prior to the text. So, you have to implement the find function yourself. As we are in the C++ TA here, I show you a C++ solution (though it might get lonesome among all that pure C hack you've written above).

#include <string>
using namespace std;

struct Buffer
{
     char buf[512];   // that is the buffer, you don't need any extra byte
     unsigned char* getByteBuffer() { return (unsigned char*) buf;

     // returns the position of the found string or -1 if not found
     int  findString(const char* psz)
     {
            string s = psz;
            string b(buf, sizeof(buf));
            int pos = 0;
            if ((pos = b.find(s)) != string::npos)
                return pos;
            return -1;
     }
     // Note, std::string doesn't care for binary data - hopefully

     
}

You would use the Buffer struct like

    HINSTANCE hInstance;               /*program instance handle*/
    Buffer buffer;                    /*temporary buffer*/

      ...
          if(ReadFile(hfile,buffer.getByteBuffer(),512,&bytesRead,NULL)==FALSE)       /*read MBR or give err msg and die*/
         
          ...

        /* nice function which displays the filesystem as
           * FAT **correctly** regardless of which edition it is
           */
          int pos;
          if( (pos = buffer.findString("FAT")) >= 0)
          {
               string fat( buffer.buf + pos, 5);
               SetWindowText(fsbox, fat.c_str());
               FAT = 1;
               //readFAT();
               
          }
          ...        

Alternatively you could modify the Buffer::findString function to return a 5 byte string instead of a position:

     ...
     string findString(const string& s, int len = -1)
     {
           if (len <= 0)
               len = s.length();
            string b(buf, sizeof(buf));
            int pos = 0;
            if ((pos = b.find(s)) != string::npos)
                return b.substr(pos, len);
            return "";
     }
     ...

Then, the find call would turn to

          string fat = buffer.findString("FAT", 5));
          if (!fat.empty())
          {
               SetWindowText(fsbox, fat.c_str());
               FAT = 1;
               //readFAT();
          }


You easily could add output functions to the Buffer struct, e. g. to get a hex (raw) output like that

 0 |  00 10 C0 80 00 00 01 03 00 02 46 41 54 33 32 00  ..À€....FAT32.
 1 |  00 00 00 00 00 01 00 00 00 03 03 7F 00 00 7E 00  ...............~.
     ...
16|  00 00 00 00 00 01 00 00 00 03 03 7F 00 00 7E 00  ...............~.


You would need an output window (rawbox) that supports multiline.

Tell me if you want to go that way.

Regards, Alex
 
0
 

Author Comment

by:pushpop
ID: 16896538
Hi Guys,

I've split the points between you two as your answers were both equally useful. I hope that's ok. I'd just like to point a few things out-

1. I'm a student so I'm quite new to win32 and self-taught
2. I had to basically teach myself C/C++ as I had two very good semesters of Java and one mediocre one of C++ which barely even mentioned pointers.
3. It's quite discouraging to have your code described as 'hack,' given the above points I've just made. If I'm doing something that could be done better in a different way, I'm all for hearing about it, but I'm not paying a subscription to this site so I can have derogatory comments thrown at me :-)

Thanks again guys

P
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 16899991
>>>> It's quite discouraging to have your code described as 'hack,'

Actually, I didn't want to blame *you* as I recognized very well that you are a beginner. But the code above isn't good - even if looking at it from a C point of view. And I thought that a big part of the code was copied from a C sample. Unfortunately, nearly all samples of native Windows programming were written in C, what makes it very difficult for beginners to apply OO techniques or learn C++ by writing those kind of programs.

I asked you "Tell me if you want to go that way" cause I would like to help you changing the prog above from a badly written C program to a fairly well written C++ program.

Regards, Alex
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now