home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / PMF300.ZIP / PMFLOPPY.DOC < prev    next >
Text File  |  1993-02-06  |  16KB  |  307 lines

  1.  
  2.  
  3.                    PMFloppy - a Floppy disk utility
  4.  
  5.                                 v3.00
  6.                         Public Domain software
  7.                      written 1990-1993, Greg Bryant
  8.  
  9.  
  10.  
  11. I.  Introduction
  12.  
  13. PMFloppy is a generic floppy disk utility.  It currently can copy and compare
  14. disks, and save their "images" into a file on a hard drive.  It is a 
  15. multi-threaded application, using background threads to prevent slowing down
  16. Presentation Manager.  It allows many disks (up to twenty) to be read into
  17. memory at the same time.  It does not require any disk swapping.  Look for
  18. further additions in the future.
  19.  
  20. PMFloppy was written as an exercise in PM programming.  I wanted to put to 
  21. use some of the things I learned at the PM Apps class, and extend it a little
  22. to some topics not covered.  I was looking for a task that would lend itself
  23. well to multi-threading, when I ran across a PD program called DSKCPY by
  24. Brady Flowers.  Since DSKCPY was character-oriented,  I decided to wrap a
  25. PM interface around it and use the lengthy disk interactions as background
  26. threads.
  27.  
  28. All the standard disclaimers about damage to data, hardware, personal sanity,
  29. etc caused by the program apply.  This is public domain software, which means
  30. you may not be charged any fees other than shipping and handling costs to
  31. receive it.
  32.  
  33.  
  34.  
  35. II. Installation
  36.  
  37. PMFloppy requires a system running OS/2 2.0 or higher.  Both FAT and HPFS
  38. file systems are supported.  Copy the file "PMFLOPPY.EXE" to your OS2
  39. subdirectory.  You can run PMFloppy from the command line, or create a
  40. program object.
  41.  
  42. Full source code is being distributed.  The extra files are not necessary to
  43. run the program, but are included if you wish to make modifications to the
  44. code, or use the code as a resource for your own PM programs.
  45.  
  46. The distribution disk or archive should include the following files:
  47.  
  48. pmfloppy.exe     ; executable file
  49. pmfloppy.doc     ; this documentation
  50. pmfloppy.rc      ; main resource file
  51. pmfloppy.c       ; front end source code
  52. pmfloppy.h       ; defines for main program
  53. pmfloppy.def     ; linker definitions file
  54. pmfloppy.ico     ; incredible artwork
  55. copydlgs.c       ; dialog procs source code
  56. copydlgs.dlg     ; resource file for dialog windows
  57. copydlgs.h       ; defines for dialog windows
  58. dskim.c          ; read and write the disk image
  59. dskim.h          ; header for disk image
  60. makefile         ; NMAKE makefile
  61. dskcpy2a.zip     ; Brady's original program - requires PKUNZIP 1.02 or higher
  62.  
  63. If all these files are not present, please feel free to request the complete
  64. file set.  I am currently on Internet at gregb@pro-lep.cts.com.
  65.  
  66.  
  67. III.  Running PMFloppy
  68.  
  69. When PMFloppy is running, you are faced with a simple menu bar.  You can select
  70. Disk, Image, or Exit.  At the bottom of the window, the status of the "images"
  71. is displayed.  Images are the internal representations of the data on the
  72. disk, as well as some information about the disk itself.  At program start,
  73. all images will be empty, and the status will reflect that.  You should never
  74. see an empty screen.
  75.  
  76. If you select Disk, a drop-down menu will give you three options: Read, Write,
  77. and About.  The Read option allows you to read a disk into an image.  The
  78. Write option will allow you to write an image back out to a floppy disk.  The
  79. About option pops up an about box containing copyright information and the
  80. current version number.  At program start, the Write option will not be
  81. selectable, because there are no images to write.
  82.  
  83. The Image selection produces a drop-down menu with four options: Load, Save,
  84. Delete, and Compare.  The Load option allows you to load an image from a file
  85. on a disk, and the Save option will produce one of those files from an image.
  86. The Delete option allows you to remove an image from memory.  This _will_not_
  87. erase any files from any disk.  The program has room for twenty images, and if
  88. you use all of those, or if you run out of swap space, you may need to delete
  89. one or more of the images already loaded.  The Compare option allows you to
  90. compare two images.
  91.  
  92. Keyboard Accellerators have been set for all drop-down menu items.  To bypass
  93. the menus, use the control key and the first letter of the option you want to
  94. invoke.  For example, to read a disk into memory, hit ^R (control-R).
  95.  
  96. All of the dialog boxes that you will see bear certain features in common.  All
  97. have OK and Cancel buttons.  If the OK button is clicked when an incorrect
  98. value has been entered for one of the fields, a message box will be displayed
  99. to tell you what the program doesn't like.  Many of these boxes also have
  100. suggestions for correcting the error.
  101.  
  102. In any situation where there is a list box (a box with a single vertical scroll
  103. bar), there will invariably be an edit box directly above it.  You may enter
  104. text in any edit box.  You can only select text from a list box.  There are two
  105. types of scroll box-edit box combinations in the program, the image set, and 
  106. the file set.
  107.  
  108. The first is the image set.  You may enter an image name into the image edit
  109. field, or select an existing image from the list box.  A single click on a name
  110. from the list box will move that name to the edit box, and a double click
  111. selects that name and exits the dialog.  This is the same as a single click
  112. each on the list box and then on the OK button.  If the program detects an
  113. error, an appropriate message will be displayed.
  114.  
  115. Next is the file set.  In the file set, there are two list boxes side by side,
  116. and two boxes above - one for editting and one for display only.  The display
  117. box will show the current directory and can only be changed by double-clicking
  118. on an entry in the left list box.  The edit box displays the current file.  You
  119. can either type in a file name, or select one from the right list box.  Double
  120. clicking in the right list box is the same as a single click on the list box
  121. and then on the OK button.
  122.  
  123.  
  124.  
  125. IV.  Notes
  126. Changes from 2.02
  127.   o port to C Set/2
  128.  
  129. Changes from 1.00
  130.   o Multiple buffers
  131.   o Load, Save, Delete, and Compare functions
  132.   o better management of threads
  133.   o better memory usage
  134.   o better usage of messages
  135.   o removed multiple access to a single image
  136.   o removed format teaser
  137.  
  138. Known Anomolies 
  139.   o an error during a drive read or write will leave the status display in an
  140.     uncertain condition.
  141.   o opening the drive door during a disk operation doesn't bring up an error
  142.     until it's closed again.  This is due to the way the driver handles the
  143.     "disk change" line rather than an actual bug in the program.
  144.  
  145. some thoughts for the future:
  146.   o show graphically the percentage done (modify the DisplayStatus routine)
  147.   o anonymous copies (no explicit image) disk-to-disk or disk-to-file.
  148.   o compress the disk image as saved to a file.
  149.   o provide a Format option
  150.  
  151. This program was compiled with IBM C Set/2 running under OS/2
  152. 2.0+service pack on a DTK 386/33.
  153.  
  154.  
  155.  
  156. V.   Technical Discussion
  157.  
  158. Version 1.0
  159.  
  160. The changes to Brady's code are relatively minor.  Apparently the
  161. BIOSPARAMETERBLOCK bug has been fixed in 1.2, because my header file matches
  162. what he had defined locally.  Since they were the same, I removed the local
  163. copy.  The OpenDrive funtion has been integrated into the disk functions.
  164. This is to keep the drive handles local to the thread.  Also, errors are now
  165. handled through a common error handler, which posts a message to the parent
  166. window - this is because background threads aren't allowed into the
  167. presentation space (or, if they are, it wasn't obvious to me).  Thus, I have
  168. three classes of messages being passed forward - Error, Status, and General.
  169. Currently the "General" messages are only passing Done up, but I wanted to
  170. leave it open for future use.
  171.  
  172. Ah, the format.  This has caused me quite a bit of pain.  I really thought I
  173. had this one beaten, but I'm out of "play time", and it still doesn't work.
  174. If you enable the menu option (in the WM_INITMENU case for the main window),
  175. you can see what it does currently.  It will go through the disk, formatting
  176. each track (and dieing on errors - perfect disks only).  It will then build
  177. the root track based on an algorithm from Writing OS/2 Device Drivers (by
  178. Raymond Westwater, Addison-Wesley, p. 496), but when I go to write out the
  179. track, the IOCtl returns an invalid parameter.  Other unsolved format issues
  180. involve detecting a low density disk (unformatted) in a high density drive.
  181. I leave the resolution to this problem as an exercise to the reader.
  182.  
  183. Having only recently come to the OS/2 world (from a wide variety of other OSs),
  184. and being relatively unwashed in the intricacies of MSC and PM, I ran into
  185. a few oddities only to be resolved by Spy and Logitech's Multiscope.  These I
  186. thought I would share, hopefully to prevent others from following the same
  187. road.  First, the disappearing window.  When I got to the point that my
  188. main window was coming up fine, and I was spinning off threads that didn't do
  189. anything beyond opening the drive, I added the first real task - the IOCtl to
  190. get the BPB, and then calculate the disk parameters.  This is just straight
  191. out of what Brady had done, so I felt relatively secure.  Well, for some 
  192. reason, shortly after the IOCtl, the window would close and the program would
  193. shut down.  No messages, no warnings, no phone calls, just gone.  I set Spy
  194. to work, and found that my window was receiving a WM_DESTROY message.  Well,
  195. I certainly wasn't sending it, so it had to be PM.  According to multiscope,
  196. I was just doing some assignment statements in my background thread when it
  197. died.  Not til I looked closely at the assignments did I realize there was a
  198. divide by zero.
  199.  
  200. Conclusion 1: Certain run-time errors will cause a PM app to shut down without
  201.               warning.
  202.  
  203. Now, why was there a divide by zero?  This was just straight out of Brady's
  204. original program.  I went back and recompiled his code under my make, and 
  205. found that his did the same thing.  Again, multiscope to the rescue,  the
  206. IOCtl was returning fine, the data was there and fine, but the structure wasn't
  207. interpreting it correctly.  Linker alignment?  No, actually compiler alignment.
  208. As I said, I'm new to MSC, and they have a -Zp parameter for packing.  Not 
  209. that it's documented anywhere on the IOCtl call, but Brady's program used it,
  210. and when I created my make, I left it off.  Problem solved.
  211.  
  212. Conclusion 2:  Beware of compiler alignment as well as Linker alignment.
  213.  
  214. The invisible dialog:  This one was actually simple, but again, it might save
  215. someone a few minutes.  A couple times I had dialog boxes that looked fine,
  216. all the code was in place, but they just wouldn't appear.  It turned out that
  217. one of my resource IDs was incorrect in the .DLG file.  Nobody would complain,
  218. but they also wouldn't comply.
  219.  
  220. PM programming is actually quite interesting.  The quality of the tools is
  221. very good.  I've been playing recently with other programs, like Smalltalk/V
  222. PM and Object/1.  I've done some great prototypes very quickly with ST/V, but
  223. both products seem to need to mature a bit in the PM world.  Thanks again to
  224. Brady Flowers for the disk handling routines. Now I'd better get back to
  225. something that'll make the company money - unfortunately, I can't spend all
  226. my time just learning about the new stuff.
  227.  
  228. Version 2.0
  229.  
  230. You may have noticed that the format option is gone.  Completely.  If I get
  231. new information, I may try it again, put I decided it was silly to have two
  232. versions go by with the same teaser.
  233.  
  234. I've made two main design changes in the program.  The first is the primary
  235. data structures.  There are now two.  First is the Thread Context structure.
  236. This allows me to keep track of errors and threads.  The second is the Disk
  237. Image.  This stores status information about the image as well as the disk
  238. data itself.  They are relatively straight forward.  The second main change
  239. involves memory allocation.  In Brady's original code, he was allocating 
  240. space on a track-by-track basis.  However, when you try to allocate pointers
  241. for more than two disks (at 160 per disk), things start to get lost.  For
  242. some reason, around track 120 on the third disk (not a consistent location),
  243. the program would GP fault during the read.  Not during the allocate - that
  244. (seemingly) worked fine.  So I ended up doing a single allocation for each
  245. disk via the DosAllocHuge.  For a 1.44MB floppy, this means 23 selectors per
  246. disk.  You'll notice I have two new routines - one to do the allocation and
  247. one to create a pointer for each track.  If you're working with something like
  248. this that has many parts, these two routines (or a variation thereon) should
  249. come in handy.
  250.  
  251. The only bug I found in version 1.0 involved not releasing stack memory after
  252. a thread had completed.  As the fix was part of the data structure redesign,
  253. I decided not to do a point release, but just point out that it has been
  254. corrected.  The fix also brought out a shortcoming in Thread Management.  I
  255. needed a way to wait until a background had completely died before freeing
  256. its stack allocation.  Without some kind of wait, the foreground thread would
  257. often beat the background thread, so when the BG thread went to exit, it no
  258. longer had an execution context, causing a GP fault.  Since the only wait
  259. functions are for child processes rather than threads (and they don't work for
  260. threads, I tried), I ended up doing a busy wait, checking the thread's
  261. priority.  It's not real pretty, but it does work.  I'm open to a more elegant
  262. solution, however.
  263.  
  264. I've changed the user defined messages to a simpler design, one I think is a
  265. bit more elegant than the brute-force method I used in 1.00.  The General
  266. message is now an official "Done" message, and the Status and Error messages
  267. are now generic to all background operations.  There are two new messages 
  268. being used for Compare.  Compare is a very special case, because it uses two
  269. images, where all other operations use one.  This compromised me design a
  270. little, but I think inclusion of the function was worth it.
  271.  
  272. A further note on the disappearing dialog from version 1.  I've noticed that
  273. if any resources that a program expects are not present, it just doesn't run.
  274. Again, no messages.  I noticed this on a commercial package that required its
  275. own font.  At first I forgot to install the font.  The program wouldn't run,
  276. and OS/2 wouldn't tell me why it wouldn't.
  277.  
  278. Incidentally, there is a typo in Quickhelp in the Memory Manager Overview
  279. section.  The example shows the digit two being shifted by the shift count.
  280. It should be a one.  The text preceeding the example is correct.
  281.  
  282. Version 2.01
  283.  
  284. Discovered that you couldn't use the keyboard to select a directory.
  285.  
  286. Version 2.02
  287.  
  288. An incorrect check of the Busy flag in the WriteDlgProc prevented a buffer
  289. from ever being written.  I had changed my busy checks several times, and
  290. this one must have slipped by.  Actually found by someone in our QA group
  291. here.  On a non-compare thread, FreeThread would overrun the ImageBuffers
  292. array.  This didn't *appear* to be causing any problems, but I'd rather be
  293. safe . . .
  294.  
  295. It seems the latest PM driver from MS (177) cares a little more about the
  296. EXPORTS statement in the DEF file.  I didn't have all my dialog procs exported,
  297. and under earlier versions, it worked fine.  Now, however, if I try to call
  298. a proc via the WinCreateWindow, or any of its derivatives, that hasn't been
  299. exported, the entire system starts beeping and locks up.  The mouse responds,
  300. but the app locks - I don't even get the 10 second timeout from Switch To.
  301.  
  302. Version 3.00
  303.  
  304. Ported to OS/2 2.0 and C Set/2.  Nothing strange, just the usual
  305. assortment of USHORTs becoming ULONGs, and of course the parameter
  306. changes for DosDevIOCtl.
  307.