TweetFollow Us on Twitter

Sector Dumps
Volume Number:5
Issue Number:7
Column Tag:HyperChat™

XCMD Corner: Sector Dumps

By Donald Koscheka, Arthur Young & Company, MacTutor Contributing Editor

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

Reinventing the wheel often provides an opportunity to embellish on the original design. Recently, I needed a file dump utility. Several packages are available “over the counter”, but I needed a utility that dumps the entire file without having to manually move from sector to sector as is the case with most commercial solutions. Moreover, I use file dump tools frequently enough that I could afford to spend the effort writing one for Hypercard.

I dump the file in a fairly typical way. Each line in the dump contains the “sector address” of the first byte on the line followed by the hexadecimal dump of 16 bytes followed by the ASCII interpretation of the data. Not all ASCII characters are “printable” so we replace non-printing characters with the “.”, yielding a cleaner display.

This month’s XFCN, FilePeek.c (listing 1) accepts two parameters. The first parameter is the reference number of the opened file; the second parameter is the sector you want dumped. HFS sectors are 512 bytes so filepeek returns 32 lines of 16 bytes apiece.

Dumping the entire contents of a file becomes a matter of calling FilePeek repeatedly for all the logical sectors in the file.

The first line in the dump tells us how many bytes were read in. This number can be equal to or less than a full sector. If line 1 contains less than a sector full of data, then you know that logical end of file is after the last byte read in.

The Hypertalk afficianado will realize that this code can easily be written in Hypertalk. I chose to commit my scheme to an XFCN only after discovering that the Hypertalk version was too slow for my purposes.

The dumping scheme is amazingly simple. Position the file mark at the beginning of the sector that you want to dump. If the start of the sector extends beyond end of file, do nothing and return to hypercard with a result of zero (no bytes were read in), otherwise read the sector into the buffer we allocated (buf).

The sector is presented to Hypercard as a series of haxadecimal characters. Hypercard contains a call back “NumtoHex” which converts an arbitrary run of data to a hex string. We lose portability when using a callback so you’ll need to write your own hexdump algorithm or dig one up in the toolbox.

FilePeek dumps two bytes at a time (4 hex digits). This is analogous to dumping the contents of a short. We can use a pointer to short (rPtr). To dump the ascii data, we use a char pointer (cPtr) to the same data.

The current line in the dump is assembled by first displaying the “sector address” of that line. The sector address is 512 * blk (blk = sector number).

The sector address is delineated by the “:” character. Following the sector address, we display 16 bytes of data in hexadecimal format. The data is grouped into 8 words.

The hexadecimal data is followed by the ascii representation of the line. If the character falls in the range of printing characters, we display the character, otherwise print a “.”. Characters below the space (0x020) are not normally considered printing characters. Likewise, Inside Macintosh indicates that no characters above $D8 have a printable format. Using the period to represent non-printing characters results in a less-cluttered looking dump.

We need to cycle the character pointer, cPtr, twice for every cycle on rPtr (a character is half a word). We accumulate the ascii data into a separate string which we then concatenate onto the end of the hex data.

Once the current line is assembled, we stick a carriage return on the end, block move it to the output data handle and then go to the next 16 bytes in the input stream. When the outer loop completes, outdata will contain 32 lines of 16 bytes apiece, suitable for framing.

Figure 1.

How you open and close a file from Hypercard is a matter of taste. I prefer to keep my interface to the file manager as clean as possible. This requires passing a filename and working directory id to the file manager’s FSOpen call and subsequently referring to the file by the reference number returned by FSOpen. To close the file, pass the reference number to FSClose (last month I provided an XFCN that will return a file name and working directory id from the standard file package).

Listings 2 and 3 are two simple XFCNs that open and close a file respectively. FileOpen returns a reference number if the file opened ok (0 otherwise). Pass this reference number to FilePeek along with the number of the sector you wish to dump.

Figure 1. is a sample card that I use to dump the contents of the file. The dump is presented in a mono-spaced font to keep it “clean-looking”. The forward and back arrows allow the user to “browse” sectors by moving 1 sector forward or backward. The scripts for theses two buttons is fairly obvious so I’ve left them to the reader. The scripts for open, close are contained in listing 4.

--1

-- file open button
on mouseUp
  global fileName, DirectoryID
  global fileRefNum, theSector
  
  put getFileNameToOpen() into it
  put item 1 of it into fileName
  put item 2 of it into DirectoryID
  put filename into card field “file name”
  
  if filename is not empty then
    Put FileOpen( fileName, DirectoryID ) into fileRefNum
  end if
  
end mouseUp

-- Go to Sector
on mouseUp
  global fileRefNum, theSector
  
  if filerefnum is empty then
    answer “You have to open a file first, silly!”
  else
    
    ask “Read what sector?” with “0”
    
    if (it is not empty) then
      put it into theSector
      Peekat theSector
    end if
  end if
  
end mouseUp

-- file close
on mouseUp
  global fileRefNum
  
  put FileClose( fileRefNum ) into it
  -- ignore the result of a closed file
end mouseUp

Listing 4. Scripts for the buttons

An interesting variation on this theme would be to dump the files in reverse order so that it prints in ascending order on the LaserWriter. Several easy solutions exist for this problem, and I’ll leave it as this month’s exercise to the reader. As a hint, I can think of two ways to do this off hand, one easy but inefficient, the second a little more challenging: (1) create a card for every sector (make sure your file is small first!) or (2) Find out how many sectors the file contains before starting the dump ( a wonderful opportunity to try your hand at XFCN writing).

Note on a bug in last month’s article:

Last month’s XFCN, GetFileName, incorrectly returns the working directory id of the file selected from SFGetFile. Change the call to GetFileNameToOpen to Read:

/* 1 */

if( GetFileNameToOpen(typs,numTypes,FileName,&FileWDID ) ){
 temp = (long)FileWDID & 0xFFFF;
 NumToStr( paramPtr, temp, &WDIDString );
 PtoCstr( WDIDString );
Listing 1:  FilePeek.c

/********************************/
/* File: FilePeek.c*/
/* */
/* Given the sector index into*/
/* an existing file, read the */
/* sector in and “dump” it to */
/* the screen    */
/* */
/* Paramters:    */
/* param0 = file referencenum */
/* ( file is open) */
/* param1 = sector number */
/* (1 sector = 512 bytes) */
/* ----------------------------  */
/* To Build:*/
/* */
/* (1) Create a project using */
/* this file as well as the */
/* XCMD.Glue.c file. (Set */
/* project type to XCMD (or */
/* XFCN) from the Project menu.  */
/* */
/* (2) Bring the project up to*/
/* date.*/
/* */
/* (3) Build Code Resource. */
/* */
/* (4) Use ResEdit to copy the   */
/* resource to your stack.*/
/********************************/

#include<MacTypes.h>
#include<OSUtil.h>
#include<MemoryMgr.h>
#include<FileMgr.h>
#include<ResourceMgr.h>
#include<pascal.h>
#include<strings.h>
#include  “HyperXCmd.h”
#include“HyperUtils.h”

#define SECTOR   512 /***size of input buffer ***/
#define NUMROWS  8 /***across each line***/
#define NUMLINES 32/***lines of data ***/
#define NUMBYTES 16/***#bytes per row of data***/
#define SPACE    0x020  /***the space character***/

long  paramtoNum();
void  appendChar();
void  CopyStrToHandle();
char  *CopyAscii();

pascal void main( paramPtr )
 XCmdBlockPtr  paramPtr;
{
 short  err;
 short  fref;
 short  lc; /* line count */
 short  rc; /* row count  */
 long   cnt;
 long   blk;/* sector number  */
 Handle outData;
 short  *rPtr;   /* per row */
 char   *cPtr;   /* for ASCII */
 char   *aPtr;   /* points to asciival */
 char   *buf;
 char   asciiStr[32];
 char   curntLine[256]; 
 Str31  numString;
 
 outData = 0L;
 if( paramPtr->paramCount == 2 ){  
 /*** expect two parameters ***/
 /*** (1) Get our input parameters ***/
 fref = (short)paramtoNum( paramPtr, 0 );
 blk   = paramtoNum( paramPtr, 1 );

 /*** (2) Read a buffer of data    ***/
 blk = blk * SECTOR;
 err = SetFPos( fref, fsFromStart, blk );
 if ( !err ){
 cnt = SECTOR;
 
 /*** We need to keep this data locked ***/
 /*** Since we can;t trust callbacks not     ***/
 /*** to move stuff, we allocate the ***/
 /*** buffer as non-relocatable.   ***/
 buf = NewPtr( cnt );
 err = FSRead( fref, &cnt, buf );
 
 if ( err != noErr &&  err != eofErr ){
 paramPtr->returnValue = 0L;
 return;
 }
 }
 
 /*** result is returned to hypercard as     ***/
 /*** a null terminated string***/
 outData = NewHandle( 0L );

 /*** (3) Start filling the output buffer    ***/
 *curntLine = ‘\0’;
 
 /*** first the number of bytes read in***/
 NumToHex( paramPtr, cnt, 4 , &numString );

 appendChar( PtoCstr( (char *)&numString), ‘\r’ );
 CopyStrToHandle( &numString, outData );

 /*** point to the input data ***/
 rPtr = (short *)buf;
 
 for( lc = 0;  lc < NUMLINES; ++lc ){
 *curntLine = ‘\0’;

 /*** blk is the sector address  ***/
 NumToHex( paramPtr, blk, 6, &numString );
 PtoCstr( (char *)&numString );
 strcat( curntLine, &numString );
 appendChar( curntLine, ‘:’ );
 appendChar( curntLine, SPACE );
 aPtr = asciiStr;
 blk += NUMBYTES;
 
 for( rc = 0; rc < NUMROWS; ++rc ){
 
 /*** convert eight shorts per row ***/
 /*** if we overrun the buffer, draw ***/
 /*** whatever data follows it...  ***/
 NumToHex( paramPtr, (long)*rPtr, 4 , &numString);
 strcat( curntLine, PtoCstr( (char *)&numString));
 appendChar( curntLine, ‘ ‘ );
 
 cPtr = (char *)rPtr;
 aPtr = CopyAscii( aPtr, *cPtr++ );
 aPtr = CopyAscii( aPtr, *cPtr++ );
 rPtr++;
 }
 
 *aPtr = ‘\0’; /*** terminate the ascii data ***/
 strcat( curntLine, asciiStr );
 appendChar( curntLine, ‘\r’ );
 
 /*** move  line into output buffer***/
 CopyStrToHandle( curntLine, outData );
 }
 
 DisposPtr( buf );
 }
 
 cnt = GetHandleSize( outData );
 *(*outData + cnt) = ‘\0’;
 paramPtr->returnValue = outData;
}

long  paramtoNum( paramPtr, i )
 XCmdBlockPtr  paramPtr;
 short  i;
/************************
* Given a handle to an input
* argument in the paramBlk
* return an integer representation
* of the data.
*
************************/
{
 Str31  theStr;
 
 HLock( paramPtr->params[ i ] );
 ZeroToPas( paramPtr, *(paramPtr->params[ i ]), &theStr );
 HUnlock( paramPtr->params[ i ] );
 return( StrToLong( paramPtr, &theStr ) );
}

void  appendChar( theStr, theChar )
 char *theStr;
 char theChar;
/************************
* append the character passed
* to the end of the string 
************************/
{
 long len = strlen( theStr );
 char *theEnd;

 theEnd = theStr + len;
 *theEnd++  = theChar;
 *theEnd  = ‘\0’;
}

char  *CopyAscii( outStr, theChar )
 char *outStr;
 char theChar;
/************************
* if the character passed  
* in the input stream is a 
* printing character, append
* it to the output string,
* otherwise, append the ‘.’
*
* return the update output 
* string.
************************/
{
 if ( theChar >= SPACE  &&  theChar <= 0x0D8  ) 
 *outStr++ = theChar;
 else
 *outStr++ = ‘.’;
 
 return( outStr );
}

void CopyStrToHandle( theStr, hand )
 char *theStr;
 Handle hand;
/************************
* Copy the input data to the
* output handle.
*
************************/
{
 long cnt = strlen( theStr );
 long oldSize  = GetHandleSize( hand );

 SetHandleSize( hand, oldSize + cnt );
 BlockMove( theStr, *hand + oldSize, cnt );
}
Listing 2: FileOpen.c

/********************************/
/* File: FIleOpen.c*/
/* */
/* open the file whose name and */
/* working directory id are */
/* passed as parameters.  This*/
/* information can be obtained*/
/* using GetFileNameToLoad... */
/* */
/* Paramters:    */
/* param0 = file namenum  */
/* param1 = directory id  */
/* */
/* Out: */
/* File RefNum if opened, 0 */
/* otherwise*/
/* ----------------------------  */
/********************************/

#include<MacTypes.h>
#include<OSUtil.h>
#include<MemoryMgr.h>
#include<FileMgr.h>
#include<ResourceMgr.h>
#include<pascal.h>
#include<strings.h>
#include  “HyperXCmd.h”
#include“HyperUtils.h”

pascal void main( paramPtr )
 XCmdBlockPtr  paramPtr;
{
 char   *filename;
 Str31  str, fName;
 short  wdid, refnum;

 HLock( paramPtr->params[0] );
 ZeroToPas( paramPtr, *(paramPtr->params[0]), &fName );
 HUnlock( paramPtr->params[0] );
 
 /* convert the wdid to a usable form */
 HLock( paramPtr->params[1] );
 ZeroToPas( paramPtr, *(paramPtr->params[1]), &str );
 HUnlock( paramPtr->params[1] );
 wdid = (short)StrToNum( paramPtr, &str );
 
 if( FSOpen( &fName, wdid, &refnum) == noErr )
 NumToStr( paramPtr, (long)refnum, &str );
 else
 NumToStr( paramPtr, 0L, &str );

 paramPtr->returnValue = PasToZero( paramPtr, &str );
}
Listing 3:  FileClose.c

/********************************/
/* File: FileClose.c */
/* */
/* XCMD to access the file mgr*/
/* call FSClose  */
/* Paramters:    */
/* param0 = file reference from  */
/* the fileopen xcmd */
/* ----------------------------  */
/********************************/

#include<MacTypes.h>
#include<OSUtil.h>
#include<MemoryMgr.h>
#include<FileMgr.h>
#include<ResourceMgr.h>
#include<pascal.h>
#include<strings.h>
#include  “HyperXCmd.h”
#include“HyperUtils.h”

pascal void main( paramPtr )
 XCmdBlockPtr  paramPtr;
{
 short  refnum;
 char   str[256];
 
 /* convert the refnum to a usable form */
 HLock( paramPtr->params[0] );
 ZeroToPas( paramPtr, *(paramPtr->params[0]), &str );
 HUnlock( paramPtr->params[0] );
 refnum = (short)StrToNum( paramPtr, &str );
 
 /* Normally we should check the result      */
 /* code but it won’t kill us to ignore*/
 /* the reslt of a close file call */
 if ( FSClose(refnum) )
 ;
 paramPtr->returnValue = 0L;
}

 
AAPL
$118.80
Apple Inc.
+1.20
MSFT
$47.48
Microsoft Corpora
+0.01
GOOG
$539.34
Google Inc.
-1.74

MacTech Search:
Community Search:

Software Updates via MacUpdate

RapidWeaver 6.0.3 - Create template-base...
RapidWeaver is a next-generation Web design application to help you easily create professional-looking Web sites in minutes. No knowledge of complex code is required, RapidWeaver will take care of... Read more
iPhoto Library Manager 4.1.10 - Manage m...
iPhoto Library Manager lets you organize your photos into multiple iPhoto libraries. Separate your high school and college photos from your latest summer vacation pictures. Or keep some photo... Read more
iExplorer 3.5.1.9 - View and transfer al...
iExplorer is an iPhone browser for Mac lets you view the files on your iOS device. By using a drag and drop interface, you can quickly copy files and folders between your Mac and your iPhone or... Read more
MacUpdate Desktop 6.0.3 - Discover and i...
MacUpdate Desktop 6 brings seamless 1-click installs and version updates to your Mac. With a free MacUpdate account and MacUpdate Desktop 6, Mac users can now install almost any Mac app on macupdate.... Read more
SteerMouse 4.2.2 - Powerful third-party...
SteerMouse is an advanced driver for USB and Bluetooth mice. It also supports Apple Mighty Mouse very well. SteerMouse can assign various functions to buttons that Apple's software does not allow,... Read more
iMazing 1.1 - Complete iOS device manage...
iMazing (was DiskAid) is the ultimate iOS device manager with capabilities far beyond what iTunes offers. With iMazing and your iOS device (iPhone, iPad, or iPod), you can: Copy music to and from... Read more
PopChar X 7.0 - Floating window shows av...
PopChar X helps you get the most out of your font collection. With its crystal-clear interface, PopChar X provides a frustration-free way to access any font's special characters. Expanded... Read more
Carbon Copy Cloner 4.0.3 - Easy-to-use b...
Carbon Copy Cloner backups are better than ordinary backups. Suppose the unthinkable happens while you're under deadline to finish a project: your Mac is unresponsive and all you hear is an ominous,... Read more
ForeverSave 2.1.3 - Universal auto-save...
ForeverSave auto-saves all documents you're working on while simultaneously doing backup versioning in the background. Lost data can be quickly restored at any time. Losing data, caused by... Read more
Voila 3.8.1 - Capture, annotate, organiz...
Voila is a screen-capture, recording, and annotation tool that is a full-featured replacement for Mac's screen-capture and screen-recording capabilities. It has a large and robust set of editing,... Read more

Latest Forum Discussions

See All

Sunburn! Review
Sunburn! Review By Campbell Bird on November 26th, 2014 Our Rating: :: DON'T DIE ALONEUniversal App - Designed for iPhone and iPad Platform through the depths of space to make sure your entire crew dies together in this satisfying... | Read more »
Black Friday has Started Early – Lots an...
It’s almost turkey time! Which means lots and lots of food but also lots and lots of sales. Some sales have even started a few days early, which is why we’ve put together a list of iOS games that are currently discounted (sometimes by a lot).... | Read more »
Loose Leaf Review
Loose Leaf Review By Jennifer Allen on November 26th, 2014 Our Rating: :: SIMPLE SKETCHINGiPad Only App - Designed for the iPad Sketch out ideas with simple drawing tools, courtesy of Loose Leaf.   | Read more »
Screeny (Utilities)
Screeny 1.0 Device: iOS iPhone Category: Utilities Price: $.99, Version: 1.0 (iTunes) Description: Screeny is an utility app that helps you save space consumed by screenshots. It screens your camera roll and helps you to filter and... | Read more »
Tilt to Live Bundle Set to Arrive This T...
Tilt to Live Bundle Set to Arrive This Thanksgiving Posted by Ellis Spice on November 25th, 2014 [ permalink ] One Man Left has unveiled an upcoming Tilt to Live bundle, allowing players to get the series for a di | Read more »
BattleLore: Command (Entertainment)
BattleLore: Command 1.0 Device: iOS Universal Category: Entertainment Price: $9.99, Version: 1.0 (iTunes) Description: ***NOTE: Compatible with iPad 2/iPad mini, iPod touch 5 and up and iPhone 4S and up – WILL NOT RUN ON EARLIER... | Read more »
Weather Or Not Review
Weather Or Not Review By Jennifer Allen on November 25th, 2014 Our Rating: :: STYLISH WEATHER REPORTINGiPhone App - Designed for the iPhone, compatible with the iPad Check the weather quickly and conveniently with Weather or Not... | Read more »
The All-New Football Manager Handheld 20...
The All-New Football Manager Handheld 2015 is Available Now Posted by Jessica Fisher on November 25th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Six iOS Games to Get You Ready for Thank...
Image Source: Friends Wiki At this point in the month, you or at least a few people you know are probably getting ready to scramble around (or are already scrambling around) for Thanksgiving Dinner. It’s a hectic day of precise oven utilization, but... | Read more »
Call of Duty: Heroes: Tips, Tricks, and...
Hello Heroes: What’d we think of Call of Duty‘s take on Clash of Clans? Check out our Call of Duty: Heroes review to find out! Just downloaded Call of Duty: Heroes and need some handy tips and tricks on how to get ahead of the rest? As we often do,... | Read more »

Price Scanner via MacPrices.net

Early Black Friday Mac Pro sale, 6-Core 3.5GH...
 B&H Photo has the 6-Core 3.5GHz Mac Pro on sale today for $3499 including free shipping plus NY sales tax. Their price is $500 off MSRP, and it’s the lowest price available for this model from... Read more
Early Black Friday sale price: 15-inch 2.2GHz...
 B&H Photo has the 2014 15″ 2.2GHz Retina MacBook Pro on sale today for $1699.99. Shipping is free, and B&H charges NY sales tax only. Their price is $300 off MSRP, equalling Best Buy’s price... Read more
13-inch 2.5GHz MacBook Pro (refurbished) avai...
The Apple Store has Apple Certified Refurbished 13″ 2.5GHz MacBook Pros available for $170 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free: - 13″ 2.5GHz... Read more
Early Black Friday iPad mini 3 sale: $75 off...
 Best Buy has iPad mini 3s on sale for $75 off MSRP on their online store for a limited time. Choose free shipping or free local store pickup (if available). Sale prices available for online orders... Read more
Early Black Friday MacBook Pro sale: 15-inch...
 Best Buy has posted early Black Friday prices on 15″ Retina MacBook Pros, with models on sale for $300 off MSRP on their online store for a limited time. Choose free local store pickup (if available... Read more
A9 Chips Already?
It’s barely more than a couple of months since Apple got the first A8 systems-on-chip into consumer hands, but rumor and news focus is already turning to the next-generation A9 SoC. Apple Daily... Read more
NewerTech Announces NuGuard KXs Impact X-Orbi...
NewerTech has announced updates to its family of Impact X-Orbing Screen Armor bringing military grade, triple layer protection to Apple’s new iPhone 6 and 6 Plus. Like all models in the NuGuard KXs... Read more
13-inch 1.4GHz MacBook Air on sale for $889,...
 B&H Photo has the 13″ 1.4GHz/128GB MacBook Air on sale for $889 including free shipping plus NY tax only. Their price is $110 off MSRP. B&H will also include free copies of Parallels Desktop... Read more
Save up to $300 on Macs and iPads with your A...
Purchase a new Mac or iPad at The Apple Store for Education and take up to $300 off MSRP. All teachers, students, and staff of any educational institution qualify for the discount. Shipping is free,... Read more
Apple refurbished Mac Pros available for up t...
The Apple Store is offering Apple Certified Refurbished Mac Pros for up to $600 off the cost of new models. An Apple one-year warranty is included with each Mac Pro, and shipping is free. The... Read more

Jobs Board

*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Senior Event Manager, *Apple* Retail Market...
…This senior level position is responsible for leading and imagining the Apple Retail Team's global event strategy. Delivering an overarching brand story; in-store, Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.