From: pottier@clipper.ens.fr (Francois Pottier) Subject: csmp-digest-v3-028 Date: Wed, 18 May 94 14:13:10 MET DST C.S.M.P. Digest Wed, 18 May 94 Volume 3 : Issue 28 Today's Topics: CRC-16 routine in C for native code CodeWarrior Gold Education Price How to write a bullet-proof lib? PixMap to mask Posting an event to another application? Shared memory... Unmounting all volumes? The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier (pottier@clipper.ens.fr). The digest is a collection of article threads from the internet newsgroup comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi- regularly and want an archive of the discussions. If you don't know what a newsgroup is, you probably don't have access to it. Ask your systems administrator(s) for details. If you don't have access to news, you may still be able to post messages to the group by using a mail server like anon.penet.fi (mail help@anon.penet.fi for more information). Each issue of the digest contains one or more sets of articles (called threads), with each set corresponding to a 'discussion' of a particular subject. The articles are not edited; all articles included in this digest are in their original posted form (as received by our news server at nef.ens.fr). Article threads are not added to the digest until the last article added to the thread is at least two weeks old (this is to ensure that the thread is dead before adding it to the digest). Article threads that consist of only one message are generally not included in the digest. The digest is officially distributed by two means, by email and ftp. If you want to receive the digest by mail, send email to listserv@ens.fr with no subject and one of the following commands as body: help Sends you a summary of commands subscribe csmp-digest Your Name Adds you to the mailing list signoff csmp-digest Removes you from the list Once you have subscribed, you will automatically receive each new issue as it is created. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest. Questions related to the ftp site should be directed to scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP digest are available there. Also, the digests are available to WAIS users as comp.sys.mac.programmer.src. ------------------------------------------------------- >From satcomm@aol.com (SatComm) Subject: CRC-16 routine in C for native code Date: 30 Apr 1994 14:40:08 -0400 Organization: America Online, Inc. (1-800-827-6364) I'm looking to replace some old code in assembly that calculated the standard Xmodem/MacBinary CRC-16 stuff. Unfortunately, I think I threw away all remnants of my CRC stuff when I discovered the assembly routine. Does anyone have a CRC routine for this in C? Thanks. satcomm@aol.com +++++++++++++++++++++++++++ >From david@oahu.cs.ucla.edu (David Dantowitz) Date: Sun, 01 May 94 16:36:57 GMT Organization: UCLA, Computer Science Department Here's some code and information on CRCs I put together some years back. It is in the public domain. David - --------- cut here -------------- /* Computing CRCs This set of implementations was written by David M. Dantowitz, and has been placed in the public domain, to be used at the user's discretion. The original code was implemented in Turbo Pascal 3.0 this submission is a version written in C. This program demonstrates various ways by which Cyclic Redundancy Checks (CRC) may be computed and their relative speeds. CRC polynomials in this program are represented by replacing each term that is non-zero with a 1 and each zero term with a 0. Note that the highest order bits represent the low order terms of the polynomial. Thus X^3+X^1+1 becomes 1101 and X^4+X^1+1 becomes 11001. Now, since all polynomials have a highest term (X^a) we drop the highest term during computation (shift right one bit, dropping the low bit). Here are some examples of conversion from symbolic to binary representation (but not necessarily polynomials with desirable CRC properties): Polynomial Representation Hex X^5 + X^2 + 1 10100 $14 X^7 + 1 1000000 $40 X^3+X^2+X^1+1 111 $7 X^6+X^5+X^3+1 100101 $25 For a good discussion of polynomial selection see "Cyclic Codes for Error Detection", by W. W. Peterson and D. T. Brown, Proceedings of the IEEE, volume 49, pp 228-235, January 1961. A reference on table driven CRC computation is "A Cyclic Redundancy Checking (CRC) Algorithm" by A. B. Marton and T. K. Frambs, The Honeywell Computer Journal, volume 5, number 3, 1971. Also used to prepare these examples was "Computer Networks", by Andrew S. Tanenbaum, Prentice Hall, Inc. Englewood Cliffs, New Jersey, 1981. The following four polynomials are international standards: CRC-12 = X^12 + X^11 + X^3 + X^2 + X^1 + 1 CRC-16 = X^16 + X^15 + X^2 + 1 CRC-CCITT = X^16 + X^12 + X^5 + 1 CCITT-32 = X^32 + X^26 + X^23 + X^22 + X^16 + X^12 + X^11 + X^10 + X^8 + X^7 + X^5 + X^4 + X^2 + X^1 + 1 In Binary and hexadecimal : Binary Hex CRC-12 = 1111 0000 0001 $0F01 CRC-16 = 1010 0000 0000 0001 $A001 CRC-CCITT = 1000 0100 0000 1000 $8404 (Used below) CCITT-32 = 1110 1101 1011 1000 1000 0011 0010 0000 $EDB88320 The first is used with 6-bit characters and the second two with 8-bit characters. All of the above will detect any odd number of errors. The second two will catch all 16-bit bursts, a high percentage of 17-bit bursts (~99.997%) and also a large percentage of 18-bit or larger bursts (~99.998%). The paper mentioned above (Peterson and Brown) discusses how to compute the statistics presented which have been quoted from Tanenbaum. (A burst of length N is defined a sequence of N bits, where the first and last bits are incorrect and the bits in the middle are any possible combination of correct and incorrect. See the paper by Peterson and Brown for more information) Note that when using a polynomial of degree N, the CRC is the first N bits of the value returned by the routines below. (e.g. with CRC-12, the CRC is bits 0 to 11 of the CRC value, with the other two mentioned above, the CRC is all 16 bits.) Here is a quick idea of what is being calculated ... The CRC is the residual from division of the data stream by the CRC polynomial. The data stream is also thought of as a polynomial, with the highest order term being the lowest bit of the first byte of the data stream and the lowest order term of the polynomial being the high bit of the last byte of data. The actual division is performed on the data stream polynomial multiplied by X^y where y is the degree of the CRC polynomial. All math used to compute CRCs is done modulo 2. This means the following relationships are used: 0+0=0 0+1=1 1+0=1 1+1=0 (XOR) 0-0=0 0-1=1 1-0=1 1-1=0 (XOR) 0*0=0 0*1=0 1*0=0 1*1=1 (AND) Thus addition and subtraction have NO carries or borrows. Here is a sample computation showing the actual division. Polynomial = X^4+X^3+1; Data = $94. The division performed is 1001 into 0010 1001. Notice that the highest order terms of the data polynomial are the lowest order bits of the data stream. We will also multiply the dividend by X^4 as noted above: 1011011 - The quotient is not important and is discarded. 1001/001010010000 -1001 ---- The extra 0s result from multiplying the data by X^4 ---- 1101 <-- The code below calculates this value -1001 ---- 1000 -1001 ---- 1000 -1001 ---- 0001 This is the CRC (the residual from the division)! The code below does not shift the data by the number of bits equal to the degree of the CRC polynomial. There is no ill effect caused by not doing this multiply. Now, the result of the CRC computation is just the residue from the division of the data by the CRC. None of the routines below appear to compute a division. In the example above the subtractions are really XORs (pronounced exclusive OR). XOR has the same behavior as +/- in modulo two arithmetic, so it is used in the computations. The first CRC routine below (Simple_CRC) models the computation lucidly. The other routines use various optimization techniques to speed the computation. CRC use ... The CRC is appended to the end of the original data stream (or stored separetely). When the receiver gets the data stream, the CRC is again computed and matched against the received CRC, if the two do not match then an error has most likely occurred. My address is David Dantowitz Dantowitz Consulting and Research P.O. Box 8105 Englewood, NJ 07631 (201) Low-Bug-C AppleLink: Dantowitz */ #include #include #define INITIAL_CRC 0xFFFFFFFF /* This result was obtained by calling make_crc_table(0xedb88320). */ int crc_table[16] = { 0x00000000, 0xfdb71064, 0xfb6e20c8, 0x06d930ac, 0xf6dc4190, 0x0b6b51f4, 0x0db26158, 0xf005713c, 0xedb88320, 0x100f9344, 0x16d6a3e8, 0xeb61b38c, 0x1b64c2b0, 0xe6d3d2d4, 0xe00ae278, 0x1dbdf21c }; make_crc_table(crc_poly) int crc_poly; { int i, val, result; for (val = 0; val < 16; val++) { result = val; for (i = 0; i < 4; i++) if (result & 1) result = (result >> 1) ^ crc_poly; else result >>= 1; crc_table[val] = result; printf("0x%08lx\n", result); } } int compute_crc(old_crc, s, len) int old_crc; char *s; int len; { int i; for (i = 0; i < len; i++) { /* XOR in the data. */ old_crc ^= s[i]; /* Perform the XORing for each nybble */ old_crc = (old_crc >> 4) ^ crc_table[old_crc & 0x0f]; old_crc = (old_crc >> 4) ^ crc_table[old_crc & 0x0f]; } return (old_crc); } main() { char line[100]; int crc_val; int len; /* make_crc_table(0xedb88320); done at compile time... */ /* initialize the crc -- start with this value each time you start a session. */ crc_val = INITIAL_CRC; strcpy(line, "This will test the crc function"); len = strlen(line); crc_val = compute_crc(crc_val, line, len); /* let's add MORE text to the CRC -- they can be cumulative across many blocks of data. */ strcpy(line, "More text to add"); len = strlen(line); crc_val = compute_crc(crc_val, line, len); } -- David Dantowitz david@cs.ucla.edu Singing Barbershop when I'm not doing parallel simulation +++++++++++++++++++++++++++ >From Bruce@hoult.actrix.gen.nz (Bruce Hoult) Date: Mon, 2 May 1994 18:51:22 +1200 (NZST) Organization: (none) satcomm@aol.com (SatComm) writes: > I'm looking to replace some old code in assembly that calculated the standard > Xmodem/MacBinary CRC-16 stuff. Unfortunately, I think I threw away all > remnants of my CRC stuff when I discovered the assembly routine. Does anyone > have a CRC routine for this in C? Here's a routine for checking the Macbinary header CRC. I'm not sure what XModem uses: - -------------- #define CCITT_CRC_GEN 0x1021 short CalcCRC(register unsigned char *dataBuf, register long size) { register unsigned short crc = 0; register unsigned short dataByte; register long i; while (size--) { dataByte = *dataBuf++ << 8; for (i = 8; i > 0; i--) { if ((dataByte ^ crc) & 0x8000) crc = (crc << 1) ^ CCITT_CRC_GEN; else crc <<= 1 ; dataByte <<= 1; } } return(crc); } - -------------- For my own use, I've recoded it slightly in a way that gives much better code on unsophisticated compilers such as MPW C. I was able to alternate operations on different data, which should probably help a little on pipelined CPUs (I don't know how much), and spelling things out a little more explicitely stopped a lot of data moves etc that weren't needed. Treating C as a two-address assembly language seems to help many compilers a lot... :-) - -------------- #define CCITT_CRC_GEN 0x1021 short CalcCRC(register unsigned char *dataBuf, register long size) { register unsigned long crc = 0; register unsigned long dataByte; register long i; while (--size >= 0) { dataByte = *dataBuf++; dataByte <<= 8; i = 8; do { register long bit = dataByte; dataByte += dataByte; bit ^= crc; crc += crc; if (bit &= 0x8000) crc ^= CCITT_CRC_GEN; } while (--i); } return crc; } - -------------- +++++++++++++++++++++++++++ >From Bruce@hoult.actrix.gen.nz (Bruce Hoult) Date: Mon, 2 May 1994 19:15:41 +1200 (NZST) Organization: (none) satcomm@aol.com (SatComm) writes: > I'm looking to replace some old code in assembly that calculated the standard > Xmodem/MacBinary CRC-16 stuff. Unfortunately, I think I threw away all > remnants of my CRC stuff when I discovered the assembly routine. Does anyone > have a CRC routine for this in C? Further to my last post, and to (hopefully) forstall email, yes I am aware that a bit-by-bit algorithm for CRC isn't the fastest way to do it, no matter how efficiently coded. It was good enough for my purpose (which was checking a smallish Macbinary header), and I was more interested in code size than in speed (for reasons I won't go into...). -- Bruce --------------------------- >From cvafy002@csupomona.edu Subject: CodeWarrior Gold Education Price Date: 25 Apr 94 14:32:09 PST Organization: California State Polytechnic University, Pomona I have a friend who'd like to get CodeWarrior Gold at the education price (I read it was $99). How would he go about getting it? He doesn't have internet access. How can he find out if his College and/or he qualifies? +++++++++++++++++++++++++++ >From mwron@aol.com (MW Ron) Date: 27 Apr 1994 21:16:03 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <1994Apr25.143209.1@clstac>, cvafy002@csupomona.edu writes: >>I have a friend who'd like to get CodeWarrior Gold at the education price (I read it was $99). How would he go about getting it? He doesn't have internet access. How can he find out if his College and/or he qualifies? I think this will be helpful to all of you strugling students. For educational prices, BookMasters is our distributor and their phone number is 1-800-247-6553 in the US. Educational pricing is as such: Gold $99.00 US Silver $79.00 US Bronze $59.00 US $15.00 shipping and handling US orders. You must fax BookMasters proof that you are either a student or officially affilliated with a University. Their fax number is(419) 281-6883. Ron Liechty mwron@aol.com Metrowerks Inc. +++++++++++++++++++++++++++ >From cs2ev@herts.ac.uk (Mas) Date: 28 Apr 1994 17:29:59 +0100 Organization: University of Hertfordshire Dear all Please do tell me the difference between gold, silver & bronze versions of codewarrior. Thanks Andre-John MAS +++++++++++++++++++++++++++ >From mwron@aol.com (MW Ron) Date: 28 Apr 1994 20:46:02 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <2pooa7$dej@altair.herts.ac.uk>, cs2ev@herts.ac.uk (Mas) writes: Please do tell me the difference between gold, silver & bronze versions of codewarrior. >>GOLD Includes all for 68K Macintosh and Power Macintosh as well as 68K-hosted PowerPC compilers. SILVER Includes all for PowerPC Only (no 68K Macintosh compilers or linkers) BRONZE Includes all for 68K Macintosh (no PowerPC compilers or linkers) Ron Liechty mwron@aol.com Metrowerks Inc. +++++++++++++++++++++++++++ >From zee@fwi.uva.nl (Daniel vd Zee) Date: 3 May 1994 14:15:03 GMT Organization: FWI, University of Amsterdam mwron@aol.com (MW Ron) writes: >For educational prices, BookMasters is our distributor and their phone number >is 1-800-247-6553 in the US. Educational pricing is as such: > > Gold $99.00 US > Silver $79.00 US > Bronze $59.00 US > >$15.00 shipping and handling US orders. How about non-US students, are the pricing and the distributor the same and do i have to get some kind of internalional student card to order? Thanx, Daniel (zee@fwi.uva.nl) +++++++++++++++++++++++++++ >From mwron@aol.com (MW Ron) Date: 4 May 1994 17:10:03 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <2q5m97$4dv@hermes.fwi.uva.nl>, zee@fwi.uva.nl (Daniel vd Zee) writes: >> How about non-US students, are the pricing and the distributor the same and do i have to get some kind of internalional student card to order? I do not know if we have or do not have any international educational discounts you would have to contact one of the following to find out what the item is in your particular country. Japan - B.U.G. in Sapporo, Applelink = BUGPLAN.DVJ Australia - Techflow in Australia, Applelink = TECHFLOW Germay - pandasoft in Berlin, Germany, telephone= (49) 3031 5913 16 All others, BookMasters U.S./Canada: 1-800-247-6553 International: 1-419-281-1802 Fax No.: 1-419-281-6883 Everywhere else in the world, including Europe out of Germany should be taken direct through our distributor BookMasters. Ron Liechty mwron@aol.com Metrowerks Inc. +++++++++++++++++++++++++++ >From neeri@iis.ee.ethz.ch (Matthias Neeracher) Date: 4 May 1994 22:34:08 GMT Organization: Swiss Federal Institute of Technology (ETHZ) mwron@aol.com (MW Ron) writes: >In article <2q5m97$4dv@hermes.fwi.uva.nl>, zee@fwi.uva.nl (Daniel vd Zee) >writes: >>> How about non-US students, are the pricing and the distributor the same and >do i have to get some kind of internalional student card to order? >I do not know if we have or do not have any international educational >discounts Yes you do. It was no problem getting the Ed. Discount from Switzerland. >All others, BookMasters > Fax No.: 1-419-281-6883 I got my copy of CodeWarrior from BookMasters. All I had to do was to fax them a copy of my Student ID and my credit card number. They messed up the reply to my first fax, but once I had sent the order, I got CW within 4 or 5 working days... well done, BookMasters! Matthias - --- Matthias Neeracher neeri@iis.ee.ethz.ch "Do not mess with any jumper you do not know about even if it is labeled SEX and FREE BEER" -- Dave Haynie --------------------------- >From mpcline@cats.ucsc.edu (Matthew Paul Cline) Subject: How to write a bullet-proof lib? Date: 1 May 1994 23:35:06 GMT Organization: University of California, Santa Cruz I am writing a library for the Mac, and would like it to be bullet-proof. When I say bullet proof, I'm using the term in a paranoid way: if a customer calls up and complains that he/she can't use it to make a desktop accessory, I can't say "Well, Apple recommends against making a desktop accessory"; thus, I am not using any global variables in the library (the only thing I know programming a desktop accessory). Given my level of paranoia, is it possible to make a bullet-proof library? Or can I just get cloose to bullet-proof? Any help would be appreciated. P.S.: Am I being paranoid, or is this the way you should go about making a library? -- X-phile, GATB Have you hugged your shoggoth today? GE d? p c++(+++) l++ u++ e+ m+ s/- n+(-) h+ f !g w+ t+ r y+ +++++++++++++++++++++++++++ >From Matt Slot Date: 2 May 1994 07:15:30 GMT Organization: University of Michigan Matthew Paul Cline, mpcline@cats.ucsc.edu writes: >P.S.: Am I being paranoid, or is this the way you should go about >making a library? I dont think its paranoid to put something out that you feel is stable enough for others to want to use. If I get a library that I think isn't of good quality or has some bugs in it, I dont feel comfortable putting it into my own software. When I wrote my Gamma Libs, I tried to test it on as many computers as I could and make it work for the widest audience possible. These are the things I learned: * Use simple interfaces and explain them well enough that others can use them easily. Calling a function with wrong information is an easy way to make anything barf. * Comment the rest of your code (if provided) so users can see what you are trying to do and can make improvments/changes as fits their needs. (And bug feedback is much easier too) * Use the best programming styles and follow the books, technotes and advice you can find to make the software as compatible for future versions. * Use Gestalt and other calls make sure you are able to run in a given environment and that your memory calls succeed. Returning error codes is very important. * Try it out in a test app (making a demo program with source is really nice), and run it with various system configurations and extensions. Clearly define a minimum system that you require, such as Mac Plus, System 6 or 7, or Color QD. * Run it with heap scrambling and Even Better Bus Error. A user trying to use software with my library complained that EBBE flagged it... and it helped me to clean up some skanky pointer arithmetic. * Look for testers who will give you feedback before you make the libs public... so you dont get your lib branded before it gets popular. * Beg for programmer and user feedback, and try to work with others who come to you with odd problems. Hope this helps... good luck with your library. Matt +++++++++++++++++++++++++++ >From gurgle@netcom.com (Pete Gontier) Date: Mon, 2 May 1994 07:01:34 GMT Organization: cellular mpcline@cats.ucsc.edu (Matthew Paul Cline) writes: >I am writing a library for the Mac, and would like it to be >bullet-proof. ...thus, I am not using any global variables in the >library (the only thing I know programming a desktop accessory). It depends on what your library does, of course; I hope you're allowed to post that so we can consider it. But, in general, you'll have to be careful about some other things as well as global variables. If your library is bigger than 32K, that's as bad as having globals, because any number of segments greater than one causes many of the same problems as global variables. Also be careful about calls which assume a valid A5 world. Many QuickDraw calls, for example, assume they own the A5 world. One alternative which takes care of many problems is to provide two copies of the library, one for A5-based projects (apps) and the other for A4-based projects (everything else). Of course, under MPW, there is no such thing as a code resource which has global variables, so even a separate A4-based lib will not help you there, so it is better to avoid globals altogether. >P.S.: Am I being paranoid, or is this the way you should go about >making a library? Be paranoid. Be very very paranoid. :-) As long as you understand low-level Mac programming, and as long as your boss is happy with the notion of a reasonable beta period, you should be OK. Your testers may not find bugs in your code, but they can probably be counted on to have problems linking your library into their projects, even if you do everything right! :-) Resolving any linking problems they have which are actually your fault won't be half as nasty as any one bug hunt. -- Pete Gontier, CTO, Integer Poet Software; gurgle@netcom.com "Reality is 50 million polygons per second." -- Alvy Ray Smith +++++++++++++++++++++++++++ >From d88-jwa@dront.nada.kth.se (Jon Wätte) Date: 2 May 1994 08:50:58 GMT Organization: The Royal Institute of Technology In <2q29ai$hcl@lastactionhero.rs.itd.umich.edu> Matt Slot writes: > * Use simple interfaces and explain them well enough that others > can use them easily. Calling a function with wrong information > is an easy way to make anything barf. Have a debugging version of your library, which calls Debugger() when it detects inconsistent data, parameters out of range or unexpected return values BEFORE returning them. A simple ASSERT() macro will do this! > * Use Gestalt and other calls make sure you are able to run in > a given environment and that your memory calls succeed. > Returning error codes is very important. Actually, the library probably shouldn't call Gestalt. Maybe a separate little utility rouinte, in source, which just made sure that everything's OK and returned a Boolean. Let the user's code do the checking, for instance by calling your separate utility routine. > * Beg for programmer and user feedback, and try to work with others > who come to you with odd problems. Especially: be responsive, and take every complaint seriously. -- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe (on a Swedish scale) -- There's no problem that can't be solved using brute-force algorithms and a sufficiently fast computer. Ergo, buy more hardware. (NOT!) +++++++++++++++++++++++++++ >From mpcline@cats.ucsc.edu (Matthew Paul Cline) Date: 2 May 1994 17:56:24 GMT Organization: University of California, Santa Cruz In gurgle@netcom.com (Pete Gontier) writes: >mpcline@cats.ucsc.edu (Matthew Paul Cline) writes: >>I am writing a library for the Mac, and would like it to be >>bullet-proof. ...thus, I am not using any global variables in the >>library (the only thing I know programming a desktop accessory). >It depends on what your library does, of course; I hope you're allowed >to post that so we can consider it. It uses the Novell socket library on top of MacTCP. > But, in general, you'll have to be >careful about some other things as well as global variables. Since this is a port of an already existing library, I'm replacing all global variables with static variables local to one file, and then using get_GLOBAL() and set_GLOBAL() type function calls. Does that still have the problem of globals variables? What about staic variables within a procedure? > If your >library is bigger than 32K, that's as bad as having globals, because any >number of segments greater than one causes many of the same problems as >global variables. I was planning on either using pluged-in code resources or using ASLM. Would this also be bad for a library? [snip] >As long as you understand low-level Mac programming. Hmmm, might have a problem here: I'm very new to the Mac. My boss basically hired me and said: "Here, go and learn everything you need to know about the Mac and port our library to it." Do you have any advice on taking a crash course on low-level Mac programming? Thanks in advance. -- X-phile, GATB Have you hugged your shoggoth today? GE d? p c++(+++) l++ u++ e+ m+ s/- n+(-) h+ f !g w+ t+ r y+ +++++++++++++++++++++++++++ >From rmah@panix.com (Robert S. Mah) Date: Mon, 02 May 1994 19:25:06 -0500 Organization: One Step Beyond mpcline@cats.ucsc.edu (Matthew Paul Cline) wrote: > Since this is a port of an already existing library, I'm replacing all > global variables with static variables local to one file, and then > using get_GLOBAL() and set_GLOBAL() type function calls. Does that > still have the problem of globals variables? What about staic variables > within a procedure? Using statics will prevent name space pollution but the variables themselves are still referenced like globals. That is they are accessed via offsets from register a5. This will fall down if the code is being used in drivers, extensions or anything without a proper a5 world. One option is to build two sets of libraries, one compiled using a5 offsets and another using a4 offsets. This is the technique used by Symantec for their ANSI libraries, for example. Cheers, Rob ___________________________________________________________________________ Robert S. Mah -=- One Step Beyond -=- 212-947-6507 -=- rmah@panix.com +++++++++++++++++++++++++++ >From gurgle@netcom.com (Pete Gontier) Date: Tue, 3 May 1994 18:40:42 GMT Organization: cellular mpcline@cats.ucsc.edu (Matthew Paul Cline) writes: >It uses the Novell socket library on top of MacTCP. OK, if you are porting, then you do need to be careful the code you are porting doesn't use any global variables or use the 'static' modifier for variables declared inside functions. It's possible to let the code do these things, depending on the compiler in use, but you do need to be aware of it so you can make sure it works -- or document how to make it work, if it needs to be the caller's responsibility. >Since this is a port of an already existing library, I'm replacing all >global variables with static variables local to one file, and then >using get_GLOBAL() and set_GLOBAL() type function calls. Does that >still have the problem of globals variables? Yes. What your routines are doing is hiding the globals, to a certain extent, and that's marginally good in terms of maintainability. But the machine doesn't care how maintainable your code is. :-) The hidden globals are still globals in terms of where they are stored in memory at run-time, that is at offsets from register A5 (apps) or register A4 (everything else). >What about staic variables within a procedure? Same problem, as I said above. >>If your library is bigger than 32K, that's as bad as having globals, >>because any number of segments greater than one causes many of the >>same problems as global variables. >I was planning on either using pluged-in code resources or using ASLM. >Would this also be bad for a library? I don't know much about ASLM except that it's not available in a fairly large subset of installed Systems. And last I heard, it required MPW C++, but that restriction has probably gone away by now. But, if you are stuffing this code into a code resource, I can tell you you won't have to concern yourself with two different versions of a linkable library file any more. Your project will be A4-based, and you can look up and understand the use of and be done with it. You can also have code larger than 32K without much difficulty. There are a couple of drawbacks to a code resource, though. First, there's the fact that if you want more than one entry point, you must create them yourself. In other words, the calling program should probably call the code resource's main entry point with the understanding that all that will result is a list of other entry points into the code resource. I'm basically talking about a structure full of function pointers here. You will also have to write *another* library to be linked into programs in order to avoid the chore of documenting for others how to call your external code resource. (Believe me, writing this extra library is much better than writing a document about code resources, because people will call you for tech support no matter how good your doc is.) Fortunately, this extra library will probably be simple enough that you can include source code instead of a library file without revealing any trade secrets. TAKE-HOME MESSAGE: I think your best bet is to do linkable libraries. They involve the fewest technical headaches. You'll actually have to do three of them (one for A5, one for A4, and one for PowerPC), but once you have done one, the rest will follow pretty easily. You'll also have a 32K limit on each library file, but you can always do more than one library file for each kind of project. >>As long as you understand low-level Mac programming... >Hmmm, might have a problem here: I'm very new to the Mac. My boss >basically hired me and said: "Here, go and learn everything you need to >know about the Mac and port our library to it." Tell your boss right away that aspects of this project are beyond your field of expertise. The Macintosh issues are fairly simple for a very experienced Mac programmer, but for someone new to the Mac, they can be really ugly and take a lot more time than you would like. It will be especially frustrating if you know all there is to know about the networking aspects of the job and are constrained only by the Mac aspects, because your boss may not understand that. If you tell her now, you'll be able to plan ahead. >Do you have any advice on taking a crash course on low-level Mac >programming? Of course, if there is no way to tell your boss, then you have just embarked on the best low-level Mac programming course there is! Experience: 12 units. Unfortunately, it's also the *only* course. Good luck, and the net will be here when you need it. :-) -- Pete Gontier, CTO, Integer Poet Software; gurgle@netcom.com You thought Obfuscated C was confusing? Wait for Obfuscated C++! --------------------------- >From adamnash@Xenon.Stanford.EDU (Adam Nash) Subject: PixMap to mask Date: 2 May 1994 06:28:05 GMT Organization: Computer Science Department, Stanford University. This may be really simple, but I wanted to check with the net first in case this has been done a better way. I'm converting a PixMap (from a Pict) into a Mask for that item. Now, if you call BitMapToRegion you get a nasty speckle because, it translates anything more than "half white" to white, when I want every non-white pixel to be black. So, I was going to roll my own PixMapToMask, which went through the pixel data and every time it hit a value > 0, it would put a black pixel in a temporary BitMap, then call BitMapToRgn. What do you think, all you sprite and offscreen gurus out there? -Adam +++++++++++++++++++++++++++ >From daniel@unx.al.alcoa.com (David L. Daniel) Date: 2 May 1994 13:51:41 GMT Organization: Alcoa In article <2q26hl$f72@Times.Stanford.EDU>, adamnash@Xenon.Stanford.EDU (Adam Nash) wrote: > > So, I was going to roll my own PixMapToMask, which went through the > pixel data and every time it hit a value > 0, it would put a black pixel in > a temporary BitMap, then call BitMapToRgn. You could try using SeedCFill and CalcCMask, but I have had lots of trouble using these - not just understanding them (which can be difficult), but also with inconsistent results. Others have expressed similar problems. Here is some code that I use to do what you want. No guarantees, but it seems to work for me. The argument "ignoreColor" is the pixel value that you want to be ignored in creating a mask. Good luck. /* ###################################################################### */ /* Make a mask for a PixMap (put it into a BitMap). */ void MakeMask(unsigned char ignoreColor, PixMapHandle pmHndl, BitMapHandle bmHndl) { short i,j,k,bmBytes,pmBytes,bmBit,cols,rows; unsigned char *bmPtr,*pmPtr; cols = (**pmHndl).bounds.right - (**pmHndl).bounds.left; rows = (**pmHndl).bounds.bottom - (**pmHndl).bounds.top; /*if the image rectangles are not the same dimensions, then return an error*/ if( ( cols != ((**bmHndl).bounds.right - (**bmHndl).bounds.left)) || ( rows != ((**bmHndl).bounds.bottom - (**bmHndl).bounds.top)) ) return; /*Get the number of rowBytes for each image*/ pmBytes = (0x1fff & (**pmHndl).rowBytes); bmBytes = (**bmHndl).rowBytes; /*Determine the starting address for the rectangles in each image*/ pmPtr=(unsigned char*) ((**pmHndl).baseAddr + pmBytes*(**pmHndl).bounds.top + (**pmHndl).bounds.left); bmPtr=(unsigned char*) ((**bmHndl).baseAddr + bmBytes*(**bmHndl).bounds.top + (short)((**bmHndl).bounds.left / 8) ); /*Get the number of bytes to increment at the end of a row for each image*/ bmBit = (**bmHndl).bounds.left % 8; /*the starting bit for the bitmap*/ pmBytes -= cols; bmBytes -= (short)( (cols + bmBit - 1) / 8); bmBit = 7 - bmBit; /*image bits are reversed from the order they are counted*/ /*Loop through each row of the images*/ for(i=0; iFrom Dwayne Knowles Subject: Posting an event to another application? Date: Tue, 03 May 94 01:23:48 +1200 Organization: Society for the Prevention of Cruelty to Hobbits Is there a way to post an event to another application - eg. a keydown event, without writing my own version of postEvent? I realise this is probably going to break with future system releases and is very uncool in general but I would like to be able to control an application remotely that isn't scriptable or anything. Is this possible? Thanks. -- +++++++++++++++++++++++++++ >From mkb@remarque.berkeley.edu (Mike Brodhead) Date: 2 May 1994 17:47:02 GMT Organization: STEDT Project, Dept. o' Linguistics, UCBerkeley In article <94050301234800677@bagend.nacjack.gen.nz>, Dwayne Knowles wrote: > > Is there a way to post an event to another application - eg. a keydown > event, without writing my own version of postEvent? I realise this is > probably going to break with future system releases and is very uncool in > general but I would like to be able to control an application remotely that > isn't scriptable or anything. Is this possible? > > Thanks. > > -- I doubt you could do this easily from an app, but an INIT can surely do it. Witness QuickKeys. In fact, you would probably be better off installing QK on the machine and sending Apple Events to QK than doing everything from scratch. (I'm asuming this is for in-house use.) If you want to code it yourself, you'll have to use the process manager to check that the apropriate app is in the foreground before calling PostEvent(). You could even force the app to the foreground. __________________________________________________________________________ Mike Brodhead (New! .sig now 33% shorter!) +++++++++++++++++++++++++++ >From Bruce@hoult.actrix.gen.nz (Bruce Hoult) Date: Tue, 3 May 1994 14:15:05 +1200 (NZST) Organization: (none) Dwayne Knowles writes: > Is there a way to post an event to another application - eg. a keydown > event, without writing my own version of postEvent? I realise this is > probably going to break with future system releases and is very uncool in > general but I would like to be able to control an application remotely that > isn't scriptable or anything. Is this possible? There is only one queue for mouse-downs, keydowns etc, and the frontmost application always gets them -- if you want to post events for a particular application then move it to the front (using the process manager) and then use PostEvent in the normal way... +++++++++++++++++++++++++++ >From Dwayne Knowles Date: Thu, 05 May 94 01:46:59 +1200 Organization: Society for the Prevention of Cruelty to Hobbits In article , Mike Brodhead writes: > > I doubt you could do this easily from an app, but an INIT can surely > do it. Witness QuickKeys. In fact, you would probably be better off > installing QK on the machine and sending Apple Events to QK than doing > everything from scratch. (I'm asuming this is for in-house use.) > > If you want to code it yourself, you'll have to use the process manager > to check that the apropriate app is in the foreground before calling > PostEvent(). You could even force the app to the foreground. > There are several problems with this however. The receiving app has to be forced into the foreground, and more importantly, postEvent doesn't let me post a keyDown event with the command key as a modifier - eg. post a menu key event. Unfortunately I don't have Quickeys. -- +++++++++++++++++++++++++++ >From jeremyr@dcs.qmw.ac.uk (Jeremy Roussak;Guest of Distributed Systems Lab) Date: Wed, 4 May 1994 21:04:28 GMT Organization: Computer Science Dept, QMW, University of London >> If you want to code it yourself, you'll have to use the process manager >> to check that the apropriate app is in the foreground before calling >> PostEvent(). You could even force the app to the foreground. >There are several problems with this however. The receiving app has to be >forced into the foreground, and more importantly, postEvent doesn't let me >post a keyDown event with the command key as a modifier - eg. post a menu >key event. There's no way around forcing the app to the front, since, as has been pointed out before, there's only one event queue and all the events in it go to the frontmost app. However, you can easily post an event with a specific set of modifiers: use PPostEvent, which returns a pointer to the queue element, and then modify the modifiers field. Jeremy +++++++++++++++++++++++++++ >From mkb@remarque.berkeley.edu (Mike Brodhead) Date: 5 May 1994 01:56:34 GMT Organization: STEDT Project, Dept. o' Linguistics, UCBerkeley In article , jeremyr@dcs.qmw.ac.uk (Jeremy Roussak;Guest of Distributed Systems Lab) wrote: > However, you can easily post an event with a specific set of > modifiers: use PPostEvent, which returns a pointer to the queue > element, and then modify the modifiers field. This is true. Still, if QuickKeys will do the job it is probably a lot more cost effective to use it. Divide the cost of QK by the number of hours you expect to spend coding. (Don't forget Hofstadter's law :) What is your desired end result? What will your code accomplish? Who will use it? __________________________________________________________________________ Mike Brodhead (New! .sig now 33% shorter!) +++++++++++++++++++++++++++ >From Bruce@hoult.actrix.gen.nz (Bruce Hoult) Date: Thu, 5 May 1994 18:36:54 +1200 (NZST) Organization: (none) Dwayne Knowles writes: > > If you want to code it yourself, you'll have to use the process manager > > to check that the apropriate app is in the foreground before calling > > PostEvent(). You could even force the app to the foreground. > > > There are several problems with this however. The receiving app has to be > forced into the foreground, and more importantly, postEvent doesn't let me > post a keyDown event with the command key as a modifier - eg. post a menu > vkey event. No, that's no problem -- you use PPostEvent, which returns a pointer to the newly posted event queue element , and you can them diddle the modifiers. Just don't call WaitNextEvent first :-) -- Bruce +++++++++++++++++++++++++++ >From chris-b@cs.aukuni.ac.nz (Christopher David Burns) Date: 5 May 1994 11:22:45 GMT Organization: University of Auckland Bruce@hoult.actrix.gen.nz (Bruce Hoult) writes: >No, that's no problem -- you use PPostEvent, which returns a pointer to the >newly posted event queue element , and you can them diddle the modifiers. >Just don't call WaitNextEvent first :-) Why don't you use the jGNEFilter mechanism instead of PPostEvent(). Simply write an app that installs a jGNEFilter. This proc gets called just before GetNextEvent() or WaitNextEvent() return. It has access to the boolean result and the event record about to be returned. You can simply call SetFrontProcess() and in your proc check curAppName (or maybe compare GetFrontProcess() with the process you're interested in). When you find that the right app is switched in, you can change the first null event to a mouseDown (or whatever). Simple. (I assume that the jGNEFilter is called on null events). Give me a call if you want some code. Cheers, Chris B - --------------------------------------------------------------------- NewZealand:AucklandUniversity:ComputerScience:HyperMediaUnit:ChrisBurns Internet:chris-b@cs.aukuni.ac.nz Phone: +64 9 373-7599 x5602 Fax: +64 9 373-7453 +++++++++++++++++++++++++++ >From zellers@berksys.com (Steve Zellers) Date: 5 May 1994 21:17:01 GMT Organization: Berkeley Systems, Inc. In article <94050501465900688@bagend.nacjack.gen.nz>, Dwayne Knowles wrote: > postEvent doesn't let me > post a keyDown event with the command key as a modifier - eg. post a menu > key event. Check out PPostEvent. Consider an INIT/background app combination. -- Sr. Software Engineer Berkeley Systems, Inc. +++++++++++++++++++++++++++ >From jedavis@CS.Stanford.EDU (James Edward Davis) Date: 6 May 1994 14:20:57 -0500 Organization: UTexas Mail-to-News Gateway References: <94050301234800677@bagend.nacjack.gen.nz> Dwayne Knowles writes: >Is there a way to post an event to another application - eg. a keydown >event, without writing my own version of postEvent? I realise this is >probably going to break with future system releases and is very uncool in >general but I would like to be able to control an application remotely that >isn't scriptable or anything. Is this possible? Well, the simple answer is use AutoType. An OSAX I worte that lets AppleScript send keyDowns with modifiers to other apps, so you can script non-scriptable applications. I use ppostevent essentially like others in this thread described. Available at fine ftp sites everywhere. -James Davis : jedavis@cs.stanford.edu +++++++++++++++++++++++++++ >From walkerj@math.scarolina.edu (Jim Walker) Date: 4 May 1994 18:21:50 GMT Organization: University of South Carolina - Columbia - Computer Science Dwayne Knowles writes: (stuff deleted) >There are several problems with this however. The receiving app has to be >forced into the foreground, and more importantly, postEvent doesn't let me >post a keyDown event with the command key as a modifier - eg. post a menu >key event. PPostEvent (not a typo!) does allow you to post a keyDown event with modifiers. -- -- Jim Walker USC Dept. of Math. walkerj@math.scarolina.edu --------------------------- >From dnebing@bgsu.edu ( Mr. Neb) Subject: Shared memory... Date: 28 Apr 1994 02:04:11 GMT Organization: Bowling Green State University Here's a good one... I have a component which can be opened multiple times. I don't want the components to have to allocate the same memory each time (they all share a common resource (a picture) that I don't want multiple copies of floating around in memory). Anyone have a good solution for setting up a shared buffer between the components? Thanks in advance, Dave Nebinger ============================================================ Dave Nebinger dnebing@andy.bgsu.edu Network Manager, Biology Dept. dnebing@opie.bgsu.edu Bowling Green State University dnebing@bgsuopie (bitnet) Bowling Green, OH 43403 #include *THE* alt.sources.mac supporter! -- ============================================================ Dave Nebinger dnebing@andy.bgsu.edu Network Manager, Biology Dept. dnebing@opie.bgsu.edu Bowling Green State University dnebing@bgsuopie (bitnet) +++++++++++++++++++++++++++ >From devon_hubbard@taligent.com (Devon Hubbard) Date: Thu, 28 Apr 1994 17:35:31 GMT Organization: Taligent, Inc. In article <2pn5ir$rcm@falcon.bgsu.edu>, dnebing@bgsu.edu ( Mr. Neb) wrote: > Here's a good one... > > I have a component which can be opened multiple times. I don't want > the components to have to allocate the same memory each time (they > all share a common resource (a picture) that I don't want multiple > copies of floating around in memory). Anyone have a good solution > for setting up a shared buffer between the components? > > Thanks in advance, > > Dave Nebinger > > ============================================================ > Dave Nebinger dnebing@andy.bgsu.edu > Network Manager, Biology Dept. dnebing@opie.bgsu.edu > Bowling Green State University dnebing@bgsuopie (bitnet) > Bowling Green, OH 43403 #include > > *THE* alt.sources.mac supporter! > Install your own _Gestalt selector. Whichever process is first, it installs the selector. The other checks for it's existance. If there, the selector returns the address of a struct that contains whatever you want (i.e. addresses of shared memory blocks). Any of your processes can get to it. If you're starting and quitting apps, allocate the memory in the system heap so it'll stick around. Just be friendly and clean up the memory when everything's done. dEVoN - ------------------------------------------------------------------------ Devon Hubbard Silicon Pilot devon_hubbard@taligent.com Taligent, Inc +++++++++++++++++++++++++++ >From sblack@us.oracle.com (Steven T. Black) Date: 28 Apr 94 22:15:44 GMT Organization: Oracle Corporation In article devon_hubbard@taligent.com (Devon Hubbard) writes: > In article <2pn5ir$rcm@falcon.bgsu.edu>, dnebing@bgsu.edu ( Mr. Neb) > wrote: > > > Here's a good one... > > > > I have a component which can be opened multiple times. I don't want > > the components to have to allocate the same memory each time (they > > all share a common resource (a picture) that I don't want multiple > > copies of floating around in memory). Anyone have a good solution > > for setting up a shared buffer between the components? > > > > Thanks in advance, > > > > Dave Nebinger > > > > ============================================================ > > Dave Nebinger dnebing@andy.bgsu.edu > > Network Manager, Biology Dept. dnebing@opie.bgsu.edu > > Bowling Green State University dnebing@bgsuopie (bitnet) > > Bowling Green, OH 43403 #include > > > > *THE* alt.sources.mac supporter! > > > > Install your own _Gestalt selector. Whichever process is first, it > installs the selector. The other checks for it's existance. If there, the > selector returns the address of a struct that contains whatever you want > (i.e. addresses of shared memory blocks). Any of your processes can get to > it. If you're starting and quitting apps, allocate the memory in the > system heap so it'll stick around. Just be friendly and clean up the > memory when everything's done. > > dEVoN > > -------------------------------------------------------------------------- > Devon Hubbard Silicon Pilot > devon_hubbard@taligent.com Taligent, Inc You can also use the ASLM (Shared Library Manager) to store the resource in a library, and have a routine that returns the address of the PICT. This has the advantage that the ASLM can monitor how many clients are using the PICT, and so won't flush it from memory when the original app that called it quits if other apps are still referencing it. It also takes care of flushing it from memory when it is no longer needed. - ---------------------------------------------------------------------- -- Steven T. Black Lead Technical Staff sblack@us.oracle.com Oracle Desktop Products +++++++++++++++++++++++++++ >From dnebing@falcon.bgsu.edu.bgsu.edu ( Mr. Neb,217 LSC,3722332,3531532) Date: 29 Apr 1994 15:42:56 GMT Organization: Bowling Green State University sblack@us.oracle.com (Steven T. Black) writes: > You can also use the ASLM (Shared Library Manager) to store the > resource in a library, and have a routine that returns the address of > the PICT. This has the advantage that the ASLM can monitor how many > clients are using the PICT, and so won't flush it from memory when the > original app that called it quits if other apps are still referencing > it. It also takes care of flushing it from memory when it is no longer > needed. This assumes the following: 1. That somehow you have the ASLM headers and libs necessary to do so. 2. That the user has the ASLM or that Apple will give you a license to distribute it in your shareware/freeware. I would love to use the ASLM because it would simplify my life a great deal. Currently I am implementing my package as a bunch of components because Apple chooses to make me pay for the headers and libraries needed to use the ASLM. The way I figure it, if Apple wanted me to use new functionality within the system then they would provide the headerws and libs necessary to do so. I can't even get the Universal Headers without purchasing a major upgrade. Without the necessary headers, my stuff won't use the DragMgr, PowerTalk, etc. So people who use my stuff won't see any reason to go buy the components from Apple. So you tell me who is really hurt by charging for these simple development products. Like I was quoted in the latest MacWEEK, I don't expect to get the components for free. But I don't think that the headers and libs needed to implement the functionality of those components is too much to ask for. ============================================================ Dave Nebinger dnebing@andy.bgsu.edu Network Manager, Biology Dept. dnebing@opie.bgsu.edu Bowling Green State University dnebing@bgsuopie (bitnet) Bowling Green, OH 43403 #include *THE* alt.sources.mac supporter! -- ============================================================ Dave Nebinger dnebing@andy.bgsu.edu Network Manager, Biology Dept. dnebing@opie.bgsu.edu Bowling Green State University dnebing@bgsuopie (bitnet) +++++++++++++++++++++++++++ >From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) Date: 30 Apr 94 15:01:20 +1200 Organization: University of Waikato, Hamilton, New Zealand In article <2pn5ir$rcm@falcon.bgsu.edu>, dnebing@bgsu.edu ( Mr. Neb) writes: > > I have a component which can be opened multiple times. I don't want > the components to have to allocate the same memory each time (they > all share a common resource (a picture) that I don't want multiple > copies of floating around in memory). Anyone have a good solution > for setting up a shared buffer between the components? You could use SetComponentRefcon and GetComponentRefcon. The Component Manager documentation makes it clear that a component only has a single Refcon value, no matter how many instances are open. If you want to dispose of the storage when the last instance is closed, you can just call CountComponentInstances on yourself in your CloseComponent handler. I assume the count isn't decremented until your CloseComponent handler returns, in which case the value to check for is 1. If the count _is_ decremented before entering your CloseComponent handler, then the value to check for is 0. Or you could avoid the question and maintain your own reference count... Lawrence D'Oliveiro fone: +64-7-856-2889 Info & Tech Services Division fax: +64-7-838-4066 University of Waikato electric mail: ldo@waikato.ac.nz Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00 +++++++++++++++++++++++++++ >From jim_reekes@quickmail.apple.com (Jim Reekes) Date: Tue, 3 May 1994 19:56:15 GMT Organization: Apple Computer, Inc. In article <1994Apr30.150120.28180@waikato.ac.nz>, ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) wrote: > > In article <2pn5ir$rcm@falcon.bgsu.edu>, dnebing@bgsu.edu ( Mr. Neb) writes: > > > > I have a component which can be opened multiple times. I don't want > > the components to have to allocate the same memory each time (they > > all share a common resource (a picture) that I don't want multiple > > copies of floating around in memory). Anyone have a good solution > > for setting up a shared buffer between the components? > > You could use SetComponentRefcon and GetComponentRefcon. The Component Manager > documentation makes it clear that a component only has a single Refcon value, > no matter how many instances are open. > > If you want to dispose of the storage when the last instance is closed, > you can just call CountComponentInstances on yourself in your CloseComponent > handler. I assume the count isn't decremented until your CloseComponent > handler returns, in which case the value to check for is 1. If the count > _is_ decremented before entering your CloseComponent handler, then the value > to check for is 0. > > Or you could avoid the question and maintain your own reference count... > > Lawrence D'Oliveiro fone: +64-7-856-2889 > Info & Tech Services Division fax: +64-7-838-4066 > University of Waikato electric mail: ldo@waikato.ac.nz > Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00 Lawrence is right. For components, the refCon was designed exactly for this purpose. Only one thing to consider, if the system heap is tight and cannot load your component there, then it will be "cloned" into the current application heap (the heap that is responsible for opening it). When a component is cloned it will not carry it's refCon from the parent. In this case you need to check by calling GetComponentInstanceA5. A nil value means you're in the system heap, but any value will mean you're in some application's context. - --------------------------------------------------------------------- Jim Reekes, Polterzeitgeist | Macintosh Toolbox Engineering | Sound Manager Expert Apple Computer, Inc. | "All opinions expressed are mine, and do 20525 Mariani Ave. MS 302-3KS | not necessarily represent those of my Cupertino, CA 95014 | employer, Apple Computer Inc." --------------------------- >From Anders.Wahlin@hum.gu.se (Anders Wahlin) Subject: Unmounting all volumes? Date: Tue, 3 May 1994 08:03:46 GMT Organization: Hum Fak:s Dataservice I would like to know how I can unmount all volumes (except for the system volume). I would like to do this without knowing the names or the reference number of them. Should I do this in loop and not care about the errorcodes? Thanks! -- Anders Wahlin Anders.Wahlin@hum.gu.se +++++++++++++++++++++++++++ >From jumplong@aol.com (Jump Long) Date: 3 May 1994 16:03:02 -0400 Organization: America Online, Inc. (1-800-827-6364) In article , Anders.Wahlin@hum.gu.se (Anders Wahlin) writes: > I would like to know how I can unmount all volumes (except for the system > volume). I would like to do this without knowing the names or the reference > number of them. Should I do this in loop and not care about the errorcodes? You can get a list of mounted volumes by calling PBHGetVInfo starting with ioVolIndex==1 and then incrementing ioVolIndex until you get an error. Each call to PBHGetVInfo will give you a mounted volume's volume reference number in ioVRefNum. With that volume reference number, you'll be able to unmount volumes that don't have any non-system files open on them with PBUnmountVol. If any non-system files are open on a volume, PBUnmountVol will return fBsyErr (-47) and the volume won't be unmounted. There's function named UnmountAndEject in the DTS sample code MoreFiles that you can use to unmount and eject (if needed) a volume correctly. IMPORTANT WARNING: Some programmers have found and used the _UnmountVol trap with the HFS bit set (PBHUnmountVol which isn't in Files.h) to unconditionally unmount volumes that have open files. DON'T EVER DO THAT! PBHUnmountVol is reserved for system use at shutdown when volumes need to be unmounted no matter what because the system is either going to be shut off or restarted. Use of PBHUnmountVol at any other time can, and usually does, cause serious file and volume corruption because all open files on the volume unmounted by PBHUnmountVol are slammed closed by the file system that owns the volume. If one of those "slammed closed" file's File Control Blocks (FCB) is reused to open another file and the program that opened the first file writes to it or closes it, it will be accessing the wrong file! For a good explanation of how closing files more than once (which is another thing that can happen if PBHUnmountVol is used) can really screw things up, see the Technical Note "HFS Elucidations" (used to be TN #102). -- Jim Luther --------------------------- End of C.S.M.P. Digest **********************