From ce0f90fd7853eee1b2e6a77a636b58033d6ac2dd Mon Sep 17 00:00:00 2001 From: "racham%netscape.com" Date: Fri, 14 Jul 2000 03:10:18 +0000 Subject: [PATCH] Fixing bug 13850. Profile Manager now handles out of disk space errors passed by prefmigrator. r=dbragg --- profile/macbuild/profile.mcp | Bin 140815 -> 140815 bytes profile/src/Makefile.in | 1 + profile/src/makefile.win | 3 + profile/src/nsProfile.cpp | 212 +++++++++++++++++++++++++++++++++-- profile/src/nsProfile.h | 3 + 5 files changed, 212 insertions(+), 7 deletions(-) diff --git a/profile/macbuild/profile.mcp b/profile/macbuild/profile.mcp index 511bcb0ab4571bb9f1fccea06456f0b10b621c8c..1c93b7e26c7a2307e0ce0c84510004176847dfc5 100644 GIT binary patch delta 1733 zcmb7_YfM~46vt=g?u%V4EO(cen&m0zQeKs!tL3%q3Z#`K)i(X0r98C2LJ_P+NrUJI znwkdINnOF1w574qs%aU?nwXeijP?V@)VA1ElWH52CK^k$Hd<)b|J+%s@tY^i%$eVr zIdkTJ?_DMqZ4-;OQ*K7>yuBqOH;E8pMzf$<(QIfA*)()$)BHnLkPK%Eb7@IDo#i|2 z@MLqyJ!nVyK$|D&FuWtiEM4cLwtl9Rp6qNGAy2~LqCyZ~=J^V9wN7VHd zO_k@1pY$wB%{=bPu?3qq2jp$I$L$8Ha^FGI{7H9pA<-)aLPjF*``$GhBV%OE_j==A z-lx|_LS~-Y;t>Vumy0cvOPAvDYr<)6q>)gJo9Z*HlNX@ax^Kinc!l!1Ig>LPS*57S z^ZdLc9>2XwbO+sxf7*S9rvz)nxjlWNY@Aj=BKd(*Spg~>kG#633$Q`lL7?v_B4sFiRgx_yPiB9gA zdWf%vhUC+gM@`A&#B|#YDwcL&Gl%9oR`Iy7P0^izx#W(%}UZD6$Vf1YeE3IrjiDIlWPU8J0#EVqCqZuz; zj^b}!1us^7{LAQyhn0<{W4ca-yLKY%RbjmkV~0ACK8ew; z^2|aPR+``_izKV{w(r2p6b}S3em*!fD(hXDMW9>-wjRViGF76zm%%F(@0Oyyr}(ws zz$+EEHef7Qe0ddogW@kf0^c~8#801q|DfV}5=KK`5C$>bdN z(qrf#yL`K7Be+x#HiiqVslNEvC<1;J==mOFLiQQ?IIu}t^CCJ!c1l{`0S_3MOnd-8 zA^Y)T@a1!cHRI8cVnd16k$G@g2&|4%p!zjqe<`9(4ifIGozmWM4g~$ll&YD@=mm@fyKN= zE8*8!k)04qoSe?r4^B`gU#B$`*eQ(2pG?POCyfU*pGFcH@wxV<=9W{`9Lh8Kr6TT3 zxl=PgP#bS|R`By$E)VJ+-mB;F&peG;|IFrrcAXd5eR4DLi(W{vAhW>lZGUNfSZzZV z*;|dst}PhZc!S5!4NqNdQ}*V~q`79Q?x$Js^*vkJhOv!CJYL^365nYI`a?US{l;*8 zc-Yu%3>&X+GUD}X4L+c65<&0Ha%bK3hndVfKZ=XVdz9N&6#(3WYR3QqOnlVkr2Jt= z8E+r?l5aOo@Jk)bcy4H=4_irLbLRZiilQ`-C{M`bo;8dW1K5tDnL= zm{d)QCYRdK9B5EkR)DzB%+iScFFI)&DHs(8))Z)>evglG_r$aOL3o%i?+&_T!7!VM z!`-t~vlA-1Cp=UfTlbq=bVLH0I6aob`0A1AWY}dUV##o`N^@h|DRF4~A|_sl6l-E_ zXn^wZ_HynsTd7EH1i1QId1__>T_To@>JC0+ObY*QhdL1x-zIYz^5-MvW8&j+O2x}> zH4VC%d9Oed?kFa2FSSv>aL21`c~T%1^INeho5+cK*}1z58D)ab57G36ee@eG{fdLu z+Eab!Xjy814lPKAZRs7C=yJQbkgU@7_UbgD`0mh+i@lJb|DKn*lBDM zOkXZ!&06P>z!A<5?uB z#n-^+sQIqz;7b*69fJQNHk^>>y?+vcWh&5x4X95g+I17WO7XT@_!El%`X_j`;<|ju z%M_n^0KQ!DO=t0KZcH*~PvN^papwkjQ(uz#`Y6dGOeTii#XrUsOVtHfbE4=({&Db?7Kd_kvPaK=H(?C(UPfoh{wfa1R+*R>pTa|S`MPK; zxGWoN>-UdTpZ+U>K#K}&`vcyR{fI0F7D;QnfzFhjlCBTH+e}OnP;*Z9<45rwQe2;c zFE^Fw8pSu07lO5RptE>g6nr(t={t+r6}FJzjo3|9iPmxeu`O~1q4qtgTcxbxZ-mu% AEC2ui diff --git a/profile/src/Makefile.in b/profile/src/Makefile.in index 102438297b4e..99007d232c80 100644 --- a/profile/src/Makefile.in +++ b/profile/src/Makefile.in @@ -37,6 +37,7 @@ CPPSRCS = nsProfile.cpp \ EXTRA_DSO_LDOPTS = \ -L$(DIST)/bin \ $(XPCOM_LIBS) \ + $(MOZ_JS_LIBS) \ $(NSPR_LIBS) \ $(NULL) diff --git a/profile/src/makefile.win b/profile/src/makefile.win index c5d3bf13696c..ef7ec4e399b5 100644 --- a/profile/src/makefile.win +++ b/profile/src/makefile.win @@ -79,6 +79,9 @@ BINREL_DIST=$(XPDIST)\WIN954.0_DBG.OBJD LLIBS = \ $(LIBNSPR) \ $(DIST)\lib\xpcom.lib \ + $(DIST)\lib\js3250.lib \ + $(DIST)\lib\jsdombase_s.lib \ + $(DIST)\lib\jsdomevents_s.lib \ $(NULL) #//------------------------------------------------------------------------ diff --git a/profile/src/nsProfile.cpp b/profile/src/nsProfile.cpp index 01ea17aa35b5..c93f18cc8d62 100644 --- a/profile/src/nsProfile.cpp +++ b/profile/src/nsProfile.cpp @@ -44,6 +44,7 @@ #include "nsIIOService.h" #include "nsNetUtil.h" +#include "nsPrefMigration.h" #include "nsIPrefMigration.h" #include "nsPrefMigrationCIDs.h" #include "nsFileStream.h" @@ -66,6 +67,12 @@ #include "nsIWebShell.h" #include "nsIWebBrowserChrome.h" +#include "nsIScriptGlobalObject.h" +#include "nsIBaseWindow.h" +#include "nsICommonDialogs.h" +#include "nsIDOMWindow.h" +#include "nsIWindowMediator.h" + #if defined (XP_UNIX) #elif defined (XP_MAC) #define OLD_REGISTRY_FILE_NAME "Netscape Registry" @@ -130,6 +137,8 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); static NS_DEFINE_CID(kPrefMigrationCID, NS_PREFMIGRATION_CID); static NS_DEFINE_CID(kPrefConverterCID, NS_PREFCONVERTER_CID); static NS_DEFINE_IID(kCookieServiceCID, NS_COOKIESERVICE_CID); +static NS_DEFINE_CID(kDialogParamBlockCID, NS_DialogParamBlock_CID); +static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID); static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID); @@ -162,6 +171,8 @@ nsresult GetStringFromSpec(nsFileSpec inSpec, char **string) nsProfile::nsProfile() { mAutomigrate = PR_FALSE; + mOutofDiskSpace = PR_FALSE; + mDiskSpaceErrorQuitCalled = PR_FALSE; if(!gProfileDataAccess) gProfileDataAccess = new nsProfileAccess(); @@ -236,6 +247,11 @@ nsProfile::StartupWithArgs(nsICmdLineService *cmdLineArgs) if (cmdLineArgs) rv = ProcessArgs(cmdLineArgs, &profileDirSet, profileURLStr); + // This boolean is set only when an automigrated user runs out of disk space + // and chooses to cancel further operations from the dialogs presented... + if (mDiskSpaceErrorQuitCalled) + return NS_ERROR_FAILURE; + if (!profileDirSet) { rv = LoadDefaultProfileDir(profileURLStr); @@ -400,7 +416,9 @@ nsProfile::AutoMigrate() // automatically migrate the one 4.x profile rv = MigrateAllProfiles(); - if (NS_FAILED(rv)) + // Create a default profile if automigration failed for reasons + // other than out of disk space case... + if (NS_FAILED(rv) && !mOutofDiskSpace) { #ifdef DEBUG_profile printf("AutoMigration failed. Let's create a default 5.0 profile.\n"); @@ -408,7 +426,7 @@ nsProfile::AutoMigrate() rv = CreateDefaultProfile(); if (NS_FAILED(rv)) return rv; - } + } gProfileDataAccess->mProfileDataChanged = PR_TRUE; gProfileDataAccess->UpdateRegistry(); @@ -1374,12 +1392,12 @@ nsProfile::MigrateProfile(const PRUnichar* profileName, PRBool showProgressAsMod newSpec->GetFileSpec(&newProfDir); newProfDir += profileName; - newProfDir.MakeUnique(); + newProfDir.MakeUnique(); if (newProfDir.Exists()) { #ifdef DEBUG_profile - printf("directory already exists\n"); + printf("directory already exists\n"); #endif - return NS_ERROR_FAILURE; + return NS_ERROR_FAILURE; } // Call migration service to do the work. @@ -1395,10 +1413,11 @@ nsProfile::MigrateProfile(const PRUnichar* profileName, PRBool showProgressAsMod nsXPIDLCString oldProfDirStr; nsXPIDLCString newProfDirStr; - + if (!newProfDir.Exists()) { newProfDir.CreateDirectory(); - } + } + rv = GetStringFromSpec(newProfDir, getter_Copies(newProfDirStr)); if (NS_FAILED(rv)) return rv; @@ -1414,6 +1433,58 @@ nsProfile::MigrateProfile(const PRUnichar* profileName, PRBool showProgressAsMod rv = pPrefMigrator->ProcessPrefs(showProgressAsModalWindow); if (NS_FAILED(rv)) return rv; + // check for diskspace errors + nsresult errorCode; + errorCode = pPrefMigrator->GetError(); + + // In either of the cases below we have to return error to make + // app understand that migration has failed. + if (errorCode == CREATE_NEW) + { + PRInt32 numProfiles = 0; + ShowProfileWizard(); + + // When the automigration process fails because of disk space error, + // we present user a create profile wizard if the user chooses to create a + // a profile then. But then the user may click on cancel on that dialog... + // So, if the user clicks on cancel, the number of profiles should be + // ZERO at the point for the user who failed to automigrate single 4x profile. + // On such condition, set mDiskSpaceErrorQuitCalled to allow user to quit the app. + // If the user is presented with profilemanager dialog with multiple 4x profiles + // to migrate, value of mDiskSpaceErrorQuitCalled does not matter as it gets ignored.. + // If a single profile needs automigration and no confirmation + // is needed for that operation mAutomigrate is set to false. + if (!mAutomigrate) + { + GetProfileCount(&numProfiles); + if (numProfiles == 0) + mDiskSpaceErrorQuitCalled = PR_TRUE; + } + mOutofDiskSpace = PR_TRUE; + return NS_ERROR_FAILURE; + } + else if (errorCode == CANCEL) + { + // When the automigration process fails because of disk space error, + // user may choose to simply quit the app from the dialog presented + // by pref-migrator. So, set mDiskSpaceErrorQuitCalled to allow user + // to quit the app in such a case. + // If the user is presented with profilemanager dialog with multiple 4x profiles + // to migrate, value of mDiskSpaceErrorQuitCalled does not matter as it gets ignored.. + // If a single profile needs automigration and no confirmation + // is needed for that operation mAutomigrate is set to false. + if (!mAutomigrate) + mDiskSpaceErrorQuitCalled = PR_TRUE; + + ForgetCurrentProfile(); + mOutofDiskSpace = PR_TRUE; + return NS_ERROR_FAILURE; + } + else if (errorCode != SUCCESS) + { + return NS_ERROR_FAILURE; + } + // Copy the default 5.0 profile files into the migrated profile // Get profile defaults folder.. nsCOMPtr profDefaultsDir; @@ -1445,6 +1516,133 @@ nsProfile::MigrateProfile(const PRUnichar* profileName, PRBool showProgressAsMod return rv; } +nsresult +nsProfile::ShowProfileWizard(void) +{ + nsresult rv = NS_OK; + PRBool hasParentWindow = PR_FALSE; + nsCOMPtr PMDOMWindow; + + // Get the window mediator + NS_WITH_SERVICE(nsIWindowMediator, windowMediator, kWindowMediatorCID, &rv); + if (NS_SUCCEEDED(rv)) + { + nsCOMPtr windowEnumerator; + + if (NS_SUCCEEDED(windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator)))) + { + // Get each dom window + PRBool more; + windowEnumerator->HasMoreElements(&more); + while (more) + { + nsCOMPtr protoWindow; + rv = windowEnumerator->GetNext(getter_AddRefs(protoWindow)); + if (NS_SUCCEEDED(rv) && protoWindow) + { + PMDOMWindow = do_QueryInterface(protoWindow); + if (PMDOMWindow) + { + hasParentWindow = PR_TRUE; + break; + } + } + windowEnumerator->HasMoreElements(&more); + } + } + } + + if (hasParentWindow) + { + // Get the script global object for the window + nsCOMPtr sgo; + sgo = do_QueryInterface(PMDOMWindow); + if (!sgo) return NS_ERROR_FAILURE; + + // Get the script context from the global context + nsCOMPtr scriptContext; + sgo->GetContext( getter_AddRefs(scriptContext)); + if (!scriptContext) return NS_ERROR_FAILURE; + + // Get the JSContext from the script context + JSContext* jsContext = (JSContext*)scriptContext->GetNativeContext(); + if (!jsContext) return NS_ERROR_FAILURE; + + + //----------------------------------------------------- + // Create the nsIDialogParamBlock to pass the trigger + // list to the dialog + //----------------------------------------------------- + nsCOMPtr ioParamBlock; + rv = nsComponentManager::CreateInstance(kDialogParamBlockCID, + nsnull, + NS_GET_IID(nsIDialogParamBlock), + getter_AddRefs(ioParamBlock)); + + + if ( NS_SUCCEEDED( rv ) ) + ioParamBlock->SetInt(0,4); // standard wizard buttons + + + void* stackPtr; + jsval *argv = JS_PushArguments( jsContext, + &stackPtr, + "sss%ip", + PROFILE_WIZARD_URL, + "_blank", + "chrome,modal", + (const nsIID*)(&NS_GET_IID(nsIDialogParamBlock)), + (nsISupports*)ioParamBlock); + + if (argv) + { + nsCOMPtr newWindow; + rv = PMDOMWindow->OpenDialog(jsContext, + argv, + 4, + getter_AddRefs(newWindow)); + if (NS_SUCCEEDED(rv)) + { + JS_PopArguments( jsContext, stackPtr); + } + else + return NS_ERROR_FAILURE; + } + else + return NS_ERROR_FAILURE; + + } + else + { + // No parent window is available. + // So, Create top level window with create profile wizard + NS_WITH_SERVICE(nsIAppShellService, wizAppShell, + kAppShellServiceCID, &rv); + if (NS_FAILED(rv)) return rv; + + nsCString profURLStr = PROFILE_WIZARD_URL; + nsCOMPtr profURI; + rv = NS_NewURI(getter_AddRefs(profURI), (const char *)profURLStr); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr newWindow; + rv = wizAppShell->CreateTopLevelWindow(nsnull, profURI, + PR_TRUE, PR_TRUE, CHROME_STYLE, + NS_SIZETOCONTENT, // width + NS_SIZETOCONTENT, // height + getter_AddRefs(newWindow)); + + if (NS_FAILED(rv)) return rv; + + /* + * Bring up the wizard... + */ + rv = wizAppShell->Run(); + } + return rv; + +} + NS_IMETHODIMP nsProfile::ProfileExists(const PRUnichar *profileName, PRBool *exists) { NS_ENSURE_ARG_POINTER(profileName); diff --git a/profile/src/nsProfile.h b/profile/src/nsProfile.h index 5942104375d3..2d66f7842bb1 100644 --- a/profile/src/nsProfile.h +++ b/profile/src/nsProfile.h @@ -69,6 +69,8 @@ private: nsFileSpec& newProfDir, const char *fileName); PRBool mAutomigrate; + PRBool mOutofDiskSpace; + PRBool mDiskSpaceErrorQuitCalled; public: nsProfile(); @@ -88,5 +90,6 @@ public: nsresult AutoMigrate(); nsresult CreateDefaultProfile(void); + nsresult ShowProfileWizard(void); };