Back to index

lightning-sunbird  0.9+nobinonly
nsWinReg.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsWinReg.h"
00039 #include "nsWinRegItem.h"
00040 #include "nsNativeCharsetUtils.h"
00041 #include <windows.h>
00042 
00043 
00044 /* Public Methods */
00045 
00046 MOZ_DECL_CTOR_COUNTER(nsWinReg)
00047 
00048 nsWinReg::nsWinReg(nsInstall* suObj)
00049 {
00050     MOZ_COUNT_CTOR(nsWinReg);
00051 
00052     mInstallObject      = suObj;
00053        mRootKey = (PRInt32)HKEY_CLASSES_ROOT;
00054 }
00055 
00056 nsWinReg::~nsWinReg()
00057 {
00058     MOZ_COUNT_DTOR(nsWinReg);
00059 }
00060 
00061 PRInt32
00062 nsWinReg::SetRootKey(PRInt32 key)
00063 {
00064        mRootKey = key;
00065     return NS_OK;
00066 }
00067   
00068 PRInt32
00069 nsWinReg::CreateKey(const nsAString& subkey, const nsAString& classname, PRInt32* aReturn)
00070 {
00071        nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_CREATE, subkey, classname, NS_LITERAL_STRING("null"), aReturn);
00072 
00073   if(wi == nsnull)
00074   {
00075     *aReturn = nsInstall::OUT_OF_MEMORY;
00076     return NS_OK;
00077   }
00078 
00079   if(*aReturn != nsInstall::SUCCESS)
00080   {
00081     if(wi)
00082     {
00083       delete wi;
00084       return NS_OK;
00085     }
00086   }
00087 
00088   if(mInstallObject)
00089        *aReturn = mInstallObject->ScheduleForInstall(wi);
00090        
00091   return 0;
00092 }
00093   
00094 PRInt32
00095 nsWinReg::DeleteKey(const nsAString& subkey, PRInt32* aReturn)
00096 {
00097        nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_DELETE, subkey, NS_LITERAL_STRING("null"), NS_LITERAL_STRING("null"), aReturn);
00098 
00099   if(wi == nsnull)
00100   {
00101     *aReturn = nsInstall::OUT_OF_MEMORY;
00102     return NS_OK;
00103   }
00104 
00105   if(*aReturn != nsInstall::SUCCESS)
00106   {
00107     if(wi)
00108     {
00109       delete wi;
00110       return NS_OK;
00111     }
00112   }
00113 
00114   if(mInstallObject)
00115     *aReturn = mInstallObject->ScheduleForInstall(wi);
00116 
00117   return 0;
00118 }
00119 
00120 PRInt32
00121 nsWinReg::DeleteValue(const nsAString& subkey, const nsAString& valname, PRInt32* aReturn)
00122 {
00123        nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_DELETE_VAL, subkey, valname, NS_LITERAL_STRING("null"), aReturn);
00124 
00125   if(wi == nsnull)
00126   {
00127     *aReturn = nsInstall::OUT_OF_MEMORY;
00128     return NS_OK;
00129   }
00130 
00131   if(*aReturn != nsInstall::SUCCESS)
00132   {
00133     if(wi)
00134     {
00135       delete wi;
00136       return NS_OK;
00137     }
00138   }
00139 
00140   if(mInstallObject)
00141     *aReturn = mInstallObject->ScheduleForInstall(wi);
00142 
00143   return 0;
00144 }
00145 
00146 PRInt32
00147 nsWinReg::SetValueString(const nsAString& subkey, const nsAString& valname, const nsAString& value, PRInt32* aReturn)
00148 {
00149        nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_SET_VAL_STRING, subkey, valname, value, aReturn);
00150 
00151   if(wi == nsnull)
00152   {
00153     *aReturn = nsInstall::OUT_OF_MEMORY;
00154     return NS_OK;
00155   }
00156 
00157   if(*aReturn != nsInstall::SUCCESS)
00158   {
00159     if(wi)
00160     {
00161       delete wi;
00162       return NS_OK;
00163     }
00164   }
00165 
00166   if(mInstallObject)
00167     *aReturn = mInstallObject->ScheduleForInstall(wi);
00168        
00169   return 0;
00170 }
00171 
00172 PRInt32
00173 nsWinReg::GetValueString(const nsString& subkey, const nsString& valname, nsString* aReturn)
00174 {
00175    return NativeGetValueString(subkey, valname, aReturn);
00176 }
00177  
00178 PRInt32
00179 nsWinReg::EnumValueNames(const nsString& aSubkey, PRInt32 aIndex, nsString &aReturn)
00180 {
00181     char           namebuf[MAX_BUF];
00182     HKEY           root;
00183     HKEY           newkey;
00184     LONG           result;
00185     DWORD          namesize         = sizeof(namebuf);
00186     PRInt32        rv = nsInstall::UNEXPECTED_ERROR;
00187 
00188     nsCAutoString subkey;
00189     if ( NS_FAILED ( NS_CopyUnicodeToNative(aSubkey, subkey) ) )
00190         return nsInstall::UNEXPECTED_ERROR;
00191 
00192     root   = (HKEY) mRootKey;
00193     result = RegOpenKeyEx( root, subkey.get(), 0, KEY_READ, &newkey );
00194 
00195     if ( ERROR_SUCCESS == result ) {
00196         result = RegEnumValue( newkey, aIndex, namebuf, &namesize, nsnull, 0, 0, 0 );
00197         RegCloseKey( newkey );
00198 
00199         if ( ERROR_SUCCESS == result ) {
00200             nsCAutoString cstrName(namebuf);
00201             nsAutoString name;
00202             if(NS_SUCCEEDED(NS_CopyNativeToUnicode(cstrName, name)))
00203             {
00204                 aReturn.Assign(name);
00205                 rv = nsInstall::SUCCESS;
00206             }
00207         } 
00208     }
00209 
00210     return rv;
00211 }
00212 
00213 PRInt32
00214 nsWinReg::EnumKeys(const nsString& aSubkey, PRInt32 aIndex, nsString &aReturn)
00215 {
00216     char            keybuf[MAX_BUF];
00217     HKEY            root;
00218     HKEY            newkey;
00219     LONG            result;
00220     DWORD           type            = REG_SZ;
00221     PRInt32         rv = nsInstall::UNEXPECTED_ERROR;
00222 
00223     nsCAutoString subkey;
00224     if ( NS_FAILED(NS_CopyUnicodeToNative(aSubkey, subkey) ) )
00225         return nsInstall::UNEXPECTED_ERROR;
00226 
00227     root   = (HKEY) mRootKey;
00228     result = RegOpenKeyEx( root, subkey.get(), 0, KEY_READ, &newkey );
00229 
00230     if ( ERROR_SUCCESS == result ) {
00231         result = RegEnumKey( newkey, aIndex, keybuf, sizeof keybuf );
00232         RegCloseKey( newkey );
00233         
00234         if ( ERROR_SUCCESS == result ) {
00235             nsCAutoString cstrKey(keybuf);
00236             nsAutoString key;
00237             if (NS_SUCCEEDED(NS_CopyNativeToUnicode(cstrKey, key) ) )
00238             {
00239                 aReturn.Assign(key);
00240                 rv = nsInstall::SUCCESS;
00241             }
00242         }
00243     }
00244 
00245     return rv;
00246 }
00247 
00248 PRInt32
00249 nsWinReg::SetValueNumber(const nsString& subkey, const nsString& valname, PRInt32 value, PRInt32* aReturn)
00250 {
00251        nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_SET_VAL_NUMBER, subkey, valname, value, aReturn);
00252 
00253   if(wi == nsnull)
00254   {
00255     *aReturn = nsInstall::OUT_OF_MEMORY;
00256     return NS_OK;
00257   }
00258 
00259   if(*aReturn != nsInstall::SUCCESS)
00260   {
00261     if(wi)
00262     {
00263       delete wi;
00264       return NS_OK;
00265     }
00266   }
00267 
00268   if(mInstallObject)
00269     *aReturn = mInstallObject->ScheduleForInstall(wi);
00270 
00271   return 0;
00272 }
00273 
00274 PRInt32
00275 nsWinReg::GetValueNumber(const nsString& subkey, const nsString& valname, PRInt32* aReturn)
00276 {
00277     return NativeGetValueNumber(subkey, valname, aReturn);
00278 }
00279  
00280 PRInt32
00281 nsWinReg::SetValue(const nsString& subkey, const nsString& valname, nsWinRegValue* value, PRInt32* aReturn)
00282 {
00283   // fix: need to figure out what to do with nsWinRegValue class.
00284   //
00285        // nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_SET_VAL, subkey, valname, (nsWinRegValue*)value, aReturn);
00286   //
00287        // if(wi == nsnull)
00288   // {
00289   //   return NS_OK;
00290   // }
00291        // mInstallObject->ScheduleForInstall(wi);
00292        return 0;
00293 }
00294   
00295 PRInt32
00296 nsWinReg::GetValue(const nsString& subkey, const nsString& valname, nsWinRegValue** aReturn)
00297 {
00298   // fix:
00299   return NS_OK;
00300 }
00301   
00302 nsInstall* nsWinReg::InstallObject()
00303 {
00304        return mInstallObject;
00305 }
00306   
00307 PRInt32
00308 nsWinReg::KeyExists(const nsString& subkey,
00309                     PRBool* aReturn)
00310 {
00311   *aReturn = NativeKeyExists(subkey);
00312   return NS_OK;
00313 }
00314 
00315 PRInt32
00316 nsWinReg::ValueExists(const nsString& subkey,
00317                       const nsString& valname,
00318                       PRBool* aReturn)
00319 {
00320   *aReturn = NativeValueExists(subkey, valname);
00321   return NS_OK;
00322 }
00323  
00324 PRInt32
00325 nsWinReg::IsKeyWritable(const nsString& subkey,
00326                         PRBool* aReturn)
00327 {
00328   *aReturn = NativeIsKeyWritable(subkey);
00329   return NS_OK;
00330 }
00331 
00332 PRInt32
00333 nsWinReg::PrepareCreateKey(PRInt32 root,
00334                            const nsString& subkey,
00335                            PRInt32* aReturn)
00336 {
00337   SetRootKey(root);
00338   if(NativeIsKeyWritable(subkey))
00339     *aReturn = nsInstall::SUCCESS;
00340   else
00341     *aReturn = nsInstall::KEY_ACCESS_DENIED;
00342 
00343   return NS_OK;
00344 }
00345 
00346 PRInt32
00347 nsWinReg::PrepareDeleteKey(PRInt32 root,
00348                            const nsString& subkey,
00349                            PRInt32* aReturn)
00350 {
00351   SetRootKey(root);
00352   if(NativeKeyExists(subkey))
00353   {
00354     if(NativeIsKeyWritable(subkey))
00355       *aReturn = nsInstall::SUCCESS;
00356     else
00357       *aReturn = nsInstall::KEY_ACCESS_DENIED;
00358   }
00359   else
00360     *aReturn = nsInstall::KEY_DOES_NOT_EXIST;
00361 
00362   return NS_OK;
00363 }
00364   
00365 PRInt32
00366 nsWinReg::PrepareDeleteValue(PRInt32 root,
00367                              const nsString& subkey,
00368                              const nsString& valname,
00369                              PRInt32* aReturn)
00370 {
00371   SetRootKey(root);
00372   if(NativeValueExists(subkey, valname))
00373   {
00374     if(NativeIsKeyWritable(subkey))
00375       *aReturn = nsInstall::SUCCESS;
00376     else
00377       *aReturn = nsInstall::KEY_ACCESS_DENIED;
00378   }
00379   else
00380     *aReturn = nsInstall::VALUE_DOES_NOT_EXIST;
00381 
00382   return NS_OK;
00383 }
00384 
00385 PRInt32
00386 nsWinReg::PrepareSetValueString(PRInt32 root,
00387                                 const nsString& subkey,
00388                                 PRInt32* aReturn)
00389 {
00390   SetRootKey(root);
00391   if(NativeIsKeyWritable(subkey))
00392     *aReturn = nsInstall::SUCCESS;
00393   else
00394     *aReturn = nsInstall::KEY_ACCESS_DENIED;
00395 
00396   return NS_OK;
00397 }
00398  
00399 PRInt32
00400 nsWinReg::PrepareSetValueNumber(PRInt32 root,
00401                                 const nsString& subkey,
00402                                 PRInt32* aReturn)
00403 {
00404   SetRootKey(root);
00405   if(NativeIsKeyWritable(subkey))
00406     *aReturn = nsInstall::SUCCESS;
00407   else
00408     *aReturn = nsInstall::KEY_ACCESS_DENIED;
00409 
00410   return NS_OK;
00411 }
00412  
00413 PRInt32
00414 nsWinReg::PrepareSetValue(PRInt32 root,
00415                           const nsString& subkey,
00416                           PRInt32* aReturn)
00417 {
00418   SetRootKey(root);
00419   if(NativeIsKeyWritable(subkey))
00420     *aReturn = nsInstall::SUCCESS;
00421   else
00422     *aReturn = nsInstall::KEY_ACCESS_DENIED;
00423 
00424   return NS_OK;
00425 }
00426 
00427 PRInt32
00428 nsWinReg::FinalCreateKey(PRInt32 root, const nsString& subkey, const nsString& classname, PRInt32* aReturn)
00429 {
00430        SetRootKey(root);
00431        *aReturn = NativeCreateKey(subkey, classname);
00432   return NS_OK;
00433 }
00434   
00435 PRInt32
00436 nsWinReg::FinalDeleteKey(PRInt32 root, const nsString& subkey, PRInt32* aReturn)
00437 {
00438        SetRootKey(root);
00439   if ( PR_TRUE == NativeKeyExists(subkey) )
00440     *aReturn = NativeDeleteKey(subkey);
00441   else {
00442     NS_WARNING("Trying to delete a key that doesn't exist anymore. Possible causes include calling deleteKey for the same key multiple times, or key+subkey are not unique");
00443     *aReturn = ERROR_SUCCESS;
00444   }
00445   return NS_OK;
00446 }
00447   
00448 PRInt32
00449 nsWinReg::FinalDeleteValue(PRInt32 root, const nsString& subkey, const nsString& valname, PRInt32* aReturn)
00450 {
00451        SetRootKey(root);
00452        *aReturn = NativeDeleteValue(subkey, valname);
00453   return NS_OK;
00454 }
00455 
00456 PRInt32
00457 nsWinReg::FinalSetValueString(PRInt32 root, const nsString& subkey, const nsString& valname, const nsString& value, PRInt32* aReturn)
00458 {
00459        SetRootKey(root);
00460        *aReturn = NativeSetValueString(subkey, valname, value);
00461   return NS_OK;
00462 }
00463  
00464 PRInt32
00465 nsWinReg::FinalSetValueNumber(PRInt32 root, const nsString& subkey, const nsString& valname, PRInt32 value, PRInt32* aReturn)
00466 {
00467        SetRootKey(root);
00468        *aReturn = NativeSetValueNumber(subkey, valname, value);
00469   return NS_OK;
00470 }
00471  
00472 PRInt32
00473 nsWinReg::FinalSetValue(PRInt32 root, const nsString& subkey, const nsString& valname, nsWinRegValue* value, PRInt32* aReturn)
00474 {
00475        SetRootKey(root);
00476        *aReturn = NativeSetValue(subkey, valname, value);
00477   return NS_OK;
00478 }
00479 
00480 
00481 /* Private Methods */
00482 
00483 PRBool
00484 nsWinReg::NativeKeyExists(const nsString& aSubkey)
00485 {
00486     HKEY    root, newkey;
00487     LONG    result;
00488     PRBool  keyExists     = PR_FALSE;
00489 
00490 #ifdef WIN32
00491     nsCAutoString subkey;
00492 
00493     if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) )
00494         return PR_FALSE;
00495 
00496     root   = (HKEY)mRootKey;
00497     result = RegOpenKeyEx(root, subkey.get(), 0, KEY_READ, &newkey);
00498     switch(result)
00499     {
00500         case ERROR_SUCCESS:
00501             RegCloseKey(newkey);
00502             keyExists = PR_TRUE;
00503             break;
00504 
00505         case ERROR_FILE_NOT_FOUND:
00506         case ERROR_ACCESS_DENIED:
00507         default:
00508             break;
00509     }
00510 #endif
00511 
00512     return keyExists;
00513 }
00514 
00515 PRBool
00516 nsWinReg::NativeValueExists(const nsString& aSubkey, const nsString& aValname)
00517 {
00518     HKEY          root;
00519     HKEY          newkey;
00520     LONG          result;
00521     PRBool        valueExists = PR_FALSE;
00522     DWORD         length      = _MAXKEYVALUE_;
00523     unsigned char valbuf[_MAXKEYVALUE_];
00524     
00525 #ifdef WIN32
00526     nsCAutoString subkey;
00527     nsCAutoString valname;
00528 
00529     if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
00530          NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
00531         return PR_FALSE;
00532 
00533     root   = (HKEY) mRootKey;
00534     result = RegOpenKeyEx(root, subkey.get(), 0, KEY_READ, &newkey);
00535     switch(result)
00536     {
00537         case ERROR_SUCCESS:
00538             result = RegQueryValueEx(newkey,
00539                                      valname.get(),
00540                                      0,
00541                                      NULL,
00542                                      valbuf,
00543                                      &length);
00544             switch(result)
00545             {
00546                 case ERROR_SUCCESS:
00547                     valueExists = PR_TRUE;
00548                     break;
00549 
00550                 case ERROR_FILE_NOT_FOUND:
00551                 case ERROR_ACCESS_DENIED:
00552                 default:
00553                     break;
00554             }
00555             RegCloseKey(newkey);
00556             break;
00557 
00558         case ERROR_FILE_NOT_FOUND:
00559         case ERROR_ACCESS_DENIED:
00560         default:
00561             break;
00562     }
00563 #endif
00564 
00565     return valueExists;
00566 }
00567  
00568 PRBool
00569 nsWinReg::NativeIsKeyWritable(const nsString& aSubkey)
00570 {
00571     HKEY     root;
00572     HKEY     newkey;
00573     LONG     result;
00574     nsString subkeyParent = aSubkey;
00575     PRInt32  index;
00576     PRInt32  rv = PR_FALSE;
00577 
00578 #ifdef WIN32
00579     /* In order to check to see if a key is writable (user has write access
00580      * to the key), we need to open the key with KEY_WRITE access.  In order
00581      * to open a key, the key must first exist.  If the key passed does not
00582      * exist, we need to search for one of its parent key that _does_ exist.
00583      * This do{} loop will search for an existing parent key. */
00584     do
00585     {
00586         rv = NativeKeyExists(subkeyParent);
00587         if(!rv)
00588         {
00589             index = subkeyParent.RFindChar('\\', -1, -1);
00590             if(index > 0)
00591                 /* delete everything from the '\\' found to the end of the string */
00592                 subkeyParent.SetLength(index);
00593             else
00594                 /* key does not exist and no parent key found */
00595                 break;
00596         }
00597     }while(!rv);
00598 
00599     if(rv)
00600     {
00601         nsCAutoString subkey;
00602 
00603         if ( NS_FAILED( NS_CopyUnicodeToNative(subkeyParent, subkey) ) )
00604             result = nsInstall::UNEXPECTED_ERROR;
00605         else
00606         {
00607             rv     = PR_FALSE;
00608             root   = (HKEY)mRootKey;
00609             result = RegOpenKeyEx(root, subkey.get(), 0, KEY_WRITE, &newkey);
00610             switch(result)
00611             {
00612                 case ERROR_SUCCESS:
00613                     RegCloseKey(newkey);
00614                     rv = PR_TRUE;
00615                     break;
00616 
00617                 case ERROR_FILE_NOT_FOUND:
00618                 case ERROR_ACCESS_DENIED:
00619                 default:
00620                     break;
00621             }
00622         }
00623     }
00624 #endif
00625     return rv;
00626 }
00627 
00628 PRInt32
00629 nsWinReg::NativeCreateKey(const nsString& aSubkey, const nsString& aClassname)
00630 {
00631     HKEY    root, newkey;
00632     LONG    result;
00633     ULONG   disposition;
00634 
00635 #ifdef WIN32
00636     nsCAutoString subkey;
00637     nsCAutoString classname;
00638 
00639     if (NS_FAILED(NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
00640         NS_FAILED(NS_CopyUnicodeToNative(aClassname, classname) ) )
00641         return nsInstall::UNEXPECTED_ERROR;
00642 
00643     root   = (HKEY)mRootKey;
00644     result = RegCreateKeyEx(root, subkey.get(), 0, NS_CONST_CAST(char*, classname.get()),
00645                 REG_OPTION_NON_VOLATILE, KEY_WRITE, nsnull, &newkey, &disposition);
00646 
00647     if(ERROR_SUCCESS == result)
00648     {
00649         RegCloseKey( newkey );
00650     }
00651 #endif
00652 
00653     return result;
00654 }
00655 
00656 PRInt32
00657 nsWinReg::NativeDeleteKey(const nsString& aSubkey)
00658 {
00659     HKEY  root;
00660     LONG  result;
00661 
00662 #ifdef WIN32
00663     nsCAutoString subkey;
00664 
00665     if (NS_FAILED(NS_CopyUnicodeToNative(aSubkey, subkey) ) )
00666       return nsInstall::UNEXPECTED_ERROR;
00667 
00668     root   = (HKEY) mRootKey;
00669     result = RegDeleteKey( root, subkey.get() );
00670 #endif
00671 
00672     return result;
00673 }
00674   
00675 PRInt32
00676 nsWinReg::NativeDeleteValue(const nsString& aSubkey, const nsString& aValname)
00677 {
00678 #if defined (WIN32) || defined (XP_OS2)
00679     HKEY    root, newkey;
00680     LONG    result;
00681     nsCAutoString subkey;
00682     nsCAutoString valname;
00683 
00684     if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
00685          NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
00686         return nsInstall::UNEXPECTED_ERROR;
00687     root   = (HKEY) mRootKey;
00688     result = RegOpenKeyEx( root, subkey.get(), 0, KEY_WRITE, &newkey);
00689 
00690     if ( ERROR_SUCCESS == result )
00691     {
00692         result = RegDeleteValue( newkey, valname.get() );
00693         RegCloseKey( newkey );
00694     }
00695 
00696     return result;
00697 #else
00698     return ERROR_INVALID_PARAMETER;
00699 #endif
00700 }
00701 
00702 PRInt32
00703 nsWinReg::NativeSetValueString(const nsString& aSubkey, const nsString& aValname, const nsString& aValue)
00704 {
00705     HKEY    root;
00706     HKEY    newkey;
00707     LONG    result;
00708     DWORD   length;
00709 
00710     nsCAutoString subkey;
00711     nsCAutoString valname;
00712     nsCAutoString value;
00713 
00714     if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
00715          NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) ||
00716          NS_FAILED( NS_CopyUnicodeToNative(aValue, value) ) )
00717         return nsInstall::UNEXPECTED_ERROR;
00718 
00719     length = value.Length();
00720 
00721     root   = (HKEY) mRootKey;
00722     result = RegOpenKeyEx( root, subkey.get(), 0, KEY_WRITE, &newkey);
00723 
00724     if(ERROR_SUCCESS == result)
00725     {
00726         result = RegSetValueEx( newkey, valname.get(), 0, REG_SZ, (unsigned char*)value.get(), length );
00727         RegCloseKey( newkey );
00728     }
00729 
00730     return result;
00731 }
00732  
00733 #define STRBUFLEN 255
00734  
00735 PRInt32
00736 nsWinReg::NativeGetValueString(const nsString& aSubkey, const nsString& aValname, nsString* aReturn)
00737 {
00738     unsigned char     valbuf[_MAXKEYVALUE_];
00739     HKEY              root;
00740     HKEY              newkey;
00741     LONG              result;
00742     DWORD             type            = REG_SZ;
00743     DWORD             length          = sizeof(valbuf);
00744     nsCAutoString     subkey;
00745     nsCAutoString     valname;
00746 
00747     if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
00748          NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
00749         return nsInstall::UNEXPECTED_ERROR;
00750 
00751     root   = (HKEY) mRootKey;
00752     result = RegOpenKeyEx( root, subkey.get(), 0, KEY_READ, &newkey );
00753 
00754     if ( ERROR_SUCCESS == result ) {
00755         result = RegQueryValueEx( newkey, valname.get(), nsnull, &type, valbuf, &length );
00756 
00757         RegCloseKey( newkey );
00758 
00759         if( result == ERROR_SUCCESS && type == REG_SZ)
00760         {
00761             // this cast is ok until mozilla is compiled in UNICODE, then this
00762             // will break.
00763             nsAutoString value;
00764             if (NS_SUCCEEDED( NS_CopyNativeToUnicode(nsDependentCString(NS_REINTERPRET_CAST(const char *, valbuf)), value) ) )
00765               aReturn->Assign(value);
00766             else
00767               result = nsInstall::UNEXPECTED_ERROR;
00768         }
00769     }
00770 
00771     if(ERROR_ACCESS_DENIED == result)
00772         result = nsInstall::ACCESS_DENIED;
00773 
00774     return result;
00775 }
00776 
00777 PRInt32
00778 nsWinReg::NativeSetValueNumber(const nsString& aSubkey, const nsString& aValname, PRInt32 aValue)
00779 {
00780     HKEY    root;
00781     HKEY    newkey;
00782     LONG    result;
00783     nsCAutoString subkey;
00784     nsCAutoString valname;
00785 
00786     if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
00787          NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
00788         return nsInstall::UNEXPECTED_ERROR;
00789 
00790     root   = (HKEY) mRootKey;
00791     result = RegOpenKeyEx( root, subkey.get(), 0, KEY_WRITE, &newkey);
00792 
00793     if(ERROR_SUCCESS == result)
00794     {
00795         result = RegSetValueEx( newkey, valname.get(), 0, REG_DWORD, (LPBYTE)&aValue, sizeof(PRInt32));
00796         RegCloseKey( newkey );
00797     }
00798 
00799     return result;
00800 }
00801  
00802 PRInt32
00803 nsWinReg::NativeGetValueNumber(const nsString& aSubkey, const nsString& aValname, PRInt32* aReturn)
00804 
00805 {
00806     PRInt32 valbuf;
00807     PRInt32 valbuflen;
00808     HKEY    root;
00809     HKEY    newkey;
00810     LONG    result;
00811     DWORD   type            = REG_DWORD;
00812     DWORD   length          = _MAXKEYVALUE_;
00813     nsCAutoString subkey;
00814     nsCAutoString valname;
00815 
00816     if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
00817          NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
00818         return nsInstall::UNEXPECTED_ERROR;
00819 
00820     valbuflen = sizeof(PRInt32);
00821     root      = (HKEY) mRootKey;
00822     result    = RegOpenKeyEx( root, subkey.get(), 0, KEY_READ, &newkey );
00823 
00824     if ( ERROR_SUCCESS == result ) {
00825         result = RegQueryValueEx( newkey, valname.get(), nsnull, &type, (LPBYTE)&valbuf, (LPDWORD)&valbuflen);
00826 
00827         RegCloseKey( newkey );
00828 
00829         if(type == REG_DWORD)
00830             *aReturn = valbuf;
00831     }
00832 
00833     if(ERROR_ACCESS_DENIED == result)
00834         return nsInstall::ACCESS_DENIED;
00835     else if (result != ERROR_SUCCESS)
00836         return nsInstall::UNEXPECTED_ERROR;
00837 
00838     return nsInstall::SUCCESS;
00839 }
00840 
00841 PRInt32
00842 nsWinReg::NativeSetValue(const nsString& aSubkey, const nsString& aValname, nsWinRegValue* aValue)
00843 {
00844 #if defined (WIN32) || defined (XP_OS2)
00845     HKEY    root;
00846     HKEY    newkey;
00847     LONG    result;
00848     DWORD   length;
00849     DWORD   type;
00850     unsigned char* data;
00851     nsCAutoString subkey;
00852     nsCAutoString valname;
00853 
00854     if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
00855          NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
00856         return nsnull;
00857 
00858     root   = (HKEY) mRootKey;
00859     result = RegOpenKeyEx( root, subkey.get(), 0, KEY_WRITE, &newkey );
00860 
00861     if(ERROR_SUCCESS == result)
00862     {
00863         type = (DWORD)aValue->type;
00864         data = (unsigned char*)aValue->data;
00865         length = (DWORD)aValue->data_length;
00866 
00867         result = RegSetValueEx( newkey, valname.get(), 0, type, data, length);
00868         RegCloseKey( newkey );
00869     }
00870 
00871     return result;
00872 #else
00873     return ERROR_INVALID_PARAMETER;
00874 #endif
00875 }
00876   
00877 nsWinRegValue*
00878 nsWinReg::NativeGetValue(const nsString& aSubkey, const nsString& aValname)
00879 {
00880 #if defined (WIN32) || defined (XP_OS2)
00881     unsigned char    valbuf[STRBUFLEN];
00882     HKEY    root;
00883     HKEY    newkey;
00884     LONG    result;
00885     DWORD   length=STRBUFLEN;
00886     DWORD   type;
00887     nsString* data;
00888     nsWinRegValue* value = nsnull;
00889     nsCAutoString subkey;
00890     nsCAutoString valname;
00891 
00892     if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
00893          NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
00894         return nsnull;
00895 
00896     root   = (HKEY) mRootKey;
00897     result = RegOpenKeyEx( root, subkey.get(), 0, KEY_READ, &newkey );
00898 
00899     if(ERROR_SUCCESS == result)
00900     {
00901         result = RegQueryValueEx( newkey, valname.get(), nsnull, &type, valbuf, &length );
00902 
00903         if ( ERROR_SUCCESS == result ) {
00904             data = new nsString;
00905             data->AssignWithConversion((char *)valbuf);
00906                            length = data->Length();
00907             value = new nsWinRegValue(type, (void*)data, length);
00908         }
00909 
00910         RegCloseKey( newkey );
00911     }
00912 
00913     return value;
00914 #else
00915     return nsnull;
00916 #endif
00917 }
00918