Solved

SetWindowText with different number systems

Posted on 2006-06-10
7
514 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
Comment Utility
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
Comment Utility
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
Comment Utility
your WM_INITDIALOG falls through WM_COMMAND as well. I guess there should be break. Is it intentional?
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 14

Accepted Solution

by:
wayside earned 63 total points
Comment Utility
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
Comment Utility
>>>>          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
Comment Utility
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
Comment Utility
>>>> 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

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

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…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

743 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

16 Experts available now in Live!

Get 1:1 Help Now