]> git.sesse.net Git - vlc/blobdiff - src/misc/configuration.c
* src/misc/configuration.c: YAF (yet another fix).
[vlc] / src / misc / configuration.c
index 249032bab89b39c570fcca67336802b98a77913b..e5e0f53278340328d402bf4e58eee30b2ad1df80 100644 (file)
@@ -1,10 +1,10 @@
 /*****************************************************************************
  * configuration.c management of the modules configuration
  *****************************************************************************
- * Copyright (C) 2001 VideoLAN
- * $Id: configuration.c,v 1.71 2003/11/11 21:23:56 hartman Exp $
+ * Copyright (C) 2001-2004 VideoLAN
+ * $Id$
  *
- * Authors: Gildas Bazin <gbazin@netcourrier.com>
+ * Authors: Gildas Bazin <gbazin@videolan.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,9 +27,7 @@
 #include <stdio.h>                                              /* sprintf() */
 #include <stdlib.h>                                      /* free(), strtol() */
 #include <string.h>                                              /* strdup() */
-#ifdef HAVE_ERRNO_H
-#   include <errno.h>                                               /* errno */
-#endif
+#include <errno.h>                                                  /* errno */
 
 #ifdef HAVE_UNISTD_H
 #    include <unistd.h>                                          /* getuid() */
 #if defined( HAVE_SYS_TYPES_H )
 #   include <sys/types.h>
 #endif
-#if defined( WIN32 ) && !defined( UNDER_CE )
-#   include <direct.h>
+#if defined( WIN32 )
+#   if !defined( UNDER_CE )
+#       include <direct.h>
+#   endif
+#include <tchar.h>
 #endif
 
 
@@ -95,6 +96,9 @@ int __config_GetType( vlc_object_t *p_this, const char *psz_name )
         break;
 
     case CONFIG_ITEM_MODULE:
+    case CONFIG_ITEM_MODULE_CAT:
+    case CONFIG_ITEM_MODULE_LIST:
+    case CONFIG_ITEM_MODULE_LIST_CAT:
         i_type = VLC_VAR_MODULE;
         break;
 
@@ -202,12 +206,16 @@ char * __config_GetPsz( vlc_object_t *p_this, const char *psz_name )
     if( (p_config->i_type!=CONFIG_ITEM_STRING) &&
         (p_config->i_type!=CONFIG_ITEM_FILE) &&
         (p_config->i_type!=CONFIG_ITEM_DIRECTORY) &&
+        (p_config->i_type!=CONFIG_ITEM_MODULE_LIST) &&
+        (p_config->i_type!=CONFIG_ITEM_MODULE_LIST_CAT) &&
+        (p_config->i_type!=CONFIG_ITEM_MODULE_CAT) &&
         (p_config->i_type!=CONFIG_ITEM_MODULE) )
     {
         msg_Err( p_this, "option %s does not refer to a string", psz_name );
         return NULL;
     }
 
+
     /* return a copy of the string */
     vlc_mutex_lock( p_config->p_lock );
     if( p_config->psz_value ) psz_value = strdup( p_config->psz_value );
@@ -231,6 +239,7 @@ void __config_PutPsz( vlc_object_t *p_this,
 
     p_config = config_FindConfig( p_this, psz_name );
 
+
     /* sanity checks */
     if( !p_config )
     {
@@ -240,6 +249,9 @@ void __config_PutPsz( vlc_object_t *p_this,
     if( (p_config->i_type!=CONFIG_ITEM_STRING) &&
         (p_config->i_type!=CONFIG_ITEM_FILE) &&
         (p_config->i_type!=CONFIG_ITEM_DIRECTORY) &&
+        (p_config->i_type!=CONFIG_ITEM_MODULE_LIST) &&
+        (p_config->i_type!=CONFIG_ITEM_MODULE_CAT) &&
+        (p_config->i_type!=CONFIG_ITEM_MODULE_LIST_CAT) &&
         (p_config->i_type!=CONFIG_ITEM_MODULE) )
     {
         msg_Err( p_this, "option %s does not refer to a string", psz_name );
@@ -254,6 +266,8 @@ void __config_PutPsz( vlc_object_t *p_this,
     if( psz_value && *psz_value ) p_config->psz_value = strdup( psz_value );
     else p_config->psz_value = NULL;
 
+    p_config->b_dirty = VLC_TRUE;
+
     val.psz_string = p_config->psz_value;
 
     vlc_mutex_unlock( p_config->p_lock );
@@ -317,6 +331,8 @@ void __config_PutInt( vlc_object_t *p_this, const char *psz_name, int i_value )
         p_config->i_value = i_value;
     }
 
+    p_config->b_dirty = VLC_TRUE;
+
     val.i_int = p_config->i_value;
 
     if( p_config->pf_callback )
@@ -373,6 +389,8 @@ void __config_PutFloat( vlc_object_t *p_this,
         p_config->f_value = f_value;
     }
 
+    p_config->b_dirty = VLC_TRUE;
+
     val.f_float = p_config->f_value;
 
     if( p_config->pf_callback )
@@ -499,6 +517,12 @@ void config_Duplicate( module_t *p_module, module_config_t *p_orig )
     {
         p_module->p_config[i] = p_orig[i];
 
+        p_module->p_config[i].i_value_orig = p_orig[i].i_value;
+        p_module->p_config[i].f_value_orig = p_orig[i].f_value;
+        p_module->p_config[i].i_value_saved = p_orig[i].i_value;
+        p_module->p_config[i].f_value_saved = p_orig[i].f_value;
+        p_module->p_config[i].psz_value_saved = 0;
+
         p_module->p_config[i].psz_type = p_orig[i].psz_type ?
                                    strdup( p_orig[i].psz_type ) : NULL;
         p_module->p_config[i].psz_name = p_orig[i].psz_name ?
@@ -524,8 +548,8 @@ void config_Duplicate( module_t *p_module, module_config_t *p_orig )
                 if( p_module->p_config[i].ppsz_list )
                 {
                     for( j = 0; j < p_orig[i].i_list; j++ )
-                        p_module->p_config[i].ppsz_list[j] =
-                            strdup( p_orig[i].ppsz_list[j] );
+                        p_module->p_config[i].ppsz_list[j] = p_orig[i].ppsz_list[j] ?
+                            strdup( p_orig[i].ppsz_list[j] ) : NULL ;
                     p_module->p_config[i].ppsz_list[j] = NULL;
                 }
             }
@@ -536,8 +560,8 @@ void config_Duplicate( module_t *p_module, module_config_t *p_orig )
                 if( p_module->p_config[i].ppsz_list_text )
                 {
                     for( j = 0; j < p_orig[i].i_list; j++ )
-                        p_module->p_config[i].ppsz_list_text[j] =
-                            strdup( _(p_orig[i].ppsz_list_text[j]) );
+                        p_module->p_config[i].ppsz_list_text[j] = _(p_orig[i].ppsz_list_text[j]) ?
+                            strdup( _(p_orig[i].ppsz_list_text[j] ) ) : NULL ;
                     p_module->p_config[i].ppsz_list_text[j] = NULL;
                 }
             }
@@ -554,6 +578,26 @@ void config_Duplicate( module_t *p_module, module_config_t *p_orig )
             }
         }
 
+        /* duplicate the actions list */
+        if( p_orig[i].i_action )
+        {
+            int j;
+
+            p_module->p_config[i].ppf_action =
+                malloc( p_orig[i].i_action * sizeof(void *) );
+            p_module->p_config[i].ppsz_action_text =
+                malloc( p_orig[i].i_action * sizeof(char *) );
+
+            for( j = 0; j < p_orig[i].i_action; j++ )
+            {
+                p_module->p_config[i].ppf_action[j] =
+                    p_orig[i].ppf_action[j];
+                p_module->p_config[i].ppsz_action_text[j] =
+                    p_orig[i].ppsz_action_text[j] ?
+                    strdup( p_orig[i].ppsz_action_text[j] ) : NULL;
+            }
+        }
+
         p_module->p_config[i].pf_callback = p_orig[i].pf_callback;
     }
 }
@@ -593,6 +637,9 @@ void config_Free( module_t *p_module )
         if( p_item->psz_value_orig )
             free( p_item->psz_value_orig );
 
+        if( p_item->psz_value_saved )
+            free( p_item->psz_value_saved );
+
         if( p_item->i_list )
         {
             for( i = 0; i < p_item->i_list; i++ )
@@ -606,6 +653,17 @@ void config_Free( module_t *p_module )
             if( p_item->ppsz_list_text ) free( p_item->ppsz_list_text );
             if( p_item->pi_list ) free( p_item->pi_list );
         }
+
+        if( p_item->i_action )
+        {
+            for( i = 0; i < p_item->i_action; i++ )
+            {
+                if( p_item->ppsz_action_text[i] )
+                    free( p_item->ppsz_action_text[i] );
+            }
+            if( p_item->ppf_action ) free( p_item->ppf_action );
+            if( p_item->ppsz_action_text ) free( p_item->ppsz_action_text );
+        }
     }
 
     free( p_module->p_config );
@@ -816,6 +874,7 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
                         if( !*psz_option_value )
                             break;                    /* ignore empty option */
                         p_item->i_value = strtol( psz_option_value, 0, 0 );
+                        p_item->i_value_saved = p_item->i_value;
 #if 0
                         msg_Dbg( p_this, "option \"%s\", value %i",
                                  p_item->psz_name, p_item->i_value );
@@ -826,7 +885,8 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
                         if( !*psz_option_value )
                             break;                    /* ignore empty option */
                         p_item->f_value = (float)atof( psz_option_value);
-#if O
+                        p_item->f_value_saved = p_item->f_value;
+#if 0
                         msg_Dbg( p_this, "option \"%s\", value %f",
                                  p_item->psz_name, (double)p_item->f_value );
 #endif
@@ -834,7 +894,8 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
                     case CONFIG_ITEM_KEY:
                         if( !*psz_option_value )
                             break;                    /* ignore empty option */
-                        p_item->i_value = ConfigStringToKey( psz_option_value );
+                        p_item->i_value = ConfigStringToKey(psz_option_value);
+                        p_item->i_value_saved = p_item->i_value;
                         break;
 
                     default:
@@ -847,6 +908,15 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
                         p_item->psz_value = *psz_option_value ?
                             strdup( psz_option_value ) : NULL;
 
+                        if( p_item->psz_value_saved )
+                            free( p_item->psz_value_saved );
+                        p_item->psz_value_saved = 0;
+                        if( !p_item->psz_value || !p_item->psz_value_orig ||
+                            (p_item->psz_value && p_item->psz_value_orig &&
+                             strcmp(p_item->psz_value,p_item->psz_value_orig)))
+                            p_item->psz_value_saved = p_item->psz_value ?
+                                strdup( p_item->psz_value ) : 0;
+
                         vlc_mutex_unlock( p_item->p_lock );
 
 #if 0
@@ -872,6 +942,52 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
     return 0;
 }
 
+/*****************************************************************************
+ * config_CreateDir: Create configuration directory if it doesn't exist.
+ *****************************************************************************/
+int config_CreateDir( vlc_object_t *p_this, char *psz_dirname )
+{
+    if( !psz_dirname && !*psz_dirname ) return -1;
+
+#if defined( UNDER_CE )
+    {
+        wchar_t psz_new[ MAX_PATH ];
+        char psz_mod[MAX_PATH];
+        int i = 0;
+
+        /* Convert '/' into '\' */
+        while( *psz_dirname )
+        {
+            if( *psz_dirname == '/' ) psz_mod[i] = '\\';
+            else psz_mod[i] = *psz_dirname;
+            psz_dirname++;
+            i++;
+        }
+        psz_mod[i] = 0;
+
+        MultiByteToWideChar( CP_ACP, 0, psz_mod, -1, psz_new, MAX_PATH );
+        if( CreateDirectory( psz_new, NULL ) )
+        {
+            msg_Err( p_this, "could not create %s", psz_mod );
+        }
+    }
+
+#else
+#   if defined( WIN32 )
+    if( mkdir( psz_dirname ) && errno != EEXIST )
+#   else
+    if( mkdir( psz_dirname, 0755 ) && errno != EEXIST )
+#   endif
+    {
+        msg_Err( p_this, "could not create %s (%s)",
+                 psz_dirname, strerror(errno) );
+    }
+
+#endif
+
+    return 0;
+}
+
 /*****************************************************************************
  * config_SaveConfigFile: Save a module's config options.
  *****************************************************************************
@@ -891,7 +1007,8 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
  * save.
  * Really stupid no ?
  *****************************************************************************/
-int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
+int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
+                    vlc_bool_t b_autosave )
 {
     module_t *p_parser;
     vlc_list_t *p_list;
@@ -930,35 +1047,7 @@ int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
             return -1;
         }
 
-#if defined( UNDER_CE )
-        {
-            wchar_t psz_new[ MAX_PATH ];
-            MultiByteToWideChar( CP_ACP, 0, psz_filename, -1, psz_new,
-                                 MAX_PATH );
-            if( CreateDirectory( psz_new, NULL ) )
-            {
-                msg_Err( p_this, "could not create %s", psz_filename );
-            }
-        }
-
-#elif defined( HAVE_ERRNO_H )
-#   if defined( WIN32 )
-        if( mkdir( psz_filename ) && errno != EEXIST )
-#   else
-        if( mkdir( psz_filename, 0755 ) && errno != EEXIST )
-#   endif
-        {
-            msg_Err( p_this, "could not create %s (%s)",
-                             psz_filename, strerror(errno) );
-        }
-
-#else
-        if( mkdir( psz_filename ) )
-        {
-            msg_Err( p_this, "could not create %s", psz_filename );
-        }
-
-#endif
+        config_CreateDir( p_this, psz_filename );
 
         strcat( psz_filename, "/" CONFIG_FILE );
     }
@@ -1033,8 +1122,10 @@ int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
                 /* we don't have this section in our list so we need to back
                  * it up */
                 *p_index2 = 0;
+#if 0
                 msg_Dbg( p_this, "backing up config for unknown module \"%s\"",
                                  &p_line[1] );
+#endif
                 *p_index2 = ']';
 
                 b_backup = 1;
@@ -1086,8 +1177,9 @@ int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
         if( !p_parser->i_config_items )
             continue;
 
-        msg_Dbg( p_this, "saving config for module \"%s\"",
-                         p_parser->psz_object_name );
+        if( psz_module_name )
+            msg_Dbg( p_this, "saving config for module \"%s\"",
+                     p_parser->psz_object_name );
 
         fprintf( file, "[%s]", p_parser->psz_object_name );
         if( p_parser->psz_longname )
@@ -1099,11 +1191,27 @@ int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
              p_item->i_type != CONFIG_HINT_END;
              p_item++ )
         {
-            char *psz_key;
+            char  *psz_key;
+            int   i_value = p_item->i_value;
+            float f_value = p_item->f_value;
+            char  *psz_value = p_item->psz_value;
+
             if( p_item->i_type & CONFIG_HINT )
                 /* ignore hints */
                 continue;
 
+            if( b_autosave && !p_item->b_autosave )
+            {
+                i_value = p_item->i_value_saved;
+                f_value = p_item->f_value_saved;
+                psz_value = p_item->psz_value_saved;
+                if( !psz_value ) psz_value = p_item->psz_value_orig;
+            }
+            else
+            {
+                p_item->b_dirty = VLC_FALSE;
+            }
+
             switch( p_item->i_type )
             {
             case CONFIG_ITEM_BOOL:
@@ -1112,42 +1220,57 @@ int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
                     fprintf( file, "# %s (%s)\n", p_item->psz_text,
                              (p_item->i_type == CONFIG_ITEM_BOOL) ?
                              _("boolean") : _("integer") );
-                if( p_item->i_value == p_item->i_value_orig )
+                if( i_value == p_item->i_value_orig )
                     fprintf( file, "#" );
-                fprintf( file, "%s=%i\n", p_item->psz_name, p_item->i_value );
+                fprintf( file, "%s=%i\n", p_item->psz_name, i_value );
+
+                p_item->i_value_saved = i_value;
                 break;
+
             case CONFIG_ITEM_KEY:
                 if( p_item->psz_text )
                     fprintf( file, "# %s (%s)\n", p_item->psz_text,
                              _("key") );
-                if( p_item->i_value == p_item->i_value_orig )
+                if( i_value == p_item->i_value_orig )
                     fprintf( file, "#" );
-                psz_key = ConfigKeyToString( p_item->i_value );
+                psz_key = ConfigKeyToString( i_value );
                 fprintf( file, "%s=%s\n", p_item->psz_name,
                          psz_key ? psz_key : "" );
                 if ( psz_key ) free( psz_key );
+
+                p_item->i_value_saved = i_value;
                 break;
-                
+
             case CONFIG_ITEM_FLOAT:
                 if( p_item->psz_text )
                     fprintf( file, "# %s (%s)\n", p_item->psz_text,
                              _("float") );
-                if( p_item->f_value == p_item->f_value_orig )
+                if( f_value == p_item->f_value_orig )
                     fprintf( file, "#" );
-                fprintf( file, "%s=%f\n", p_item->psz_name,
-                         (double)p_item->f_value );
+                fprintf( file, "%s=%f\n", p_item->psz_name, (double)f_value );
+
+                p_item->f_value_saved = f_value;
                 break;
 
             default:
                 if( p_item->psz_text )
                     fprintf( file, "# %s (%s)\n", p_item->psz_text,
                              _("string") );
-                if( (!p_item->psz_value && !p_item->psz_value_orig) ||
-                    (p_item->psz_value && p_item->psz_value_orig &&
-                     !strcmp( p_item->psz_value, p_item->psz_value_orig )) )
+                if( (!psz_value && !p_item->psz_value_orig) ||
+                    (psz_value && p_item->psz_value_orig &&
+                     !strcmp( psz_value, p_item->psz_value_orig )) )
                     fprintf( file, "#" );
                 fprintf( file, "%s=%s\n", p_item->psz_name,
-                         p_item->psz_value ? p_item->psz_value : "" );
+                         psz_value ? psz_value : "" );
+
+                if( b_autosave && !p_item->b_autosave ) break;
+
+                if( p_item->psz_value_saved ) free( p_item->psz_value_saved );
+                p_item->psz_value_saved = 0;
+                if( (psz_value && p_item->psz_value_orig &&
+                     strcmp( psz_value, p_item->psz_value_orig )) ||
+                    !psz_value || !p_item->psz_value_orig)
+                    p_item->psz_value_saved = psz_value ? strdup(psz_value):0;
             }
         }
 
@@ -1169,6 +1292,43 @@ int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
     return 0;
 }
 
+int config_AutoSaveConfigFile( vlc_object_t *p_this )
+{
+    vlc_list_t *p_list;
+    module_t *p_parser;
+    module_config_t *p_item;
+    int i_index, i_count;
+
+    /* Check if there's anything to save */
+    vlc_mutex_lock( &p_this->p_vlc->config_lock );
+    p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
+    i_count = p_list->i_count;
+    for( i_index = 0; i_index < i_count; i_index++ )
+    {
+        p_parser = (module_t *)p_list->p_values[i_index].p_object ;
+
+        if( !p_parser->i_config_items ) continue;
+
+        for( p_item = p_parser->p_config;
+             p_item->i_type != CONFIG_HINT_END;
+             p_item++ )
+        {
+            if( p_item->b_autosave && p_item->b_dirty ) break;
+        }
+        if( p_item->i_type != CONFIG_HINT_END ) break;
+    }
+    vlc_list_release( p_list );
+    vlc_mutex_unlock( &p_this->p_vlc->config_lock );
+
+    if( i_index == i_count ) return VLC_SUCCESS;
+    return SaveConfigFile( p_this, 0, VLC_TRUE );
+}
+
+int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
+{
+    return SaveConfigFile( p_this, psz_module_name, VLC_FALSE );
+}
+
 /*****************************************************************************
  * config_LoadCmdLine: parse command line
  *****************************************************************************
@@ -1386,6 +1546,9 @@ int __config_LoadCmdLine( vlc_object_t *p_this, int *pi_argc, char *ppsz_argv[],
             case CONFIG_ITEM_FILE:
             case CONFIG_ITEM_DIRECTORY:
             case CONFIG_ITEM_MODULE:
+            case CONFIG_ITEM_MODULE_LIST:
+            case CONFIG_ITEM_MODULE_LIST_CAT:
+            case CONFIG_ITEM_MODULE_CAT:
                 config_PutPsz( p_this, psz_name, optarg );
                 break;
             case CONFIG_ITEM_INTEGER:
@@ -1414,6 +1577,9 @@ int __config_LoadCmdLine( vlc_object_t *p_this, int *pi_argc, char *ppsz_argv[],
             case CONFIG_ITEM_FILE:
             case CONFIG_ITEM_DIRECTORY:
             case CONFIG_ITEM_MODULE:
+            case CONFIG_ITEM_MODULE_CAT:
+            case CONFIG_ITEM_MODULE_LIST:
+            case CONFIG_ITEM_MODULE_LIST_CAT:
                 config_PutPsz( p_this, pp_shortopts[i_cmd]->psz_name, optarg );
                 break;
             case CONFIG_ITEM_INTEGER:
@@ -1503,28 +1669,31 @@ char *config_GetHomeDir( void )
     struct passwd *p_pw = NULL;
 #endif
 
-#if defined(WIN32) || defined(UNDER_CE)
+#if defined(WIN32) && !defined(UNDER_CE)
     typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
-                                               LPTSTR );
+                                               LPSTR );
+#ifndef CSIDL_FLAG_CREATE
 #   define CSIDL_FLAG_CREATE 0x8000
+#endif
+#ifndef CSIDL_APPDATA
 #   define CSIDL_APPDATA 0x1A
+#endif
+#ifndef SHGFP_TYPE_CURRENT
 #   define SHGFP_TYPE_CURRENT 0
+#endif
 
     HINSTANCE shfolder_dll;
     SHGETFOLDERPATH SHGetFolderPath ;
 
     /* load the shfolder dll to retrieve SHGetFolderPath */
-    if( ( shfolder_dll = LoadLibrary("shfolder.dll") ) != NULL )
+    if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
     {
         SHGetFolderPath = (void *)GetProcAddress( shfolder_dll,
-                                                  "SHGetFolderPathA" );
+                                                  _T("SHGetFolderPathA") );
         if ( SHGetFolderPath != NULL )
         {
             p_homedir = (char *)malloc( MAX_PATH );
-            if( !p_homedir )
-            {
-                return NULL;
-            }
+            if( !p_homedir ) return NULL;
 
             /* get the "Application Data" folder for the current user */
             if( S_OK == SHGetFolderPath( NULL,
@@ -1536,9 +1705,28 @@ char *config_GetHomeDir( void )
                 return p_homedir;
             }
             free( p_homedir );
+            p_homedir = NULL;
         }
         FreeLibrary( shfolder_dll );
     }
+
+#elif defined(UNDER_CE)
+
+#ifndef CSIDL_APPDATA
+#   define CSIDL_APPDATA 0x1A
+#endif
+
+    wchar_t p_whomedir[MAX_PATH];
+
+    /* get the "Application Data" folder for the current user */
+    if( SHGetSpecialFolderPath( NULL, p_whomedir, CSIDL_APPDATA, 1 ) )
+    {
+        p_homedir = (char *)malloc( MAX_PATH );
+        if( !p_homedir ) return NULL;
+
+        sprintf( p_homedir, "%ls", p_whomedir );
+        return p_homedir;
+    }
 #endif
 
 #if defined(HAVE_GETPWUID)