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

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Microsoft Remote Desktop 8.0.19 - Connec...
With Microsoft Remote Desktop, you can connect to a remote PC and your work resources from almost anywhere. Experience the power of Windows with RemoteFX in a Remote Desktop client designed to help... Read more
OmniGraffle 6.3 - Create diagrams, flow...
OmniGraffle helps you draw beautiful diagrams, family trees, flow charts, org charts, layouts, and (mathematically speaking) any other directed or non-directed graphs. We've had people use Graffle to... Read more
PDFKey Pro 4.3.2 - Edit and print passwo...
PDFKey Pro can unlock PDF documents protected for printing and copying when you've forgotten your password. It can now also protect your PDF files with a password to prevent unauthorized access and/... Read more
Ableton Live 9.2.2 - Record music using...
Ableton Live lets you create and record music on your Mac. Use digital instruments, pre-recorded sounds, and sampled loops to arrange, produce, and perform your music like never before. Ableton Live... Read more
Macs Fan Control 1.3.1.0 - Monitor and c...
Macs Fan Control allows you to monitor and control almost any aspect of your computer's fans, with support for controlling fan speed, temperature sensors pane, menu-bar icon, and autostart with... Read more
NetShade 6.3.1 - Browse privately using...
NetShade is an anonymous proxy and VPN app+service for Mac. Unblock your Internet through NetShade's high-speed proxy and VPN servers spanning seven countries. NetShade masks your IP address as you... Read more
Dragon Dictate 4.0.7 - Premium voice-rec...
With Dragon Dictate speech recognition software, you can use your voice to create and edit text or interact with your favorite Mac applications. Far more than just speech-to-text, Dragon Dictate lets... Read more
Persecond 1.0.2 - Timelapse video made e...
Persecond is the easy, fun way to create a beautiful timelapse video. Import an image sequence from any camera, trim the length of your video, adjust the speed and playback direction, and you’re done... Read more
GIMP 2.8.14p2 - Powerful, free image edi...
GIMP is a multi-platform photo manipulation tool. GIMP is an acronym for GNU Image Manipulation Program. The GIMP is suitable for a variety of image manipulation tasks, including photo retouching,... Read more
Sandvox 2.10.2 - Easily build eye-catchi...
Sandvox is for Mac users who want to create a professional looking website quickly and easily. With Sandvox, you don't need to be a Web genius to build a stylish, feature-rich, standards-compliant... Read more

ReBoard: Revolutionary Keyboard (Utilit...
ReBoard: Revolutionary Keyboard 1.0 Device: iOS Universal Category: Utilities Price: $1.99, Version: 1.0 (iTunes) Description: Do everything within the keyboard without switching apps! If you are in WhatsApp, how do you schedule a... | Read more »
Tiny Empire (Games)
Tiny Empire 1.1.3 Device: iOS Universal Category: Games Price: $2.99, Version: 1.1.3 (iTunes) Description: Launch cannonballs and blow tiny orcs into thousands of pieces in this intuitive fantasy-themed puzzle shooter! Embark on an... | Read more »
Astropad Mini (Productivity)
Astropad Mini 1.0 Device: iOS iPhone Category: Productivity Price: $4.99, Version: 1.0 (iTunes) Description: *** 50% off introductory price! ​*** Get the high-end experience of a Wacom tablet at a fraction of the price with Astropad... | Read more »
Emo Chorus (Music)
Emo Chorus 1.0.0 Device: iOS Universal Category: Music Price: $1.99, Version: 1.0.0 (iTunes) Description: Realistic Choir simulator ranging from simple Chorus emulation to full ensemble Choir with 128 members. ### introductory offer... | Read more »
Forest Spirit (Games)
Forest Spirit 1.0.5 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0.5 (iTunes) Description: | Read more »
Ski Safari 2 (Games)
Ski Safari 2 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: The world's most fantastical, fun, family-friendly skiing game is back and better than ever! Play as Sven's sister Evana, share... | Read more »
Lara Croft GO (Games)
Lara Croft GO 1.0.47768 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.47768 (iTunes) Description: Lara Croft GO is a turn based puzzle-adventure set in a long-forgotten world. Explore the ruins of an ancient... | Read more »
Whispering Willows (Games)
Whispering Willows 1.23 Device: iOS Universal Category: Games Price: $4.99, Version: 1.23 (iTunes) Description: **LAUNCH SALE 50% OFF** - Whispering Willows is on sale for 50% off ($4.99) until September 9th. | Read more »
Calvino Noir (Games)
Calvino Noir 1.1 Device: iOS iPhone Category: Games Price: $3.99, Version: 1.1 (iTunes) Description: The film noir stealth game. Calvino Noir is the exploratory, sneaking adventure through the 1930s European criminal underworld.... | Read more »
Angel Sword (Games)
Angel Sword 1.0 Device: iOS Universal Category: Games Price: $6.99, Version: 1.0 (iTunes) Description: Prepare to adventure in the most epic full scale multiplayer 3D RPG for mobile! Experience amazing detailed graphics in full HD.... | Read more »

Price Scanner via MacPrices.net

Apple and Cisco Partner to Deliver Fast-Lane...
Apple and Cisco have announced a partnership to create a “fast lane” for iOS business users by optimizing Cisco networks for iOS devices and apps. The alliance integrates iPhone with Cisco enterprise... Read more
Apple offering refurbished 2015 13-inch Retin...
The Apple Store is offering Apple Certified Refurbished 2015 13″ Retina MacBook Pros for up to $270 (15%) off the cost of new models. An Apple one-year warranty is included with each model, and... Read more
Apple refurbished 2015 MacBook Airs available...
The Apple Store has Apple Certified Refurbished 2015 11″ and 13″ MacBook Airs (the latest models), available for up to $180 off the cost of new models. An Apple one-year warranty is included with... Read more
21-inch iMacs on sale for up to $120 off MSRP
B&H Photo has 21″ iMacs on sale for up to $120 off MSRP including free shipping plus NY sales tax only: - 21″ 1.4GHz iMac: $999.99 $100 off - 21″ 2.7GHz iMac: $1199.99 $100 off - 21″ 2.9GHz iMac... Read more
5K iMacs on sale for up to $150 off MSRP, fre...
B&H Photo has the 27″ 3.3GHz 5K iMac on sale for $1899.99 including free shipping plus NY tax only. Their price is $100 off MSRP. They have the 27″ 3.5GHz 5K iMac on sale for $2149.99 $2199.99, $... Read more
1.4GHz Mac mini, refurbished, available for $...
The Apple Store has Apple Certified Refurbished 1.4GHz Mac minis available for $419. Apple’s one-year warranty is included, and shipping is free. Their price is $80 off MSRP, and it’s the lowest... Read more
iPad Air 2 on sale for up to $100 off MSRP
Best Buy has iPad Air 2s on sale for up to $100 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... Read more
MacBook Airs on sale for $100 off MSRP
Best Buy has MacBook Airs on sale for $100 off MSRP on their online store. Choose free shipping or free local store pickup (if available). Sale prices for online orders only, in-store prices may vary... Read more
Big Grips Lift Handle For iPad Air and iPad A...
KEM Ventures, Inc. which pioneered the extra-large, super-protective iPad case market with the introduction of Big Grips Frame and Stand in 2011, is launching Big Grips Lift featuring a new super-... Read more
Samsung Launches Galaxy Tab S2, Its Most Powe...
Samsung Electronics America, Inc. has announced the U.S. release of the Galaxy Tab S2, its thinnest, lightest, ultra-fast tablet. Blending form and function, elegant design and multitasking power,... Read more

Jobs Board

*Apple* Evangelist - JAMF Software (United S...
The Apple Evangelist is responsible for building and cultivating strategic relationships with Apple 's small and mid-market business development field teams. This 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* Desktop Analyst - KDS Staffing (Unit...
…field and consistent professional recruiting achievement. Job Description: Title: Apple Desktop AnalystPosition Type: Full-time PermanentLocation: White Plains, NYHot Read more
*Apple* Systems Engineer (Mclean, VA and NYC...
Title: Apple Systems Engineer (Mclean, VA and NYC) Location: United States-New York-New York-200 Park Ave (22005) Other Locations: United States-Virginia-Vienna-Towers Read more
*Apple* Systems Engineer (Mclean, VA and NYC...
…Assist in providing strategic direction and technical leadership within the Apple portfolio, including desktops, laptops, and printing environment. This person will Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.