Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
PutAwayOneVolume.c
/* |
File: PutAwayOneVolume.c |
Description: |
Author: PG |
Copyright: Copyright: © 1996-1999 by Apple Computer, Inc. |
all rights reserved. |
Disclaimer: You may incorporate this sample code into your applications without |
restriction, though the sample code has been provided "AS IS" and the |
responsibility for its operation is 100% yours. However, what you are |
not permitted to do is to redistribute the source as "DSC Sample Code" |
after having made changes. If you're going to re-distribute the source, |
we require that you make it clear in the source that the code was |
descended from Apple Sample Code, but that you've made changes. |
Change History (most recent first): |
6/25/99 Updated for Metrowerks Codewarror Pro 2.1(KG) |
03/21/96 Created(PG |
*/ |
#define OLDROUTINELOCATIONS 0 |
#define OLDROUTINENAMES 0 |
#define SystemSevenOrLater 1 |
#ifndef __DIALOGS__ |
# include <Dialogs.h> |
#endif |
#ifndef __AEREGISTRY__ |
# include <AERegistry.h> |
#endif |
#ifndef __APPLEEVENTS__ |
# include <AppleEvents.h> |
#endif |
#ifndef __MOREFILESEXTRAS__ |
# include "MoreFilesExtras.h" |
#endif |
#ifndef __ALIASES__ |
# include <Aliases.h> |
#endif |
#ifndef __FOLDERS__ |
# include <Folders.h> |
#endif |
#include "PutAwayOneVolume.h" |
#if GENERATINGCFM |
#ifndef __TRAPS__ |
# include <Traps.h> |
#endif |
pascal OSErr ReleaseFolder (short vRefNum, OSType folderType) |
{ |
const unsigned long selector = 0xB; |
enum |
{ |
uppReleaseFolderInfo = kD0DispatchedPascalStackBased |
| RESULT_SIZE (SIZE_CODE (sizeof(OSErr))) |
| DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE (SIZE_CODE (sizeof (selector))) |
| DISPATCHED_STACK_ROUTINE_PARAMETER (1,SIZE_CODE (sizeof (vRefNum))) |
| DISPATCHED_STACK_ROUTINE_PARAMETER (2,SIZE_CODE (sizeof (folderType))) |
}; |
return CallUniversalProc (GetToolTrapAddress (_AliasDispatch), uppReleaseFolderInfo, selector, vRefNum, folderType); |
} |
#endif |
static pascal OSErr BuildAppleEvent (short vRefNum, AppleEvent *event) |
{ |
OSErr err = noErr; |
FSSpecPtr fssP = (FSSpecPtr) NewPtr (sizeof (*fssP)); |
if (!(err = MemError ( ))) |
{ |
if (!(err = FSMakeFSSpec (vRefNum, fsRtDirID, nil, fssP))) |
{ |
AliasHandle aliasH; |
if (!(err = NewAlias (nil, fssP, &aliasH))) |
{ |
HLockHi ((Handle) aliasH); |
if (!(err = MemError ( ))) |
{ |
Size size = GetHandleSize ((Handle) aliasH); |
if (!(err = MemError ( ))) |
{ |
if (!(err = AEPutParamPtr (event,keyDirectObject,typeAlias,*aliasH,size))) |
{ |
AEDescList aeDescList; |
if (!(err = AECreateList (nil,0,false,&aeDescList))) |
{ |
if (!(err = AEPutPtr (&aeDescList,1,typeAlias,*aliasH,size))) |
err = AEPutParamDesc (event,keySelection,&aeDescList); |
AEDisposeDesc (&aeDescList); |
} |
} |
} |
} |
DisposeHandle ((Handle) aliasH); |
if (!err) err = MemError ( ); |
} |
} |
DisposePtr ((Ptr) fssP); |
if (!err) err = MemError ( ); |
} |
return err; |
} |
static pascal OSErr PutAwayOneVolumeByAppleEvent (short vRefNum, OSType finderLikeProcess) |
{ |
OSErr err = noErr; |
AEAddressDesc address; |
if (!(err = AECreateDesc (typeApplSignature, &finderLikeProcess, sizeof (finderLikeProcess), &address))) |
{ |
AppleEvent event; |
if (!(err = AECreateAppleEvent (kAEFinderEvents,kAEPutAwaySelection,&address,kAutoGenerateReturnID,kAnyTransactionID,&event))) |
{ |
if (!(err = BuildAppleEvent (vRefNum, &event))) |
{ |
AppleEvent reply; |
err = AESend (&event,&reply,kAENoReply,kAENormalPriority,kAEDefaultTimeout,nil,nil); |
} |
AEDisposeDesc (&event); |
} |
AEDisposeDesc (&address); |
} |
return err; |
} |
static pascal Boolean ConfirmEmptyTrash (short vRefNum, Boolean *confirmed) |
{ |
OSErr err = noErr; |
DialogRef dlgRef = nil; |
*confirmed = false; |
dlgRef = GetNewDialog (128,nil,(DialogRef)-1); |
if (dlgRef && !SetDialogDefaultItem (dlgRef,ok)) |
{ |
FSSpecPtr fssP = (FSSpecPtr) NewPtr (sizeof (FSSpec)); |
if (!(err = MemError ( ))) |
{ |
if (!FSMakeFSSpec (vRefNum,fsRtDirID,nil,fssP)) |
{ |
short itemHit; |
ParamText (fssP->name,nil,nil,nil); |
ShowWindow (dlgRef); |
ModalDialog (nil,&itemHit); |
DisposeDialog (dlgRef); |
if (itemHit == ok) |
*confirmed = true; |
} |
DisposePtr ((Ptr) fssP); |
if (!err) err = MemError ( ); |
} |
} |
return err; |
} |
static pascal OSErr CountFilesInDir (short vRefNum, long dirID, unsigned short *ioDrNmFls) |
{ |
OSErr err = noErr; |
CInfoPBPtr cipbp = (CInfoPBPtr) NewPtrClear (sizeof (CInfoPBRec)); |
if (!(err = MemError ( ))) |
{ |
cipbp->dirInfo.ioVRefNum = vRefNum; |
cipbp->dirInfo.ioDrDirID = dirID; |
cipbp->dirInfo.ioFDirIndex = -1; // ignore ioNamePtr |
if (!(err = PBGetCatInfoSync (cipbp))) |
*ioDrNmFls = cipbp->dirInfo.ioDrNmFls; |
DisposePtr ((Ptr) cipbp); |
if (!err) err = MemError ( ); |
} |
return err; |
} |
static pascal OSErr EmptyTrash (short vRefNum) |
{ |
OSErr err = noErr; |
short foundVRefNum; |
long foundDirID; |
err = FindFolder (vRefNum,kTrashFolderType,false,&foundVRefNum,&foundDirID); |
if (err == fnfErr) // if the trash ain't there, |
err = noErr; // consider it empty |
else if (!err) |
{ |
unsigned short ioDrNmFls; |
if (!(err = CountFilesInDir (foundVRefNum,foundDirID,&ioDrNmFls))) |
{ |
if (ioDrNmFls) |
{ |
Boolean confirmed; |
if (!(err = ConfirmEmptyTrash (foundVRefNum,&confirmed))) |
{ |
if (!confirmed) |
err = userCanceledErr; |
else |
{ |
FSSpecPtr fssP = (FSSpecPtr) NewPtr (sizeof (FSSpec)); |
if (!(err = MemError ( ))) |
{ |
if (!(err = FSMakeFSSpec (foundVRefNum,foundDirID,nil,fssP))) |
err = DeleteDirectory (fssP->vRefNum,fssP->parID,fssP->name); |
// DeleteDirectory is from MoreFiles |
DisposePtr ((Ptr) fssP); |
if (!err) err = MemError ( ); |
} |
} |
} |
} |
if (!err) |
err = ReleaseFolder (foundVRefNum,kTrashFolderType); |
} |
} |
return err; |
} |
pascal OSErr PutAwayOneVolume (short vRefNum, OSType finderLikeProcess) |
{ |
// |
// Administrates task of unmounting a volume. If 'finderLikeProcess' is zero, |
// will attempt to unmount with internal code. (Internal code doesn't yet |
// work on PowerPC because there's no glue for ReleaseFolder.) If 'finderLikeProcess' |
// is non-zero, will send AppleEvent which conforms to the Finder Suite's |
// "put away" spec to that process. For volumes, "put away" means "unmount". |
// |
OSErr err = noErr; |
if (finderLikeProcess) |
err = PutAwayOneVolumeByAppleEvent (vRefNum,finderLikeProcess); |
else if (!(err = EmptyTrash (vRefNum))) |
err = UnmountAndEject (nil,vRefNum); |
// UnmountAndEject is from MoreFiles |
return err; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14