# examples/Base/FileServer/FileChangeNotifier/src/filechangenotifier.cpp

    00001 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
    00002 // All rights reserved.
    00003 // This component and the accompanying materials are made available
    00004 // under the terms of "Eclipse Public License v1.0"
    00005 // which accompanies this distribution, and is available
    00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    00007 //
    00008 // Initial Contributors:
    00009 // Nokia Corporation - initial contribution.
    00010 //
    00011 // Contributors:
    00012 //
    00013 // Description:
    00014 //
    00015
    00016 #include "filechangenotifier.h"
    00017
    00018 CChangeNotifier* CChangeNotifier::NewL(TInt aPriority)
    00019     {
    00020     CChangeNotifier* self=new(ELeave)CChangeNotifier(aPriority);
    00021     CleanupStack::PushL(self);
    00022     self->ConstructL();
    00023     CleanupStack::Pop(self);
    00024     return self;
    00025     }
    00026
    00027 void CChangeNotifier::ConstructL()
    00028     {
    00029     //Create console
    00030     _LIT(KWelcome, "Welcome to File Change Notifier Example\n");
    00031     _LIT(KTextConsoleTitle, "Extended File Change Notifier");
    00032     iConsole = Console::NewL(KTextConsoleTitle, TSize(KConsFullScreen,KConsFullScreen));
    00033     iConsole->Printf(KWelcome);
    00034
    00035     // Initiate a session by connecting to the File Server
    00036     User::LeaveIfError(iFs.Connect());
    00037     // Buffer size for holding the results of completed notifications.
    00038     const TInt KNotificationHeaderSize = (sizeof(TUint16)*2)+(sizeof(TUint));
    00039     const TInt KMinNotificationBufferSize = 2*KNotificationHeaderSize + 2*KMaxFileName;
    00040
    00041     // Get the system drive on which the file/folder operations can be done.
    00042     int driveNumber = iFs.GetSystemDrive();
    00043     iDrive = (TChar('A'+ driveNumber));
    00044
    00045     // Create an object for 'CFsNotify'
    00046     iNotify= CFsNotify::NewL(iFs,KMinNotificationBufferSize);
    00047     }
    00048
    00049 CChangeNotifier::CChangeNotifier(TInt aPriority):CActive( aPriority )
    00050     {
    00051     CActiveScheduler::Add(this);
    00052     }
    00053
    00057 CChangeNotifier::~CChangeNotifier()
    00058     {
    00059     if(iIsCreateFile)
    00060         {
    00061         TBuf<80> path;
    00062         path.Append(iDrive);
    00063         _LIT(KPath,":\\private\\e80000fb\\filechange\\");
    00064         path.Append(KPath);
    00065
    00066         TBuf<20> filename;
    00067         _LIT(KFileName,"create.file");
    00068         filename.Append(KFileName);
    00069
    00070         TBuf<80> fullname;
    00071         fullname.Append(path);
    00072         fullname.Append(filename);
    00073
    00074         iFs.Delete(fullname);
    00075         }
    00076     if(iIsCreateFolder)
    00077         {
    00078         TBuf<80> path;
    00079         path.Append(iDrive);
    00080         _LIT(KPath,":\\private\\e80000fb\\filechange\\createfolder\\");
    00081         path.Append(KPath);
    00082         iFs.RmDir(path);
    00083         }
    00084     if(!iIsDeleteFile)
    00085         {
    00086         TBuf<80> path;
    00087         path.Append(iDrive);
    00088         _LIT(KPath,":\\private\\e80000fb\\filechange\\deletefolder\\");
    00089         path.Append(KPath);
    00090
    00091         TBuf<20> filename;
    00092         _LIT(KFileName,"file.txt");
    00093         filename.Append(KFileName);
    00094
    00095         TBuf<80> fullname;
    00096         fullname.Append(path);
    00097         fullname.Append(filename);
    00098
    00099         iFs.Delete(fullname);
    00100         }
    00101     if(iIsRenameFile)
    00102         {
    00103         TBuf<80> path;
    00104         path.Append(iDrive);
    00105         _LIT(KPath,":\\private\\e80000fb\\filechange\\");
    00106         path.Append(KPath);
    00107
    00108         TBuf<20> filename;
    00109         _LIT(KFileName,"NewFileName");
    00110         filename.Append(KFileName);
    00111
    00112         TBuf<80> fullname;
    00113         fullname.Append(path);
    00114         fullname.Append(filename);
    00115
    00116         iFs.Delete(fullname);
    00117         }
    00118
    00119     if(iIsRenameFolder)
    00120         {
    00121         TBuf<80> path;
    00122         path.Append(iDrive);
    00123         _LIT(KPath,":\\private\\e80000fb\\filechange\\RenameFolder\\");
    00124         path.Append(KPath);
    00125         iFs.RmDir(path);
    00126         }
    00127     if(iIsDeleteFolder)
    00128         {
    00129         TBuf<80> path;
    00130         path.Append(iDrive);
    00131         _LIT(KPath,":\\private\\e80000fb\\filechange\\deletefolder\\");
    00132         path.Append(KPath);
    00133         iFs.RmDir(path);
    00134         }
    00135     if(iIsVolumeNameChange)
    00136         {
    00137         TBuf<80> path;
    00138         path.Append('U');
    00139         path.Append(_L(":"));
    00140
    00141         _LIT(KVolumeLabel,"MyDrive");
    00142         iFs.SetVolumeLabel(KVolumeLabel,iDriveNumber);
    00143         }
    00144     if(iIsMultipleNotifications)
    00145         {
    00146         // delete file
    00147         TBuf<80> path;
    00148         path.Append(iDrive);
    00149         _LIT(KPath,":\\private\\e80000fb\\filechange\\");
    00150         path.Append(KPath);
    00151         TBuf<20> filename;
    00152         filename.Append(_L("rename.file"));
    00153
    00154         TBuf<80> fullname;
    00155         fullname.Append(path);
    00156         fullname.Append(filename);
    00157
    00158         iFs.Delete(fullname);
    00159         }
    00160     delete iConsole;
    00161     delete iNotify;
    00162     iFs.Close();
    00163     }
    00164
    00165 // The RunL() is called by the Active scheduler.
    00166 void CChangeNotifier::RunL()
    00167     {
    00168     /*
    00169      * When the user chooses an option which is not available in the list of supported features.
    00170      * The Active scheduler is stopped and the application exits.
    00171      */
    00172     if(iOption)
    00173         {
    00174         _LIT(KNotSupported,"\nNot Supported\n");
    00175         iConsole->Printf(KNotSupported);
    00176         CActiveScheduler::Stop();
    00177         }
    00178     else
    00179         {
    00180         /*
    00181          * When the user chooses a Sub-Menu option which is not among the listed options, then
    00182          * the list of Main options are once again displayed to the user.
    00183          */
    00184         if(iOptionContinue)
    00185             {
    00186             RequestCharacter();
    00187             }
    00188         if(iReqStatus == KErrNone)
    00189             {
    00190             _LIT(KSuccess,"\nSuccessfully completed the posted notifications\n");
    00191             iConsole->Printf(KSuccess);
    00192             if(!iDeleteFileContinue)
    00193                 {
    00194                 if(iIsMultipleNotifications)
    00195                     {
    00196                     //Get first notification
    00197                     const TFsNotification* notification = iNotify->NextNotification();
    00198                     TFsNotification::TFsNotificationType notificationType = ((TFsNotification*)notification)->NotificationType();
    00199
    00200                     //Process Notification
    00201                     ProcessMultipleChanges(notification);
    00202
    00203                     //Get Next notification
    00204                     notification = iNotify->NextNotification();
    00205
    00206                     //The operation may not have occurred yet..
    00207                     if(notification == NULL)
    00208                         {
    00209                         iNotify->RequestNotifications(iReqStatus);
    00210                         User::WaitForRequest(iReqStatus); // We need wait for the corresponding file change to complete.
    00211                         notification = iNotify->NextNotification();
    00212                         }
    00213
    00214                     //Process Notification
    00215                     ProcessMultipleChanges(notification);
    00216                     }
    00217                     RequestCharacter();
    00218                 }
    00219             else
    00220                 {
    00221                 DeleteFolder();
    00222                 }
    00223             }
    00224         }
    00225     }
    00226
    00227 /*
    00228  * This method will process the multiple notifications which are completed.
    00229  * Currently, the creation of the file and rename of the file are happening one after another in the DoChanges() Method
    00230  * defined below. Hence the file to be renamed will be created first and then rename operation is done.
    00231  */
    00232 void CChangeNotifier::ProcessMultipleChanges(const TFsNotification* aNotification)
    00233     {
    00234     TFsNotification::TFsNotificationType notificationType = ((TFsNotification*)aNotification)->NotificationType();
    00235
    00236     if(notificationType == TFsNotification::ECreate)
    00237         {
    00238         _LIT(KNewFileCreated,"Notification of successful creation of a new file 'notify.file'\n");
    00239         iConsole->Printf(KNewFileCreated);
    00240         }
    00241     else if (notificationType == TFsNotification::ERename)
    00242         {
    00243         _LIT(KFileRename,"Notification for notify.file being renamed to rename.file ");
    00244         iConsole->Printf(KFileRename);
    00245         }
    00246     }
    00247 /*
    00248  * User gets notified when there is a change in the file. Different kinds of notifications are posted by the
    00249  * user.
    00250  *
    00251  * Notifications are recevied for following operations :
    00252  * - Any change in the contents of the particular file.
    00253  * - If any new file is created inside the particular folder.
    00254  * - When a file rename is done.
    00255  * - When the file attributes are changed.
    00256  * - When a particular file is deleted.
    00257  *
    00258  */
    00259 void CChangeNotifier::NotifyChangeToFile()
    00260     {
    00261     _LIT(KMenuL1,"\nChoose an option:\n");
    00262     _LIT(KMenuL2,"1.Get notified when a file is created\n");
    00263     _LIT(KMenuL3,"2.Get notified when the file contents change\n");
    00264     _LIT(KMenuL4,"3.Get notified when a file rename occurs\n");
    00265     _LIT(KMenuL5,"4.Get notified when file attributes change\n");
    00266     _LIT(KMenuL6,"5.Get notified when a file is deleted\n");
    00267
    00268     iConsole->Printf(KMenuL1);
    00269     iConsole->Printf(KMenuL2);
    00270     iConsole->Printf(KMenuL3);
    00271     iConsole->Printf(KMenuL4);
    00272     iConsole->Printf(KMenuL5);
    00273     iConsole->Printf(KMenuL6);
    00274
    00275     TChar choice = iConsole->Getch();
    00276     switch(choice)
    00277         {
    00278         case '1':
    00279             {
    00280             CreateFile();
    00281             break;
    00282             }
    00283         case '2':
    00284             {
    00285             ChangeFileContents();
    00286             break;
    00287             }
    00288         case '3':
    00289             {
    00290             RenameFile();
    00291             break;
    00292             }
    00293         case '4':
    00294             {
    00295             ChangeFileAttributes ();
    00296             break;
    00297             }
    00298         case '5':
    00299             {
    00300             DeleteFile();
    00301             break;
    00302             }
    00303         default:
    00304             {
    00305             iOption = ETrue;
    00306             _LIT(KPressAnyKey,"Press any key to Exit");
    00307             iConsole->Printf(KPressAnyKey);
    00308             iConsole->Read(iStatus);
    00309             if(!IsActive())
    00310                 {
    00311                 SetActive();
    00312                 }
    00313             break;
    00314             }
    00315         }
    00316     }
    00317
    00318 /*
    00319  * User gets notified when a new file is created with a particular name in a particular folder.
    00320  */
    00321 void CChangeNotifier::CreateFile()
    00322     {
    00323     if(!iIsCreateFile)
    00324         {
    00325         TBuf<40> path;
    00326         path.Append(iDrive);
    00327         _LIT(KPath,":\\private\\e80000fb\\filechange\\");
    00328         path.Append(KPath);
    00329
    00330         TBuf<20> filename;
    00331         _LIT(KFileName,"create.file");
    00332         filename.Append(KFileName);
    00333
    00334         TInt err = iNotify->AddNotification((TUint)TFsNotification::ECreate,path,filename);
    00335         if(err == KErrNone)
    00336             {
    00337             _LIT(KSuccess,"\nAdded 'Create File' type notification to  CFsNotify object\n");
    00338             iConsole->Printf(KSuccess);
    00339             }
    00340         else
    00341             {
    00342             _LIT(KSuccess,"Added Notification failed\n");
    00343             iConsole->Printf(KSuccess);
    00344             }
    00345         err = iNotify->RequestNotifications(iReqStatus);
    00346         if(err==KErrNone)
    00347             {
    00348             _LIT(KSuccess,"Request for the above notification is successful\n");
    00349             iConsole->Printf(KSuccess);
    00350             }
    00351
    00352         DoChanges(ECreateFile);
    00353         iStatus = iReqStatus;
    00354         if(!IsActive())
    00355             {
    00356             SetActive();
    00357             }
    00358         iIsCreateFile = ETrue;
    00359         }
    00360     else
    00361         {
    00362         _LIT(KResult,"File already created\n");
    00363         iConsole->Printf(KResult);
    00364         PressAnyKey();
    00365         }
    00366     }
    00367
    00368 /*
    00369  * User gets notified when the contents of the file change.
    00370  */
    00371 void CChangeNotifier::ChangeFileContents()
    00372     {
    00373     TBuf<80> path;
    00374     path.Append(iDrive);
    00375     _LIT(KPath,":\\private\\e80000fb\\filechange\\");
    00376     path.Append(KPath);
    00377
    00378     TBuf<20> filename;
    00379     _LIT(KFileName,"file.txt");
    00380     filename.Append(KFileName);
    00381
    00382     TInt err = iNotify->AddNotification((TUint)TFsNotification::EFileChange,path,filename);
    00383     if(err == KErrNone)
    00384         {
    00385         _LIT(KSuccess,"\nAdded 'File contents change' type notification to  CFsNotify object\n");
    00386         iConsole->Printf(KSuccess);
    00387         }
    00388     else
    00389         {
    00390         _LIT(KSuccess,"Added Notification failed\n");
    00391         iConsole->Printf(KSuccess);
    00392         }
    00393     err = iNotify->RequestNotifications(iReqStatus);
    00394     if(err==KErrNone)
    00395         {
    00396         _LIT(KSuccess,"Request for the above notification is successful\n");
    00397         iConsole->Printf(KSuccess);
    00398         }
    00399     DoChanges(EChangeFileContents);
    00400     iStatus = iReqStatus;
    00401     if(!IsActive())
    00402         {
    00403         SetActive();
    00404         }
    00405     }
    00406
    00407 /*
    00408  * User gets notified when a file name is changed.
    00409  */
    00410 void CChangeNotifier::RenameFile()
    00411     {
    00412     if(!iIsCreateFile)
    00413         {
    00414         _LIT(KCreateFile,"\nCreating a file so that you can try changing it attributes later\n");
    00415         iConsole->Printf(KCreateFile);
    00416         CreateFile();
    00417         }
    00418     else
    00419         {
    00420         if(!iIsRenameFile)
    00421             {
    00422             TBuf<80> path;
    00423             path.Append(iDrive);
    00424             _LIT(KPath,":\\private\\e80000fb\\filechange\\");
    00425             path.Append(KPath);
    00426
    00427             TBuf<20> filename;
    00428             _LIT(KFileName,"create.file");
    00429             filename.Append(KFileName);
    00430
    00431             TInt err = iNotify->AddNotification((TUint)TFsNotification::ERename,path,filename);
    00432             if(err == KErrNone)
    00433                 {
    00434                 _LIT(KSuccess,"\nAdded 'File rename' type notification to  CFsNotify object\n");
    00435                 iConsole->Printf(KSuccess);
    00436                 }
    00437             else
    00438                 {
    00439                 _LIT(KSuccess,"Added notification failed\n");
    00440                 iConsole->Printf(KSuccess);
    00441                 }
    00442             err = iNotify->RequestNotifications(iReqStatus);
    00443             if(err==KErrNone)
    00444                 {
    00445                 _LIT(KSuccess,"Request for the above notification is successful\n");
    00446                 iConsole->Printf(KSuccess);
    00447                 }
    00448             DoChanges(ERenameFile);
    00449             iStatus = iReqStatus;
    00450             if(!IsActive())
    00451                 {
    00452                 SetActive();
    00453                 }
    00454             iIsRenameFile = ETrue;
    00455             }
    00456         else
    00457             {
    00458             _LIT(KResult,"File rename is already performed\n");
    00459             iConsole->Printf(KResult);
    00460             PressAnyKey();
    00461             }
    00462         }
    00463     }
    00464
    00465 /*
    00466  * User gets notified when the file attributes change
    00467  */
    00468 void CChangeNotifier::ChangeFileAttributes()
    00469     {
    00470     if(!iIsCreateFile)
    00471         {
    00472         _LIT(KCreateFile,"\nCreating a file so that you can try changing it attributes later\n");
    00473         iConsole->Printf(KCreateFile);
    00474         CreateFile();
    00475         }
    00476     else
    00477         {
    00478         if(!iIsChangeFileAttributes )
    00479             {
    00480             TBuf<80> path;
    00481             path.Append(iDrive);
    00482             _LIT(KPath,":\\private\\e80000fb\\filechange\\");
    00483             path.Append(KPath);
    00484
    00485             TBuf<20> filename;
    00486             _LIT(KFileName,"create.file");
    00487             filename.Append(KFileName);
    00488
    00489             TInt err = iNotify->AddNotification((TUint)TFsNotification::EAttribute,path,filename);
    00490             if(err == KErrNone)
    00491                 {
    00492                 _LIT(KSuccess,"\nAdded 'File attributes change' type notification to  CFsNotify object\n");
    00493                 iConsole->Printf(KSuccess);
    00494                 }
    00495             else
    00496                 {
    00497                 _LIT(KSuccess,"Added Notification failed\n");
    00498                 iConsole->Printf(KSuccess);
    00499                 }
    00500             err = iNotify->RequestNotifications(iReqStatus);
    00501             if(err==KErrNone)
    00502                 {
    00503                 _LIT(KSuccess,"Request for the above notification is successful\n");
    00504                 iConsole->Printf(KSuccess);
    00505                 }
    00506             DoChanges(EChangeFileAttributes );
    00507             iStatus = iReqStatus;
    00508             if(!IsActive())
    00509                 {
    00510                 SetActive();
    00511                 }
    00512             iIsChangeFileAttributes  = ETrue;
    00513             }
    00514         else
    00515             {
    00516             _LIT(KResult,"File attributes already changed\n");
    00517             iConsole->Printf(KResult);
    00518             PressAnyKey();
    00519             }
    00520         }
    00521     }
    00522
    00523 /*
    00524  * User gets notified when a file is deleted.
    00525  */
    00526 void CChangeNotifier::DeleteFile()
    00527     {
    00528     if(!iIsDeleteFile)
    00529         {
    00530         TBuf<80> path;
    00531         path.Append(iDrive);
    00532         _LIT(KPath,":\\private\\e80000fb\\filechange\\deletefolder\\");
    00533         path.Append(KPath);
    00534
    00535         TBuf<20> filename;
    00536         _LIT(KFileName,"file.txt");
    00537         filename.Append(KFileName);
    00538
    00539         TInt err = iNotify->AddNotification((TUint)TFsNotification::EDelete,path,filename);
    00540         if(err == KErrNone)
    00541             {
    00542             _LIT(KSuccess,"\nAdded 'File Delete' type notification to  CFsNotify object\n");
    00543             iConsole->Printf(KSuccess);
    00544             }
    00545         else
    00546             {
    00547             _LIT(KSuccess,"Add Notification failed\n");
    00548             iConsole->Printf(KSuccess);
    00549             }
    00550         err = iNotify->RequestNotifications(iReqStatus);
    00551         if(err==KErrNone)
    00552             {
    00553             _LIT(KSuccess,"Request for the above notification is successful\n");
    00554             iConsole->Printf(KSuccess);
    00555             }
    00556
    00557         DoChanges(EDeleteFile);
    00558         iStatus = iReqStatus;
    00559         if(!IsActive())
    00560             {
    00561             SetActive();
    00562             }
    00563         iIsDeleteFile = ETrue;
    00564         }
    00565     else
    00566         {
    00567         _LIT(KResult,"File already deleted\n");
    00568         iConsole->Printf(KResult);
    00569         PressAnyKey();
    00570         }
    00571     }
    00572
    00573 /*
    00574  * User gets notified when a folder is created.
    00575  */
    00576 void CChangeNotifier::CreateFolder()
    00577     {
    00578     if(!iIsCreateFolder)
    00579         {
    00580         TBuf<80> path;
    00581         path.Append(iDrive);
    00582         _LIT(KPath,":\\private\\e80000fb\\filechange\\createfolder\\");
    00583         path.Append(KPath);
    00584
    00585         TBuf<10> filename;
    00586         _LIT(KFileName,"*");
    00587         filename.Append(KFileName);
    00588
    00589         TInt err = iNotify->AddNotification((TUint)TFsNotification::ECreate,path,filename);
    00590         if(err == KErrNone)
    00591             {
    00592             _LIT(KSuccess,"\nAdded 'Create Folder' type notification to  CFsNotify object\n");
    00593             iConsole->Printf(KSuccess);
    00594             }
    00595         else
    00596             {
    00597             _LIT(KSuccess,"Add Notification failed\n");
    00598             iConsole->Printf(KSuccess);
    00599             }
    00600         err = iNotify->RequestNotifications(iReqStatus);
    00601         if(err==KErrNone)
    00602             {
    00603             _LIT(KSuccess,"Request for the above notification is successful\n");
    00604             iConsole->Printf(KSuccess);
    00605             }
    00606
    00607         DoChanges(ECreateFolder);
    00608         iStatus = iReqStatus;
    00609         if(!IsActive())
    00610             {
    00611             SetActive();
    00612             }
    00613         iIsCreateFolder = ETrue;
    00614         }
    00615         else
    00616             {
    00617             _LIT(KResult,"Folder already created\n");
    00618             iConsole->Printf(KResult);
    00619             PressAnyKey();
    00620             }
    00621         }
    00622
    00623 /*
    00624  * User gets notified when a folder rename is done.
    00625  */
    00626 void CChangeNotifier::RenameFolder()
    00627     {
    00628     if(!iIsRenameFolder)
    00629         {
    00630         TBuf<80> path;
    00631         path.Append(iDrive);
    00632         _LIT(KPath,":\\private\\e80000fb\\filechange\\newfolder\\");
    00633         path.Append(KPath);
    00634
    00635         TBuf<80> newPath;
    00636         newPath.Append('c');
    00637         _LIT(KPath1,":\\private\\e80000fb\\filechange\\RenameFolder\\");
    00638         newPath.Append(KPath1);
    00639
    00640         TBuf<20> filename;
    00641         _LIT(KFileName,"*");
    00642         filename.Append(KFileName);
    00643
    00644         TInt err = iNotify->AddNotification((TUint)TFsNotification::ERename,path,filename);
    00645         if(err == KErrNone)
    00646             {
    00647             _LIT(KSuccess,"\nAdded 'Rename Folder' type notification to  CFsNotify object\n");
    00648             iConsole->Printf(KSuccess);
    00649             }
    00650         else
    00651             {
    00652             _LIT(KSuccess,"Add Notification failed\n");
    00653             iConsole->Printf(KSuccess);
    00654             }
    00655         err = iNotify->RequestNotifications(iReqStatus);
    00656         if(err==KErrNone)
    00657             {
    00658             _LIT(KSuccess,"Request for the above notification is successful\n");
    00659             iConsole->Printf(KSuccess);
    00660             }
    00661         DoChanges(ERenameFolder);
    00662         iStatus = iReqStatus;
    00663         if(!IsActive())
    00664             {
    00665             SetActive();
    00666             }
    00667         iIsRenameFolder = ETrue;
    00668         }
    00669     else
    00670         {
    00671         _LIT(KResult,"Folder rename is performed already\n");
    00672         iConsole->Printf(KResult);
    00673         PressAnyKey();
    00674         }
    00675     }
    00676
    00677 void CChangeNotifier::DeleteFolder()
    00678     {
    00679     if(!iIsDeleteFolder)
    00680         {
    00681         TBuf<80> path;
    00682         path.Append(iDrive);
    00683         _LIT(KPath,":\\private\\e80000fb\\filechange\\deletefolder\\");
    00684         path.Append(KPath);
    00685
    00686         TBuf<20> filename;
    00687         _LIT(KFileName,"*");
    00688         filename.Append(KFileName);
    00689
    00690         TInt err = iNotify->AddNotification((TUint)TFsNotification::EDelete ,path,filename);
    00691         if(err == KErrNone)
    00692             {
    00693             _LIT(KSuccess,"\nAdded 'Delete Folder' type notification to  CFsNotify object\n");
    00694             iConsole->Printf(KSuccess);
    00695             }
    00696         else
    00697             {
    00698             _LIT(KSuccess,"Add Notification failed\n");
    00699             iConsole->Printf(KSuccess);
    00700             }
    00701
    00702         err = iNotify->RequestNotifications(iReqStatus);
    00703         if(err==KErrNone)
    00704             {
    00705             _LIT(KSuccess,"Request for the above notification is successful\n");
    00706             iConsole->Printf(KSuccess);
    00707             }
    00708         DoChanges(EDeleteFolder);
    00709         iStatus = iReqStatus;
    00710         if(!IsActive())
    00711             {
    00712             SetActive();
    00713             }
    00714         iIsDeleteFolder = ETrue;
    00715         }
    00716     else
    00717         {
    00718         _LIT(KResult,"Folder is already deleted\n");
    00719         iConsole->Printf(KResult);
    00720         PressAnyKey();
    00721         }
    00722     if(iDeleteFileContinue )
    00723         {
    00724         iDeleteFileContinue = EFalse;
    00725         }
    00726     }
    00727
    00728 /*
    00729  * User gets notified when a folder is deleted.
    00730  */
    00731 void CChangeNotifier::DeleteFileandFolder()
    00732     {
    00733         if((!iIsDeleteFile)){
    00734             DeleteFile();
    00735             iDeleteFileContinue = ETrue;
    00736             }
    00737         else{
    00738             DeleteFolder();
    00739             }
    00740     }
    00741
    00742 /*
    00743  * User gets notified when there is change in Folder.
    00744  */
    00745 void CChangeNotifier::NotifyChangeToFolder()
    00746     {
    00747     _LIT(KMenuL1,"\nChoose an option:\n");
    00748     _LIT(KMenuL2,"1.Create a Folder\n");
    00749     _LIT(KMenuL3,"2.Rename the Folder\n");
    00750     _LIT(KMenuL4,"3.Delete the Folder\n");
    00751
    00752     iConsole->Printf(KMenuL1);
    00753     iConsole->Printf(KMenuL2);
    00754     iConsole->Printf(KMenuL3);
    00755     iConsole->Printf(KMenuL4);
    00756
    00757     TChar choice = iConsole->Getch();
    00758     switch(choice)
    00759         {
    00760         case '1':
    00761             {
    00762             CreateFolder();
    00763             break;
    00764             }
    00765         case '2':
    00766             {
    00767             RenameFolder();
    00768             break;
    00769             }
    00770         case '3':
    00771             {
    00772            DeleteFileandFolder();
    00773             break;
    00774             }
    00775         default:
    00776             {
    00777             iOption = ETrue;
    00778             _LIT(KPressAnyKey,"Press any key to Exit");
    00779             iConsole->Printf(KPressAnyKey);
    00780             iConsole->Read(iStatus);
    00781             if(!IsActive())
    00782                 {
    00783                 SetActive();
    00784                 }
    00785             break;
    00786             }
    00787         }
    00788     }
    00789 /*
    00790  * User gets notified when there is a change in the Volume name of a Drive.
    00791  */
    00792 void CChangeNotifier::VolumeNameChange()
    00793     {
    00794     if(!iIsVolumeNameChange)
    00795         {
    00796         TBuf<5> path;
    00797         path.Append('U');
    00798         path.Append(_L(":"));
    00799         TBuf<20> filename;
    00800
    00801         TInt err = iNotify->AddNotification((TUint)TFsNotification::EVolumeName,path,filename);
    00802         if(err == KErrNone)
    00803             {
    00804             _LIT(KSuccess,"\nAdded 'Volume name change' type notification to  CFsNotify object\n");
    00805             iConsole->Printf(KSuccess);
    00806             }
    00807         else
    00808             {
    00809             _LIT(KSuccess,"Add Notification failed\n");
    00810             iConsole->Printf(KSuccess);
    00811             }
    00812         err = iNotify->RequestNotifications(iReqStatus);
    00813         if(err==KErrNone)
    00814             {
    00815             _LIT(KSuccess,"Request for the above notification is successful\n");
    00816             iConsole->Printf(KSuccess);
    00817             }
    00818         DoChanges(EVolumeNameChange);
    00819         iStatus = iReqStatus;
    00820         if(!IsActive())
    00821             {
    00822             SetActive();
    00823             }
    00824         iIsVolumeNameChange = ETrue;
    00825         }
    00826     else{
    00827         _LIT(KResult,"Volume name already changed\n");
    00828         iConsole->Printf(KResult);
    00829         PressAnyKey();
    00830         }
    00831     }
    00832
    00833
    00834 /*
    00835  * Client receives notifications for multiple notifications requested.
    00836  *
    00837  * The major differences between the old (RFs::NotifyChange) and new (CFsNotify) frameworks are:
    00838  * The ability to request multiple notifications on differing paths,
    00839  * notification types,  combinations of paths/notification-types etc..,on the same request.
    00840  * Guarantee that all notifiable operations will be served to the client (no race to re-request notifications).
    00841  * Client can query the notification to find out what change has occurred (no directory scanning required).
    00842  */
    00843 void CChangeNotifier::MultipleNotifications()
    00844     {
    00845     if(!iIsMultipleNotifications)
    00846         {
    00847         TBuf<40> path;
    00848         path.Append(iDrive);
    00849         _LIT(KPath,":\\private\\e80000fb\\filechange\\");
    00850         path.Append(KPath);
    00851
    00852         TBuf<20> filename;
    00853         _LIT(KFileName,"notify.file");
    00854         filename.Append(KFileName);
    00855
    00856         TInt err = iNotify->AddNotification((TUint)TFsNotification::ECreate,path,filename);
    00857         if(err == KErrNone)
    00858             {
    00859             _LIT(KSuccess,"\nAdded 'Create File' type notification to  CFsNotify object\n");
    00860             iConsole->Printf(KSuccess);
    00861             }
    00862         else
    00863             {
    00864             _LIT(KSuccess,"Added Notification failed\n");
    00865             iConsole->Printf(KSuccess);
    00866             }
    00867
    00868         err = iNotify->AddNotification((TUint)TFsNotification::ERename,path,filename);
    00869         if(err == KErrNone)
    00870             {
    00871             _LIT(KSuccess,"\nAdded 'Rename file' type notification to  CFsNotify object\n");
    00872             iConsole->Printf(KSuccess);
    00873             }
    00874         else
    00875             {
    00876             _LIT(KSuccess,"Add Notification failed\n");
    00877             iConsole->Printf(KSuccess);
    00878             }
    00879         iNotify->RequestNotifications(iReqStatus);
    00880         DoChanges(EMultipleNotifications);
    00881         iStatus = iReqStatus;
    00882         if(!IsActive())
    00883             {
    00884             SetActive();
    00885             }
    00886         iIsMultipleNotifications = ETrue;
    00887         }
    00888     else
    00889         {
    00890         _LIT(KResult,"Mutliple notifications already done\n");
    00891         iConsole->Printf(KResult);
    00892         PressAnyKey();
    00893         }
    00894     }
    00895
    00896 /*
    00897  * Do the file/folder changes as per the notificaiton request posted by the CFsNotify client.
    00898  * After the file/folder changes complete. RunL() will be called, successful completion of the request is displayed in RunL()
    00899  *
    00900  * Note : The file changes can originate from any thread or a process.
    00901  */
    00902 void CChangeNotifier::DoChanges(CChangeNotifier::TFileOperations aOperation)
    00903     {
    00904     TBuf<80> path;
    00905     TBuf<20> filename;
    00906     TBuf<80> fullname;
    00907     RFile file;
    00908     switch(aOperation)
    00909         {
    00910         case CChangeNotifier::ECreateFile :
    00911             {
    00912             path.Append(iDrive);
    00913             _LIT(KPath,":\\private\\e80000fb\\filechange\\");
    00914             path.Append(KPath);
    00915
    00916             TBuf<20> filename;
    00917             _LIT(KFileName,"create.file");
    00918             filename.Append(KFileName);
    00919
    00920             fullname.Append(path);
    00921             fullname.Append(filename);
    00922             file.Replace(iFs,fullname,EFileWrite); //Replace produces Create notification
    00923
    00924             _LIT(KTxtFileChanges,"\nNew file create.file created at %c drive at :\\private\\e80000fb\\filechange\\ location\n");
    00925             iConsole->Printf(KTxtFileChanges,iDrive);
    00926             return;
    00927             }
    00928
    00929         case CChangeNotifier::EChangeFileContents :
    00930             {
    00931             path.Append(iDrive);
    00932             _LIT(KPath,":\\private\\e80000fb\\filechange\\");
    00933             path.Append(KPath);
    00934             _LIT(KFileName,"file.txt");
    00935             filename.Append(KFileName);
    00936             fullname.Append(path);
    00937             fullname.Append(filename);
    00938             file.Replace(iFs,fullname,EFileWrite); //Replace produces Create notification
    00939             _LIT8(KFileData,"Some Data");
    00940             file.Write(KFileData);
    00941
    00942             _LIT(KTxtFileChanges,"\nfile contents of file.txt at %c drive at :\\private\\e80000fb\\filechange\\ location has changed\n");
    00943             iConsole->Printf(KTxtFileChanges,iDrive);
    00944             return;
    00945             }
    00946
    00947         case CChangeNotifier::ERenameFile :
    00948             {
    00949             path.Append(iDrive);
    00950             _LIT(KPath,":\\private\\e80000fb\\filechange\\");
    00951             path.Append(KPath);
    00952             _LIT(KFileName,"create.file");
    00953             filename.Append(KFileName);
    00954             fullname.Append(path);
    00955             fullname.Append(filename);
    00956
    00957             file.Replace(iFs,fullname,EFileWrite); //Replace produces Create notification
    00958             _LIT(KRenameFile,"NewFileName");
    00959             file.Rename(KRenameFile);
    00960
    00961             _LIT(KTxtFileChanges,"\ncreate.file at %c drive at :\\private\\e80000fb\\filechange\\ location has been renamed to NewFileName\n");
    00962             iConsole->Printf(KTxtFileChanges,iDrive);
    00963             return;
    00964             }
    00965
    00966         case CChangeNotifier::EChangeFileAttributes  :
    00967             {
    00968             path.Append(iDrive);
    00969             _LIT(KPath,":\\private\\e80000fb\\filechange\\");
    00970             path.Append(KPath);
    00971             _LIT(KFileName,"create.file");
    00972             filename.Append(KFileName);
    00973             fullname.Append(path);
    00974             fullname.Append(filename);
    00975             file.Replace(iFs,fullname,EFileWrite); //Replace produces Create notification
    00976             file.SetSize(134);
    00977
    00978             _LIT(KTxtFileChanges,"\ncreate.file at %c drive at :\\private\\e80000fb\\filechange\\ location has it attributes changed to 134bytes\n");
    00979             iConsole->Printf(KTxtFileChanges,iDrive);
    00980             return;
    00981             }
    00982         case CChangeNotifier::EDeleteFile :
    00983             {
    00984             path.Append(iDrive);
    00985             _LIT(KPath,":\\private\\e80000fb\\filechange\\deletefolder\\");
    00986             path.Append(KPath);
    00987             _LIT(KFileName,"file.txt");
    00988             filename.Append(KFileName);
    00989             fullname.Append(path);
    00990             fullname.Append(filename);
    00991             iFs.Delete(fullname);
    00992
    00993             _LIT(KTxtFileChanges,"\nfile.txt at %c drive at :\\private\\e80000fb\\filechange\\deletefolder\\ location has been deleted\n");
    00994             iConsole->Printf(KTxtFileChanges,iDrive);
    00995             return;
    00996             }
    00997         case CChangeNotifier::ECreateFolder :
    00998             {
    00999             path.Append(iDrive);
    01000             _LIT(KPath,":\\private\\e80000fb\\filechange\\createfolder\\");
    01001             path.Append(KPath);
    01002             iFs.MkDir(path);
    01003
    01004             _LIT(KTxtFileChanges,"\nA new folder 'createfolder' at %c drive at :\\private\\e80000fb\\filechange\\ location has been created\n");
    01005             iConsole->Printf(KTxtFileChanges,iDrive);
    01006             return;
    01007             }
    01008         case CChangeNotifier::ERenameFolder :
    01009             {
    01010             path.Append(iDrive);
    01011             _LIT(KPath,"\\private\\e80000fb\\filechange\\newfolder\\");
    01012             path.Append(KPath);
    01013
    01014             TBuf<80> newPath;
    01015             newPath.Append(iDrive);
    01016             _LIT(KNewPath,"\\private\\e80000fb\\filechange\\RenameFolder\\");
    01017             newPath.Append(KNewPath);
    01018             iFs.Rename(path,newPath);
    01019
    01020             _LIT(KTxtFileChanges,"\nnewfolder at %c drive at :\\private\\e80000fb\\filechange\\ location has been renamed to RenameFolder\n");
    01021             iConsole->Printf(KTxtFileChanges,iDrive);
    01022             return;
    01023             }
    01024         case CChangeNotifier::EDeleteFolder :
    01025             {
    01026             path.Append('U');
    01027             _LIT(KPath,":\\private\\e80000fb\\filechange\\deletefolder\\");
    01028             path.Append(KPath);
    01029             iFs.RmDir(path);
    01030
    01031             _LIT(KTxtFileChanges,"\ndeletefolder at %c drive at :\\private\\e80000fb\\filechange\\ location has been deleted\n");
    01032             iConsole->Printf(KTxtFileChanges,iDrive);
    01033             return;
    01034             }
    01035         case CChangeNotifier::EVolumeNameChange :
    01036             {
    01037             _LIT(KVolumeLabel,"MyNewDrive");
    01038             iDriveNumber = (TChar)'U'- (TChar)'A';
    01039             iFs.SetVolumeLabel(KVolumeLabel,iDriveNumber);
    01040             _LIT(KResult,"Volume name changed to MyNewDrive \n");
    01041             iConsole->Printf(KResult);
    01042             return;
    01043             }
    01044         case CChangeNotifier::EMultipleNotifications :
    01045             {
    01046             // Create a file 'notify.file'
    01047             path.Append(iDrive);
    01048             _LIT(KPath,":\\private\\e80000fb\\filechange\\");
    01049             path.Append(KPath);
    01050
    01051             TBuf<20> filename;
    01052             _LIT(KFileName,"notify.file");
    01053             filename.Append(KFileName);
    01054
    01055             fullname.Append(path);
    01056             fullname.Append(filename);
    01057             file.Replace(iFs,fullname,EFileWrite); //Replace produces Create notification
    01058
    01059             _LIT(KTxtFileChanges,"\nNew file notify.file created at %c drive at :\\private\\e80000fb\\filechange\\ location\n");
    01060             iConsole->Printf(KTxtFileChanges,iDrive);
    01061
    01062             _LIT(KRenameFile,"rename.file");
    01063             file.Rename(KRenameFile);
    01064
    01065             _LIT(KTxtFolderChanges,"\nnotify.file at %c drive at :\\private\\e80000fb\\filechange\\ location has been renamed to rename.file\n");
    01066             iConsole->Printf(KTxtFolderChanges,iDrive);
    01067             return;
    01068             }
    01069         }
    01070     file.Close();
    01071     }
    01072
    01073 void CChangeNotifier::PressAnyKey()
    01074     {
    01075     iOptionContinue = ETrue;
    01076     _LIT(KPressAnyKey,"Press any key to continue");
    01077     iConsole->Printf(KPressAnyKey);
    01078     iConsole->Read(iStatus);
    01079     if(!IsActive())
    01080         {
    01081         SetActive();
    01082         }
    01083     }
    01084
    01085 void CChangeNotifier::DoCancel()
    01086     {
    01087     iNotify->CancelNotifications(iReqStatus);
    01088     iConsole->ReadCancel();
    01089     }
    01090
    01091
    01092 void CChangeNotifier::RequestCharacter()
    01093     {
    01094     iOption = EFalse;
    01095     iOptionContinue = EFalse;
    01096     iDeleteFileContinue = EFalse;
    01097     _LIT(KMenuL1,"\nChoose an option:\n");
    01098     _LIT(KMenuL2,"1.Get notified when a file changes\n");
    01099     _LIT(KMenuL3,"2.Get notified when a folder changes\n");
    01100     _LIT(KMenuL4,"3.Get notified when the volume name changes\n");
    01101     _LIT(KMenuL5,"4.Multiple notifications\n");
    01102
    01103     iConsole->Printf(KMenuL1);
    01104     iConsole->Printf(KMenuL2);
    01105     iConsole->Printf(KMenuL3);
    01106     iConsole->Printf(KMenuL4);
    01107     iConsole->Printf(KMenuL5);
    01108
    01109     TChar choice = iConsole->Getch();
    01110     switch(choice)
    01111         {
    01112         case '1':
    01113             {
    01114             NotifyChangeToFile();
    01115             break;
    01116             }
    01117         case '2':
    01118             {
    01119             NotifyChangeToFolder();
    01120             break;
    01121             }
    01122         case '3':
    01123             {
    01124             VolumeNameChange();
    01125             break;
    01126             }
    01127         case '4':
    01128                    {
    01129                    MultipleNotifications();
    01130                    break;
    01131                    }
    01132         default:
    01133             {
    01134             iOption = ETrue;
    01135             _LIT(KPressAnyKey,"Press any key to Exit");
    01136             iConsole->Printf(KPressAnyKey);
    01137             iConsole->Read(iStatus);
    01138             if(!IsActive())
    01139                 {
    01140                 SetActive();
    01141                 }
    01142             break;
    01143             }
    01144         }
    01145     }
    01146
    01147 static void MainL()
    01148     {
    01149     CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
    01150     CleanupStack::PushL(scheduler);
    01151     CActiveScheduler::Install(scheduler);
    01152     CChangeNotifier* changeNotifier = CChangeNotifier::NewL();
    01153     CleanupStack::PushL(changeNotifier);
    01154     changeNotifier->RequestCharacter();
    01155     CActiveScheduler::Start();
    01156
    01157     CleanupStack::PopAndDestroy(changeNotifier);
    01158     CleanupStack::PopAndDestroy(scheduler);
    01159     }
    01160
    01161 extern TInt E32Main()
    01162     {
    01163     // Create cleanup stack
    01164     __UHEAP_MARK;
    01165     CTrapCleanup* cleanup = CTrapCleanup::New();
    01166     if(cleanup == NULL)
    01167         {
    01168         return KErrNoMemory;
    01169         }
    01170
    01171     // Run application code inside a TRAP harness.
    01172     TRAPD(mainError, MainL());
    01173     if(mainError != KErrNone)
    01174         {
    01175         _LIT(KUserPanic,"Failed to complete");
    01176         User::Panic(KUserPanic, mainError);
    01177         }
    01178     delete cleanup;
    01179     __UHEAP_MARKEND;
    01180     return KErrNone;
    01181     }