5 * (Originally part of the Wiretap Library, now part of the Wireshark
7 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 /* file wrapper functions to prevent the file functions from GLib like g_open(),
26 * as code compiled with MSVC 7 and above will collide with libs linked with msvcrt.dll (MSVC 6), lib GLib is
28 * DO NOT USE THESE FUNCTIONS DIRECTLY, USE ws_open() AND ALIKE FUNCTIONS FROM file_util.h INSTEAD!!!
30 * the following code is stripped down code copied from the GLib file glib/gstdio.h
31 * stipped down, because this is used on _WIN32 only and we use only wide char functions */
34 #error "This is only for Windows"
47 /*#include <direct.h>*/
51 #include "file_util.h"
53 static gchar *program_path = NULL;
54 static gchar *system_path = NULL;
58 * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
59 * @flags: as in open()
62 * A wrapper for the POSIX open() function. The open() function is
63 * used to convert a pathname into a file descriptor. Note that on
64 * POSIX systems file descriptors are implemented by the operating
65 * system. On Windows, it's the C library that implements open() and
66 * file descriptors. The actual Windows API for opening files is
67 * something different.
69 * See the C library manual for more details about open().
71 * Returns: a new file descriptor, or -1 if an error occurred. The
72 * return value can be used exactly like the return value from open().
77 ws_stdio_open (const gchar *filename,
81 wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
85 if (wfilename == NULL)
91 retval = _wopen (wfilename, flags, mode);
103 * @oldfilename: a pathname in the GLib file name encoding (UTF-8 on Windows)
104 * @newfilename: a pathname in the GLib file name encoding
106 * A wrapper for the POSIX rename() function. The rename() function
107 * renames a file, moving it between directories if required.
109 * See your C library manual for more details about how rename() works
110 * on your system. Note in particular that on Win9x it is not possible
111 * to rename a file if a file with the new name already exists. Also
112 * it is not possible in general on Windows to rename an open file.
114 * Returns: 0 if the renaming succeeded, -1 if an error occurred
119 ws_stdio_rename (const gchar *oldfilename,
120 const gchar *newfilename)
122 wchar_t *woldfilename = g_utf8_to_utf16 (oldfilename, -1, NULL, NULL, NULL);
123 wchar_t *wnewfilename;
127 if (woldfilename == NULL)
133 wnewfilename = g_utf8_to_utf16 (newfilename, -1, NULL, NULL, NULL);
135 if (wnewfilename == NULL)
137 g_free (woldfilename);
142 if (MoveFileExW (woldfilename, wnewfilename, MOVEFILE_REPLACE_EXISTING))
147 switch (GetLastError ())
149 #define CASE(a,b) case ERROR_##a: save_errno = b; break
150 CASE (FILE_NOT_FOUND, ENOENT);
151 CASE (PATH_NOT_FOUND, ENOENT);
152 CASE (ACCESS_DENIED, EACCES);
153 CASE (NOT_SAME_DEVICE, EXDEV);
154 CASE (LOCK_VIOLATION, EACCES);
155 CASE (SHARING_VIOLATION, EACCES);
156 CASE (FILE_EXISTS, EEXIST);
157 CASE (ALREADY_EXISTS, EEXIST);
159 default: save_errno = EIO;
163 g_free (woldfilename);
164 g_free (wnewfilename);
172 * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
173 * @mode: permissions to use for the newly created directory
175 * A wrapper for the POSIX mkdir() function. The mkdir() function
176 * attempts to create a directory with the given name and permissions.
178 * See the C library manual for more details about mkdir().
180 * Returns: 0 if the directory was successfully created, -1 if an error
186 ws_stdio_mkdir (const gchar *filename,
189 wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
193 if (wfilename == NULL)
199 retval = _wmkdir (wfilename);
210 * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
211 * @buf: a pointer to a <structname>stat</structname> struct, which
212 * will be filled with the file information
214 * A wrapper for the POSIX stat() function. The stat() function
215 * returns information about a file.
217 * See the C library manual for more details about stat().
219 * Returns: 0 if the information was successfully retrieved, -1 if an error
225 ws_stdio_stat64 (const gchar *filename,
228 wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
233 if (wfilename == NULL)
239 len = wcslen (wfilename);
240 while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1]))
243 (!g_path_is_absolute (filename) || len > (size_t) (g_path_skip_root (filename) - filename)))
244 wfilename[len] = '\0';
246 retval = _wstati64 (wfilename, buf);
256 * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
258 * A wrapper for the POSIX unlink() function. The unlink() function
259 * deletes a name from the filesystem. If this was the last link to the
260 * file and no processes have it opened, the diskspace occupied by the
263 * See your C library manual for more details about unlink(). Note
264 * that on Windows, it is in general not possible to delete files that
265 * are open to some process, or mapped into memory.
267 * Returns: 0 if the name was successfully deleted, -1 if an error
274 ws_stdio_unlink (const gchar *filename)
276 wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
280 if (wfilename == NULL)
286 retval = _wunlink (wfilename);
297 * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
299 * A wrapper for the POSIX remove() function. The remove() function
300 * deletes a name from the filesystem.
302 * See your C library manual for more details about how remove() works
303 * on your system. On Unix, remove() removes also directories, as it
304 * calls unlink() for files and rmdir() for directories. On Windows,
305 * although remove() in the C library only works for files, this
306 * function tries first remove() and then if that fails rmdir(), and
307 * thus works for both files and directories. Note however, that on
308 * Windows, it is in general not possible to remove a file that is
309 * open to some process, or mapped into memory.
311 * If this function fails on Windows you can't infer too much from the
312 * errno value. rmdir() is tried regardless of what caused remove() to
313 * fail. Any errno value set by remove() will be overwritten by that
316 * Returns: 0 if the file was successfully removed, -1 if an error
322 ws_stdio_remove (const gchar *filename)
324 wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
328 if (wfilename == NULL)
334 retval = _wremove (wfilename);
336 retval = _wrmdir (wfilename);
347 * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
348 * @mode: a string describing the mode in which the file should be
351 * A wrapper for the POSIX fopen() function. The fopen() function opens
352 * a file and associates a new stream with it.
354 * See the C library manual for more details about fopen().
356 * Returns: A <type>FILE</type> pointer if the file was successfully
357 * opened, or %NULL if an error occurred
362 ws_stdio_fopen (const gchar *filename,
365 wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
370 if (wfilename == NULL)
376 wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
385 retval = _wfopen (wfilename, wmode);
397 * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
398 * @mode: a string describing the mode in which the file should be
400 * @stream: an existing stream which will be reused, or %NULL
402 * A wrapper for the POSIX freopen() function. The freopen() function
403 * opens a file and associates it with an existing stream.
405 * See the C library manual for more details about freopen().
407 * Returns: A <type>FILE</type> pointer if the file was successfully
408 * opened, or %NULL if an error occurred.
413 ws_stdio_freopen (const gchar *filename,
417 wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
422 if (wfilename == NULL)
428 wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
437 retval = _wfreopen (wfilename, wmode, stream);
450 init_dll_load_paths()
452 TCHAR path_w[MAX_PATH];
454 if (program_path && system_path)
457 /* XXX - Duplicate code in filesystem.c:init_progfile_dir */
458 if (GetModuleFileName(NULL, path_w, MAX_PATH) == 0 || GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
464 app_path = g_utf16_to_utf8(path_w, -1, NULL, NULL, NULL);
465 /* We could use PathRemoveFileSpec here but we'd have to link to Shlwapi.dll */
466 program_path = g_path_get_dirname(app_path);
470 if (GetSystemDirectory(path_w, MAX_PATH) == 0) {
475 system_path = g_utf16_to_utf8(path_w, -1, NULL, NULL, NULL);
478 if (program_path && system_path)
485 ws_init_dll_search_path()
487 gboolean dll_dir_set = FALSE;
488 wchar_t *program_path_w;
490 typedef BOOL (*SetDllDirectoryHandler)(LPCTSTR);
491 SetDllDirectoryHandler PSetDllDirectory;
493 if (PSetDllDirectory = (SetDllDirectoryHandler) GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "SetDllDirectoryW")) {
494 dll_dir_set = PSetDllDirectory(_T(""));
497 if (!dll_dir_set && init_dll_load_paths()) {
498 program_path_w = g_utf8_to_utf16(program_path, -1, NULL, NULL, NULL);
499 SetCurrentDirectory(program_path_w);
500 g_free(program_path_w);
507 * Internally g_module_open uses LoadLibrary on Windows and returns an
508 * HMODULE cast to a GModule *. However there's no guarantee that this
509 * will always be the case, so we call LoadLibrary and g_module_open
514 ws_load_library(gchar *library_name)
517 wchar_t *full_path_w;
520 if (!init_dll_load_paths() || !library_name)
523 /* First try the program directory */
524 full_path = g_module_build_path(program_path, library_name);
525 full_path_w = g_utf8_to_utf16(full_path, -1, NULL, NULL, NULL);
527 if (full_path && full_path_w) {
528 dll_h = LoadLibraryW(full_path_w);
536 /* Next try the system directory */
537 full_path = g_module_build_path(system_path, library_name);
538 full_path_w = g_utf8_to_utf16(full_path, -1, NULL, NULL, NULL);
540 if (full_path && full_path_w) {
541 dll_h = LoadLibraryW(full_path_w);
553 ws_module_open(gchar *module_name, GModuleFlags flags)
558 if (!init_dll_load_paths() || !module_name)
561 /* First try the program directory */
562 full_path = g_module_build_path(program_path, module_name);
565 mod = g_module_open(full_path, flags);
572 /* Next try the system directory */
573 full_path = g_module_build_path(system_path, module_name);
576 mod = g_module_open(full_path, flags);
586 /* utf8 version of getenv, needed to get win32 filename paths */
588 getenv_utf8(const char *varname)
594 envvar = getenv(varname);
596 /* since GLib 2.6 we need an utf8 version of the filename */
597 /* using the wide char version of getenv should work under all circumstances */
599 /* convert given varname to utf16, needed by _wgetenv */
600 varnamew = g_utf8_to_utf16(varname, -1, NULL, NULL, NULL);
601 if (varnamew == NULL) {
605 /* use wide char version of getenv */
606 envvarw = _wgetenv(varnamew);
608 if (envvarw == NULL) {
612 /* convert value to utf8 */
613 envvar = g_utf16_to_utf8(envvarw, -1, NULL, NULL, NULL);