home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Server Control Snippets
- ** The server control code snippets found in the AppleShare 3.0 Developer's
- ** Kit Server Control and Server Event Handling document.
- **
- ** by J. Luther, Apple Developer Technical Support
- ** Copyright Apple Computer, Inc. 1992-1994
- ** All rights reserved
- **
- ** Port from Pascal to C - 9/8/1994 JML
- **
- ** Here's the deal with the code in this file.
- **
- ** For each server control call, there is a function named MySCxxxx. The
- ** typical MySCxxxx function shows how to fill in the parameter block, make
- ** the server control call, and return any result values the server control
- ** returns. In addition, I've made every attempt to make the server control
- ** calls supported by Macintosh File Sharing act like the same server
- ** control calls under AppleShare. In some cases, that means I've filled
- ** in the return values not supplied by old versions of Macintosh File
- ** Sharing. In other cases (i.e., SCGetExpFldr), I've had to add code just
- ** to make the server control call work as advertised.
- **
- ** For some server control calls, I've added another code snippet or
- ** function to show a common use of that particular server control call.
- ** Here's what you'll find:
- **
- ** • There are code snippets that get the server version, status, and
- ** setup information and then store that information in global variables
- ** for later use by other functions. In some case, other code depends
- ** on those global variables being initialized and that is noted
- ** where applicable.
- **
- ** • There are functions that show how to enumerate the list of exported
- ** volumes and folder, enumerate the list of installed server event
- ** handlers, enumerate the list of connected users, get a users mount
- ** information for all volumes or folders mounted, disconnect a user
- ** from the server, send a message to all connected users, and disconnect
- ** the users of a specified volume.
- **
- ** All the test functions and snippets are marked like this:
- ** ••• Test Code •••
- ** Some code snippets are commented out under the Test Code markers, because
- ** they won't compile there. They can be found again in the main function.
- */
-
- /*****************************************************************************/
-
- #include <Traps.h>
- #include <AppleTalk.h>
- #include <Errors.h>
- #include <Memory.h>
- #include "ServerEventIntf.h"
- #include "ServerControlIntf.h"
-
- /*****************************************************************************/
-
- /*
- ** File Sharing 4.0 supports most server control calls just like AppleShare.
- ** The only exceptions are SCShutDown and SCDisconnect which ignore the
- ** flags and messagePtr parameters because those calls were supported by
- ** the old File Sharing code and some callers didn't bother to set
- ** messagePtr to NULL.
- */
-
- enum
- {
- kNewFileSharingVersion = 0x3e /* File Sharing 4.0's version number */
- };
-
- /*****************************************************************************/
-
- /*
- ** Globals
- */
-
- OSErr gErr;
- Boolean gHasServerDispatch;
-
- /* results from SCServerVersion */
- Str31 gServerExtensionName;
- short gServerType;
- short gServerVersion;
-
- /* results from SCPollServer */
- short gServerState;
- short gDisconnectState;
- short gServerError;
- long gSecondsLeft;
-
- /* results from SCGetSetupInfo */
- SetupInfoRec gSetupInfoRec;
- short gMaxVolumes;
- short gMaxExpFolders;
- short gCurMaxSessions;
-
- /*****************************************************************************/
-
- /*
- ** Prototypes
- */
-
- OSErr MySCServerVersion(StringPtr extNamePtr,
- short *serverType,
- short *serverVersion);
-
- OSErr MySCPollServer(short *serverState,
- short *disconnectState,
- short *serverError,
- long *secondsLeft);
-
- OSErr MySCGetSetupInfo(SetupInfoRec *setupPtr,
- short *maxVolumes,
- short *maxExpFolders,
- short *curMaxSessions);
-
- OSErr MySCGetExpFldr(short index,
- StringPtr namePtr,
- short *vRefNum,
- short *logins,
- long *dirID);
-
- OSErr MySCGetServerStatus(StringPtr namePtr,
- short *serverFlags,
- short *numSessions,
- long *userListModDate,
- short *activity,
- long *volListModDate);
-
- OSErr MySCGetServerEventProc(QHdrPtr *theSEQHdrPtr);
-
- OSErr MySCGetUserNameRec(StringPtr namePtr,
- long *position,
- long *unRecID,
- long *userID,
- long *loginTime,
- long *lastUseTime,
- AddrBlock *socketNum);
-
- OSErr MySCGetUserMountInfo(short vRefNum,
- long unRecID,
- short *filesOpen,
- short *writeableFiles,
- Boolean *mounted,
- Boolean *mountedAsOwner);
-
- OSErr MySCStartServer(void);
-
- OSErr MySCShutDown(short numMinutes,
- short flags,
- StringPtr messagePtr);
-
- OSErr MySCCancelShutDown(void);
-
- OSErr MySCWakeServer(void);
-
- OSErr MySCSleepServer(short numMinutes,
- short flags,
- StringPtr messagePtr);
-
- OSErr MySCSetSetupInfo(SetupInfoRecPtr setupPtr);
-
- OSErr MySCDisconnect(long *discArrayPtr,
- short arrayCount,
- short numMinutes,
- short flags,
- StringPtr messagePtr);
-
- OSErr MySCSendMessage(long *discArrayPtr,
- short arrayCount,
- short flags,
- StringPtr messagePtr);
-
- OSErr MySCSetCopyProtect(StringPtr namePtr,
- short vRefNum,
- long dirID);
-
- OSErr MySCClrCopyProtect(StringPtr namePtr,
- short vRefNum,
- long dirID);
-
- OSErr MySCDisconnectVolUsers(long *discArrayPtr,
- short arrayCount,
- short numMinutes,
- short flags,
- StringPtr messagePtr);
-
- /*****************************************************************************/
- /*****************************************************************************/
-
- /*
- ** The following three functions (NumToolboxTraps, GetTrapType, and
- ** TrapAvailable) are from Inside Macintosh Volume VI.
- */
-
- static short NumToolboxTraps(void)
- {
- if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
- return ( 0x0200 );
- else
- return ( 0x0400 );
- }
-
-
- static TrapType GetTrapType(short theTrap)
- {
- if ( (theTrap & 0x0800) > 0)
- return ( ToolTrap );
- else
- return ( OSTrap );
- }
-
- static Boolean TrapAvailable(short theTrap)
- {
- TrapType tType;
-
- tType = GetTrapType(theTrap);
- if (tType == ToolTrap)
- {
- theTrap = theTrap & 0x07FF;
- if ( theTrap >= NumToolboxTraps() )
- theTrap = _Unimplemented;
- }
- return ( NGetTrapAddress(theTrap, tType) != NGetTrapAddress(_Unimplemented, ToolTrap) );
- }
-
- /*****************************************************************************/
- /*****************************************************************************/
-
- /*
- ** This function calls SCServerVersion to get the file
- ** server extension's name and the server's type and
- ** version.
- **
- ** Note: The server version (scServerVersion) returned by
- ** Macintosh File Sharing servers is not valid when
- ** the file server is not running.
- */
-
- OSErr MySCServerVersion(StringPtr extNamePtr,
- short *serverType,
- short *serverVersion)
- {
- SCParamBlockRec scPB;
- OSErr result;
-
- scPB.versionPB.scCode = SCServerVersion;
- scPB.versionPB.scExtNamePtr = extNamePtr;
-
- result = SyncServerDispatch(&scPB);
- if ( result == noErr )
- {
- *serverType = scPB.versionPB.scServerType;
- *serverVersion = scPB.versionPB.scServerVersion;
- }
-
- return ( result );
- }
-
- /*
- ** ••• Test Code •••
- **
- ** Get the server version information and store it in
- ** global variables for user later
- **
- ** gErr = MySCServerVersion(gServerExtensionName, &gServerType, &gServerVersion);
- */
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCPollServer to find out what the
- ** server is doing.
- */
-
- OSErr MySCPollServer(short *serverState,
- short *disconnectState,
- short *serverError,
- long *secondsLeft)
- {
- SCParamBlockRec scPB;
- OSErr result;
-
- scPB.pollServerPB.scCode = SCPollServer;
- /* Macintosh File Sharing doesn't return scSecondsLeft so zero it. */
- scPB.pollServerPB.scSecondsLeft = 0;
-
- result = SyncServerDispatch(&scPB);
- if ( result == noErr )
- {
- *serverState = scPB.pollServerPB.scServerState;
- *disconnectState = scPB.pollServerPB.scDisconnectState;
- *serverError = scPB.pollServerPB.scServerError;
- *secondsLeft = scPB.pollServerPB.scSecondsLeft;
- }
-
- return ( result );
- }
-
- /*
- ** ••• Test Code •••
- ** Find out what the server's doing and store it in
- ** global variables for user later
- **
- ** gErr = MySCPollServer(gServerState, gDisconnectState, gServerError, gSecondsLeft);
- **
- */
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCGetSetupInfo to get the file
- ** server's setup information. If the server type is an old
- ** Macintosh File Sharing server, then this function fills
- ** in the fields that aren't returned by the server control
- ** call. This function depends on gServerType and
- ** gServerVersion being initialized with SCServerVersion.
- */
-
- OSErr MySCGetSetupInfo(SetupInfoRec *setupPtr,
- short *maxVolumes,
- short *maxExpFolders,
- short *curMaxSessions)
- {
- SCParamBlockRec scPB;
- OSErr result;
-
- scPB.setupPB.scCode = SCGetSetupInfo;
- scPB.setupPB.scSetupPtr = setupPtr;
-
- result = SyncServerDispatch(&scPB);
- if ( result == noErr )
- {
- if ( (gServerType == MFSType) && (gServerVersion < kNewFileSharingVersion) )
- {
- *maxVolumes = 10;
- *maxExpFolders = 10;
- *curMaxSessions = setupPtr->SIMaxLogins;
- }
- else
- {
- *maxVolumes = scPB.setupPB.scMaxVolumes;
- *maxExpFolders = scPB.setupPB.scMaxExpFolders;
- *curMaxSessions = scPB.setupPB.scCurMaxSessions;
- }
- }
-
- return ( result );
- }
-
- /*
- ** ••• Test Code •••
- ** Get the server's setup information and store it in
- ** global variables for user later
- **
- ** gErr = MySCGetSetupInfo(&gSetupInfoRec, &gMaxVolumes, &gMaxExpFolders, &gCurMaxSessions);
- */
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCGetExpFldr to get the export
- ** information for shared volumes and folders at the index
- ** position specified. This function depends on gServerType
- ** being initialized with SCServerVersion.
- */
-
- OSErr MySCGetExpFldr(short index,
- StringPtr namePtr,
- short *vRefNum,
- short *logins,
- long *dirID)
- {
- SCParamBlockRec scPB;
- OSErr result;
-
- scPB.standardPB.scCode = SCGetExpFldr;
-
- /* Initialize scVRefNum to 0 so we can tell if */
- /* SCGetExpFldr returned something when used with */
- /* Macintosh File Sharing */
- scPB.standardPB.scVRefNum = 0;
-
- if (index < 0)
- {
- /* Old versions of File Sharing trashes memory if */
- /* (scIndex < 0) and (scNamePtr != NULL), so we'll */
- /* prevent that from happening here. */
- scPB.standardPB.scNamePtr = NULL;
-
- /* and we'll return an empty string */
- if ( namePtr != NULL )
- {
- namePtr[0] = 0;
- }
- }
- else
- {
- scPB.standardPB.scNamePtr = namePtr;
- }
- scPB.standardPB.scIndex = index;
-
- result = SyncServerDispatch(&scPB);
- if ( result == noErr )
- {
- if ( (gServerType == MFSType) && (gServerVersion < kNewFileSharingVersion) )
- {
- if ( scPB.standardPB.scVRefNum != 0 )
- {
- *vRefNum = scPB.standardPB.scVRefNum;
- *logins = 0;
- *dirID = scPB.standardPB.scDirID;
- }
- else
- {
- /* there's nothing at this index position */
- /* so force the error code to make it act */
- /* like AppleShare */
- result = fnfErr;
- }
- }
- else
- {
- *vRefNum = scPB.standardPB.scVRefNum;
- *logins = scPB.standardPB.scLogins;
- *dirID = scPB.standardPB.scDirID;
- }
- }
-
- return ( result );
- }
-
- /*
- ** ••• Test Code •••
- **
- ** Enumerate the list of exported volumes and folders
- */
-
- void GetAllExpFldrs(void)
- {
- short index;
- Str15 shortName; /* only 13 characters are needed... */
- short vRefNum;
- short logins;
- long dirID;
- OSErr result;
-
- for ( index = -gMaxVolumes; index <= gMaxExpFolders; ++index )
- {
- if ( index != 0 ) /* index 0 is undefined */
- {
- result = MySCGetExpFldr(index, shortName, &vRefNum, &logins, &dirID);
- if ( result == noErr )
- {
- if ( index < 0 )
- {
- /* Do something with the exported volume */
- /* information */
- }
- else
- {
- /* Do something with the exported folder */
- /* information */
- }
- }
- else if ( result != fnfErr )
- {
- /* fnfErr only means there is nothing at this index position. */
- /* If not fnfErr, then handle any unexpected errors */
- }
- }
- }
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCGetServerStatus to get the file
- ** server's current status information.
- */
-
- OSErr MySCGetServerStatus(StringPtr namePtr,
- short *serverFlags,
- short *numSessions,
- long *userListModDate,
- short *activity,
- long *volListModDate)
- {
- SCParamBlockRec scPB;
- OSErr result;
-
- scPB.statusPB.scCode = SCGetServerStatus;
- scPB.statusPB.scNamePtr = namePtr;
-
- result = SyncServerDispatch(&scPB);
- if ( result == noErr )
- {
- *serverFlags = scPB.statusPB.scServerFlags;
- *numSessions = scPB.statusPB.scNumSessions;
- *userListModDate = scPB.statusPB.scUserListModDate;
- *activity = scPB.statusPB.scActivity;
- *volListModDate = scPB.statusPB.scVolListModDate;
- }
-
- return ( result );
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCGetServerEventProc to get a
- ** pointer to the head of the server event handler queue.
- */
-
- OSErr MySCGetServerEventProc(QHdrPtr *theSEQHdrPtr)
- {
- SCParamBlockRec scPB;
- OSErr result;
-
- scPB.serverEventPB.scCode = SCGetServerEventProc;
-
- result = SyncServerDispatch(&scPB);
- if ( result == noErr )
- {
- *theSEQHdrPtr = (QHdrPtr)scPB.serverEventPB.scSEQEntryPtr;
- }
-
- return ( result );
- }
-
- /*
- ** ••• Test Code •••
- **
- ** Enumerate the list of installed server event handlers.
- */
-
- void GetServerEventHandlers(void)
- {
- OSErr result;
- QHdrPtr theSEQHdrPtr;
- tSEQEntryPtr theSEQEntryPtr;
-
- result = MySCGetServerEventProc(&theSEQHdrPtr);
- if ( result == noErr )
- {
- theSEQEntryPtr = (tSEQEntryPtr)theSEQHdrPtr->qHead;
- while ( theSEQEntryPtr != NULL )
- {
- /* Do something with the tSEQentry pointed to */
- /* by theSEQEntryPtr */
-
- /* Then, move pointer to next entry (if any) */
- theSEQEntryPtr = (tSEQEntryPtr)theSEQEntryPtr->SEQentry.qLink;
- }
- }
- else
- {
- /* handle any errors */
- }
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCGetUserNameRec to retrieve
- ** statistics on a connected user.
- */
-
- OSErr MySCGetUserNameRec(StringPtr namePtr,
- long *position,
- long *unRecID,
- long *userID,
- long *loginTime,
- long *lastUseTime,
- AddrBlock *socketNum)
- {
- SCParamBlockRec scPB;
- OSErr result;
-
- scPB.userInfoPB.scCode = SCGetUserNameRec;
- scPB.userInfoPB.scNamePtr = namePtr;
- scPB.userInfoPB.scPosition = *position;
-
- result = SyncServerDispatch(&scPB);
- if ( result == noErr )
- {
- *position = scPB.userInfoPB.scPosition;
- *unRecID = scPB.userInfoPB.scUNRecID;
- *userID = scPB.userInfoPB.scUserID;
- *loginTime = scPB.userInfoPB.scLoginTime;
- *lastUseTime = scPB.userInfoPB.scLastUseTime;
- *socketNum = scPB.userInfoPB.scSocketNum;
- }
-
- return ( result );
- }
-
- /*
- ** ••• Test Code •••
- **
- ** Enumerate the list of users logged on
- */
-
- void GetAllUserNameRecs(void)
- {
- OSErr result;
- Str31 userName;
- long position;
- long unRecID;
- long userID;
- long loginTime;
- long lastUseTime;
- AddrBlock socketNum;
-
- position = 0;
- do
- {
- result = MySCGetUserNameRec(userName, &position, &unRecID, &userID,
- &loginTime, &lastUseTime, &socketNum);
- if ( result == noErr )
- {
- /* Do something with the user information returned */
- }
- else if ( result != fnfErr )
- {
- /* fnfErr only means there are no more users */
- /* If not fnfErr, then handle any unexpected errors */
- }
- } while ( result == noErr );
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCGetUserMountInfo to return
- ** information telling how a user is using a particular
- ** volume or exported folder.
- */
-
- OSErr MySCGetUserMountInfo(short vRefNum,
- long unRecID,
- short *filesOpen,
- short *writeableFiles,
- Boolean *mounted,
- Boolean *mountedAsOwner)
- {
- SCParamBlockRec scPB;
- OSErr result;
-
- scPB.volMountedPB.scCode = SCGetUserMountInfo;
- scPB.volMountedPB.scVRefNum = vRefNum;
- scPB.volMountedPB.scUNRecID = unRecID;
-
- result = SyncServerDispatch(&scPB);
-
- *filesOpen = scPB.volMountedPB.scFilesOpen;
- *writeableFiles = scPB.volMountedPB.scWriteableFiles;
- *mounted = scPB.volMountedPB.scMounted;
- *mountedAsOwner = scPB.volMountedPB.scMountedAsOwner;
-
- return ( result );
- }
-
- /*
- ** ••• Test Code •••
- **
- ** Get the user mount information for all volumes and
- ** exported folders a user has mounted.
- */
-
- void GetAllUserMountInfo(long unRecID)
- {
- OSErr result;
- short index;
- short filesOpen;
- short writeableFiles;
- Boolean mounted;
- Boolean mountedAsOwner;
-
- for ( index = -gMaxVolumes; index <= gMaxExpFolders; ++index )
- {
- if ( index != 0 ) /* index 0 is undefined */
- {
- result = MySCGetUserMountInfo(index, unRecID, &filesOpen, &writeableFiles,
- &mounted, &mountedAsOwner);
- if ( (result == noErr) && (mounted == true) )
- {
- /* Do something with the information returned */
- }
- }
- }
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCStartServer to start the Macintosh
- ** File Sharing server.
- */
-
- OSErr MySCStartServer(void)
- {
- SCParamBlockRec scPB;
-
- scPB.startPB.scCode = SCStartServer;
- scPB.startPB.scStartSelect = kCurInstalled;
- scPB.startPB.scEventSelect = kFinderExtn;
-
- return ( SyncServerDispatch(&scPB) );
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCShutDown to shut down the file
- ** server.
- **
- ** Note: File Sharing ignores the messagePtr parameter. Even the new
- ** versions, because the Finder doesn't fill in the messagePtr
- ** and flags field in the parameter block (it never had to in
- ** the past).
- */
-
- OSErr MySCShutDown(short numMinutes,
- short flags,
- StringPtr messagePtr)
- {
- SCParamBlockRec scPB;
-
- scPB.disconnectPB.scCode = SCShutDown;
- scPB.disconnectPB.scNumMinutes = numMinutes;
- scPB.disconnectPB.scFlags = flags;
- scPB.disconnectPB.scMessagePtr = messagePtr;
-
- return ( SyncServerDispatch(&scPB) );
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCCancelShutDown to cancel the
- ** shutdown or disconnect in progress.
- */
-
- OSErr MySCCancelShutDown(void)
- {
- SCParamBlockRec scPB;
-
- scPB.disconnectPB.scCode = SCCancelShutDown;
-
- return ( SyncServerDispatch(&scPB) );
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCWakeServer to wake up a sleeping
- ** AppleShare 3.0 file server.
- */
-
- OSErr MySCWakeServer(void)
- {
- SCParamBlockRec scPB;
-
- scPB.startPB.scCode = SCWakeServer;
-
- return ( SyncServerDispatch(&scPB) );
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCSleepServer to shut down the file
- ** server temporarily.
- */
-
- OSErr MySCSleepServer(short numMinutes,
- short flags,
- StringPtr messagePtr)
- {
- SCParamBlockRec scPB;
-
- scPB.disconnectPB.scCode = SCSleepServer;
- scPB.disconnectPB.scNumMinutes = numMinutes;
- scPB.disconnectPB.scFlags = flags;
- scPB.disconnectPB.scMessagePtr = messagePtr;
-
- return ( SyncServerDispatch(&scPB) );
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCSetSetupInfo to set the file
- ** server's setup information.
- */
-
- OSErr MySCSetSetupInfo(SetupInfoRecPtr setupPtr)
- {
- SCParamBlockRec scPB;
-
- scPB.setupPB.scCode = SCSetSetupInfo;
- scPB.setupPB.scSetupPtr = setupPtr;
-
- return ( SyncServerDispatch(&scPB) );
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCDisconnect to disconnect some
- ** users. Although Macintosh File Sharing implements
- ** SCDisconnect, there is no way to use it with old
- ** versions of File Sharing because old File Sharing
- ** doesn't implement the SCGetUserNameRec call.
- **
- ** Note: File Sharing ignores the messagePtr parameter. Even the new
- ** versions, because the Finder doesn't fill in the messagePtr
- ** and flags field in the parameter block (it never had to in
- ** the past).
- */
-
- OSErr MySCDisconnect(long *discArrayPtr,
- short arrayCount,
- short numMinutes,
- short flags,
- StringPtr messagePtr)
- {
- SCParamBlockRec scPB;
-
- scPB.disconnectPB.scDiscArrayPtr = discArrayPtr;
- scPB.disconnectPB.scArrayCount = arrayCount;
- scPB.disconnectPB.scCode = SCDisconnect;
- scPB.disconnectPB.scNumMinutes = numMinutes;
- scPB.disconnectPB.scFlags = flags;
- scPB.disconnectPB.scMessagePtr = messagePtr;
-
- return ( SyncServerDispatch(&scPB) );
- }
-
- /*
- ** ••• Test Code •••
- **
- ** Disconnect the user specified in 10 minutes with a
- ** message.
- */
-
- void DisconnectUser(long unRecID)
- {
- OSErr result;
- short arrayCount;
- short numMinutes;
- short flags;
- tLoginMsg message = "\pGoodbye.";
-
- arrayCount = 1; /* one user */
- numMinutes = 10;
- flags = UNRFSendMsgMask; /* send a message */
- result = MySCDisconnect(&unRecID, arrayCount, numMinutes, flags, message);
- if ( result == noErr )
- {
- /* The disconnect was started */
- }
- else
- {
- /* Handle any errors */
- }
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCSendMessage to send a message to
- ** some users.
- */
-
- OSErr MySCSendMessage(long *discArrayPtr,
- short arrayCount,
- short flags,
- StringPtr messagePtr)
- {
- SCParamBlockRec scPB;
-
- scPB.disconnectPB.scDiscArrayPtr = discArrayPtr;
- scPB.disconnectPB.scArrayCount = arrayCount;
- scPB.disconnectPB.scCode = SCSendMessage;
- scPB.disconnectPB.scFlags = flags;
- scPB.disconnectPB.scMessagePtr = messagePtr;
-
- return ( SyncServerDispatch(&scPB) );
- }
-
- /*
- ** ••• Test Code •••
- **
- ** Send a message to all connected users
- */
-
- void SendMessageToAll(void)
- {
- /* This routine depends on gCurMaxSessions being */
- /* initialized with SCGetSetupInfo. */
-
- OSErr result;
- long *arrayPosPtr;
- SCParamBlockRec scPB;
-
- long *discArrayPtr;
- short arrayCount;
- short flags;
- tLoginMsg message = "\pMoof!(tm)";
-
- /* Allocate an array large enough to get all users */
- discArrayPtr = (long *)NewPtr(sizeof(long) * gCurMaxSessions);
- if ( discArrayPtr != NULL )
- {
- scPB.userInfoPB.scPosition = 0;
- arrayCount = 0;
- arrayPosPtr = discArrayPtr;
- do
- {
- /* Bbuild list of users with SCGEtUserNameRec */
- scPB.userInfoPB.scCode = SCGetUserNameRec;
- scPB.userInfoPB.scNamePtr = NULL;
- result = SyncServerDispatch(&scPB);
- if ( result == noErr )
- {
- /* Add user to array */
- *arrayPosPtr = scPB.userInfoPB.scUNRecID;
- ++arrayPosPtr;
- ++arrayCount;
- }
- } while ( result == noErr );
-
- if ( arrayCount > 0 )
- {
- flags = UNRFSendMsgMask; /* Send a message */
- result = MySCSendMessage(discArrayPtr, arrayCount, flags, message);
- if ( result == noErr )
- {
- /* The message was sent */
- }
- else
- {
- /* Handle any errors from SCSendMessage */
- }
- }
- else
- {
- /* There are no users connected */
- /* do nothing */
- }
- DisposPtr((Ptr)discArrayPtr);
- }
- else
- {
- /* Handle memory manager error */
- }
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCSetCopyProtect to set the copy
- ** protect status of a file.
- */
-
- OSErr MySCSetCopyProtect(StringPtr namePtr,
- short vRefNum,
- long dirID)
- {
- SCParamBlockRec scPB;
-
- scPB.standardPB.scNamePtr = namePtr;
- scPB.standardPB.scVRefNum = vRefNum;
- scPB.standardPB.scCode = SCSetCopyProtect;
- scPB.standardPB.scDirID = dirID;
-
- return ( SyncServerDispatch(&scPB) );
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCClrCopyProtect to clear the copy
- ** protect status of a file.
- */
-
- OSErr MySCClrCopyProtect(StringPtr namePtr,
- short vRefNum,
- long dirID)
- {
- SCParamBlockRec scPB;
-
- scPB.standardPB.scNamePtr = namePtr;
- scPB.standardPB.scVRefNum = vRefNum;
- scPB.standardPB.scCode = SCClrCopyProtect;
- scPB.standardPB.scDirID = dirID;
-
- return ( SyncServerDispatch(&scPB) );
- }
-
- /*****************************************************************************/
-
- /*
- ** This function calls SCDisconnectVolUsers to disconnect
- ** the users of specified volumes.
- */
-
- OSErr MySCDisconnectVolUsers(long *discArrayPtr,
- short arrayCount,
- short numMinutes,
- short flags,
- StringPtr messagePtr)
- {
- SCParamBlockRec scPB;
-
- scPB.disconnectPB.scDiscArrayPtr = discArrayPtr;
- scPB.disconnectPB.scArrayCount = arrayCount;
- scPB.disconnectPB.scCode = SCDisconnectVolUsers;
- scPB.disconnectPB.scNumMinutes = numMinutes;
- scPB.disconnectPB.scFlags = flags;
- scPB.disconnectPB.scMessagePtr = messagePtr;
-
- return ( SyncServerDispatch(&scPB) );
- }
-
- /*
- ** ••• Test Code •••}
- **
- ** Disconnect the users of the specified volume in
- ** 10 minutes with a message.
- */
-
- void DisconnectVolUsers(short vRefNum)
- {
- OSErr result;
- long discToDisconnect;
- short arrayCount;
- short numMinutes;
- short flags;
- tLoginMsg message = "\pA volume is going away.";
-
- discToDisconnect = vRefNum; /* Note: short -> long */
- arrayCount = 1;
- numMinutes = 10;
- flags = UNRFSendMsgMask; /* send a message */
- result = MySCDisconnectVolUsers(&discToDisconnect, arrayCount, numMinutes,
- flags, message);
- if ( result == noErr )
- {
- /* The disconnect was started */
- }
- else
- {
- /* Handle any errors */
- }
- }
-
- /*****************************************************************************/
-
- void main(void)
- {
- /* You MUST make sure ServerDispatch is available before calling it */
- gHasServerDispatch = TrapAvailable(ServerDispatch);
- if ( gHasServerDispatch == true )
- {
- gErr = MySCServerVersion(gServerExtensionName, &gServerType, &gServerVersion);
- gErr = MySCPollServer(&gServerState, &gDisconnectState, &gServerError, &gSecondsLeft);
- gErr = MySCGetSetupInfo(&gSetupInfoRec, &gMaxVolumes, &gMaxExpFolders, &gCurMaxSessions);
- }
- }
-