[ros-diffs] [cfinck] 34343: Remixed our Win32 version of ccache: - Mix in parts of a patch by Brant Young, which itself is based on an old patch by Filip (see http://code.google.com/p/ccache-win32/wiki/WhyNativeWin32Ccache) - Change bInheritHandles for the CreateProcess call in failed() to TRUE, so that the compilation of the RC files works (they are preprocessed with gcc and piped to a file) - Add a safe version of mkstemp based on glibc sources, so that we don't run into race condition problems - Use CSIDL_LOCAL_APPDATA as the default base path for the ccache directory, not CSIDL_PROFILE

cfinck at svn.reactos.org cfinck at svn.reactos.org
Sun Jul 6 22:49:04 CEST 2008


Author: cfinck
Date: Sun Jul  6 15:49:03 2008
New Revision: 34343

URL: http://svn.reactos.org/svn/reactos?rev=34343&view=rev
Log:
Remixed our Win32 version of ccache:
- Mix in parts of a patch by Brant Young, which itself is based on an old patch by Filip (see http://code.google.com/p/ccache-win32/wiki/WhyNativeWin32Ccache)
- Change bInheritHandles for the CreateProcess call in failed() to TRUE, so that the compilation of the RC files works (they are preprocessed with gcc and piped to a file)
- Add a safe version of mkstemp based on glibc sources, so that we don't run into race condition problems
- Use CSIDL_LOCAL_APPDATA as the default base path for the ccache directory, not CSIDL_PROFILE

Added:
    trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/mkstemp.c   (with props)
Modified:
    trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/Makefile
    trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache-win32.vcproj
    trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.c
    trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.h
    trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/execute.c
    trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/unify.c
    trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/util.c

Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/Makefile
URL: http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/Makefile?rev=34343&r1=34342&r2=34343&view=diff
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/Makefile [iso-8859-1] (original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/Makefile [iso-8859-1] Sun Jul  6 15:49:03 2008
@@ -9,7 +9,7 @@
 CC=gcc
 CFLAGS := -Wall -pedantic -D_WIN32_WINNT=0x0500 -D_WIN32_IE=0x0400 -O2
 LFLAGS := -s
-SRCS := args.c ccache.c cleanup.c execute.c getopt.c hash.c mdfour.c snprintf.c stats.c unify.c util.c win32-dirent.c
+SRCS := args.c ccache.c cleanup.c execute.c getopt.c hash.c mdfour.c mkstemp.c snprintf.c stats.c unify.c util.c win32-dirent.c
 OBJS := $(SRCS:.c=.o)
 
 $(TARGET): $(OBJS)

Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache-win32.vcproj
URL: http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache-win32.vcproj?rev=34343&r1=34342&r2=34343&view=diff
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache-win32.vcproj [iso-8859-1] (original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache-win32.vcproj [iso-8859-1] Sun Jul  6 15:49:03 2008
@@ -112,7 +112,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
 				RuntimeLibrary="2"
 				UsePrecompiledHeader="0"
 				WarningLevel="4"
@@ -197,6 +197,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\mkstemp.c"
+				>
+			</File>
+			<File
 				RelativePath=".\snprintf.c"
 				>
 			</File>

Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.c
URL: http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.c?rev=34343&r1=34342&r2=34343&view=diff
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.c [iso-8859-1] (original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.c [iso-8859-1] Sun Jul  6 15:49:03 2008
@@ -165,7 +165,7 @@
 
 	si.cb = sizeof(STARTUPINFOA);
 
-	if(!CreateProcessA(orig_args->argv[0], merged, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
+	if(!CreateProcessA(orig_args->argv[0], merged, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
 	{
 		perror(orig_args->argv[0]);
 		exit(1);

Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.h
URL: http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.h?rev=34343&r1=34342&r2=34343&view=diff
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.h [iso-8859-1] (original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/ccache.h [iso-8859-1] Sun Jul  6 15:49:03 2008
@@ -42,8 +42,7 @@
  #define mkdir(dirname, access) _mkdir(dirname)
  #define x_realpath(a) strdup(a)
  #define link(filename, linkname) CreateHardLinkA(linkname, filename, NULL)
- #define PROT_READ 0x0001
- #define MAP_PRIVATE 0x02
+ #define lstat(x, y) stat(x, y)
 
  #ifdef _MSC_VER
   typedef unsigned int mode_t;
@@ -55,7 +54,8 @@
  #ifndef S_ISDIR
   #define S_ISDIR(m) (((m) & _S_IFDIR) == _S_IFDIR)
  #endif
- #define lstat(x, y) stat(x, y)
+
+ int mkstemp (char *template);
 #else
  #include <unistd.h>
  #include <sys/wait.h>

Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/execute.c
URL: http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/execute.c?rev=34343&r1=34342&r2=34343&view=diff
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/execute.c [iso-8859-1] (original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/execute.c [iso-8859-1] Sun Jul  6 15:49:03 2008
@@ -18,16 +18,90 @@
 
 #include "ccache.h"
 
+#ifdef _WIN32
+static char *argvtos(char **argv)
+{
+       int i, len;
+       char *ptr, *str;
+
+       for (i = 0, len = 0; argv[i]; i++) {
+               len += strlen(argv[i]) + 3;
+       }
+
+       str = ptr = (char *)malloc(len + 1);
+       if (str == NULL)
+               return NULL;
+
+       for (i = 0; argv[i]; i++) {
+               len = strlen(argv[i]);
+               *ptr++ = '"';
+               memcpy(ptr, argv[i], len);
+               ptr += len;
+               *ptr++ = '"';
+               *ptr++ = ' ';
+       }
+       *ptr = 0;
+
+       return str;
+}
+#endif
 
 /*
   execute a compiler backend, capturing all output to the given paths
   the full path to the compiler to run is in argv[0]
 */
-int execute(char **argv, 
+int execute(char **argv,
 	    const char *path_stdout,
 	    const char *path_stderr)
 {
-#ifndef _WIN32
+#ifdef _WIN32
+    PROCESS_INFORMATION pinfo;
+    STARTUPINFOA sinfo;
+    BOOL ret;
+    DWORD exitcode;
+    char *args;
+    HANDLE fd_out, fd_err;
+    SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
+
+    fd_out = CreateFileA(path_stdout, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (fd_out == INVALID_HANDLE_VALUE) {
+           return STATUS_NOCACHE;
+    }
+
+    fd_err = CreateFileA(path_stderr, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS,
+                        FILE_ATTRIBUTE_NORMAL, NULL);
+    if (fd_err == INVALID_HANDLE_VALUE) {
+           return STATUS_NOCACHE;
+    }
+
+    ZeroMemory(&pinfo, sizeof(PROCESS_INFORMATION));
+    ZeroMemory(&sinfo, sizeof(STARTUPINFOA));
+
+    sinfo.cb = sizeof(STARTUPINFOA);
+    sinfo.hStdError = fd_err;
+    sinfo.hStdOutput = fd_out;
+    sinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+    sinfo.dwFlags |= STARTF_USESTDHANDLES;
+
+    args = argvtos(argv);
+
+    ret = CreateProcessA(argv[0], args, NULL, NULL, TRUE, 0, NULL, NULL,
+                        &sinfo, &pinfo);
+
+    free(args);
+    CloseHandle(fd_out);
+    CloseHandle(fd_err);
+
+    if (ret == 0)
+           return -1;
+
+    WaitForSingleObject(pinfo.hProcess, INFINITE);
+    GetExitCodeProcess(pinfo.hProcess, &exitcode);
+    CloseHandle(pinfo.hProcess);
+    CloseHandle(pinfo.hThread);
+
+    return exitcode;
+#else
 	pid_t pid;
 	int status;
 
@@ -65,46 +139,6 @@
 	}
 
 	return WEXITSTATUS(status);
-#else /* Should be portable */
-    int   status = -2;
-    int   fd, std_od = -1, std_ed = -1;
-
-    unlink(path_stdout);
-    std_od = _dup(1);
-    fd = _open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
-    if (fd == -1) {
-        status = STATUS_NOCACHE;
-        cc_log("stdout error: failed to open %s\n", path_stdout);
-        goto out;
-    }
-    /*std_od = */ _dup2(fd, 1);
-    _close(fd);
-
-    unlink(path_stderr);
-    fd = _open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
-    std_ed = _dup(2); 
-    if (fd == -1) {
-        status = STATUS_NOCACHE;
-        cc_log("stderr error: failed to open %s\n", path_stderr);
-        goto out;
-    }
-    /*std_ed =*/ _dup2(fd, 2);
-    _close(fd);
-
-    /* Spawn process (_exec* familly doesn't return) */
-    status = _spawnv(_P_WAIT, argv[0], (const char* const*)argv);
-
- out:
-    cc_log("%s:\n  stdout -> %s\n  stderr -> %s\n  process status=%i\n",
-           argv[0], path_stdout, path_stderr, status);
-    if (status == -1) cc_log("Error %i: %s\n", errno, strerror(errno));
-
-    /* Restore descriptors */
-    if (std_od != -1) _dup2(std_od, 1);
-    if (std_ed != -1) _dup2(std_ed, 2); 
-    _flushall();
-
-    return (status>0);
 #endif
 }
 
@@ -158,11 +192,24 @@
 */
 char *find_executable(const char *name, const char *exclude_name)
 {
+#ifdef _WIN32
+    DWORD ret;
+    char namebuf[MAX_PATH];
+
+    UNREFERENCED_PARAMETER(exclude_name);
+
+    ret = SearchPathA(getenv("CCACHE_PATH"), name, ".exe", sizeof(namebuf), namebuf, NULL);
+    if (ret != 0) {
+           return x_strdup(namebuf);
+    }
+
+    return NULL;
+#else
 	char *path;
 	char *tok;
-	const char *sep = ":";
-
-	if (*name == PATH_SEP_CHAR) {
+	struct stat st1, st2;
+
+	if (*name == '/') {
 		return x_strdup(name);
 	}
 
@@ -177,37 +224,40 @@
 
 	path = x_strdup(path);
 	
-	/* Determine path separator */
-    if (strchr(path, ';')) sep = ";";
-
 	/* search the path looking for the first compiler of the right name
 	   that isn't us */
-	for (tok=strtok(path, sep); tok; tok = strtok(NULL, sep)) {
+	for (tok=strtok(path,":"); tok; tok = strtok(NULL, ":")) {
 		char *fname;
-		x_asprintf(&fname, "%s"PATH_SEP"%s", tok, name);
+		x_asprintf(&fname, "%s/%s", tok, name);
 		/* look for a normal executable file */
-		
-
-		if (is_exec_file(fname, exclude_name) > 0)
-        {
+		if (access(fname, X_OK) == 0 &&
+		    lstat(fname, &st1) == 0 &&
+		    stat(fname, &st2) == 0 &&
+		    S_ISREG(st2.st_mode)) {
+			/* if its a symlink then ensure it doesn't
+                           point at something called exclude_name */
+			if (S_ISLNK(st1.st_mode)) {
+				char *buf = x_realpath(fname);
+				if (buf) {
+					char *p = str_basename(buf);
+					if (strcmp(p, exclude_name) == 0) {
+						/* its a link to "ccache" ! */
+						free(p);
+						free(buf);
+						continue;
+					}
+					free(buf);
+					free(p);
+				}
+			}
+
+			/* found it! */
 			free(path);
 			return fname;
 		}
 		free(fname);
-
-			/* found it! */
-#ifdef _WIN32 /* Add .exe under win32 */
-		x_asprintf(&fname, "%s"PATH_SEP"%s.exe", tok, name);
-
-		/* look for a normal executable file */
-        if (is_exec_file(fname, exclude_name) > 0)
-        {
-			free(path);
-			return fname;
-		}
-		free(fname);
-#endif
-	}
-free(path);
+	}
+
 	return NULL;
-}
+#endif
+}

Added: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/mkstemp.c
URL: http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/mkstemp.c?rev=34343&view=auto
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/mkstemp.c (added)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/mkstemp.c [iso-8859-1] Sun Jul  6 15:49:03 2008
@@ -1,0 +1,84 @@
+#ifdef _WIN32
+/* Copyright (C) 1998, 1999, 2001, 2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Ported for ccache-win32 by Colin Finck <colin at reactos.org>
+   Source: http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/posix/tempname.c?rev=1.39&cvsroot=glibc
+*/
+
+#include "ccache.h"
+
+/* These are the characters used in temporary filenames.  */
+static const char letters[] =
+"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+/* Generate a unique temporary file name from TEMPLATE.
+   The last six characters of TEMPLATE must be "XXXXXX";
+   they are replaced with a string that makes the filename unique.
+   Then open the file and return a fd. */
+int
+mkstemp (char *template)
+{
+    char *XXXXXX;
+    time_t value;
+    unsigned int count;
+    int fd;
+
+    /* A lower bound on the number of temporary files to attempt to
+     generate.  The maximum total number of temporary file names that
+     can exist for a given template is 62**6.  It should never be
+     necessary to try all these combinations.  Instead if a reasonable
+     number of names is tried (we define reasonable as 62**3) fail to
+     give the system administrator the chance to remove the problems.  */
+    unsigned int attempts = (62 * 62 * 62);
+
+    /* This is where the Xs start.  */
+    XXXXXX = &template[ strlen(template) - 6 ];
+
+    /* Get some more or less random data.  */
+    value = time(NULL) ^ _getpid();
+
+    for (count = 0; count < attempts; value += 7777, ++count)
+    {
+        time_t v = value;
+
+        /* Fill in the random bits.  */
+        XXXXXX[0] = letters[v % 62];
+        v /= 62;
+        XXXXXX[1] = letters[v % 62];
+        v /= 62;
+        XXXXXX[2] = letters[v % 62];
+        v /= 62;
+        XXXXXX[3] = letters[v % 62];
+        v /= 62;
+        XXXXXX[4] = letters[v % 62];
+        v /= 62;
+        XXXXXX[5] = letters[v % 62];
+
+        fd = _open (template, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0600);
+
+        if (fd >= 0)
+            return fd;
+        else if (errno != EEXIST)
+            return -1;
+    }
+
+    /* We got out of the loop because we ran out of combinations to try.  */
+    return -1;
+}
+#endif

Propchange: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/mkstemp.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/unify.c
URL: http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/unify.c?rev=34343&r1=34342&r2=34343&view=diff
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/unify.c [iso-8859-1] (original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/unify.c [iso-8859-1] Sun Jul  6 15:49:03 2008
@@ -238,10 +238,40 @@
 */
 int unify_hash(const char *fname)
 {
+#ifdef _WIN32
+    HANDLE file;
+    HANDLE section;
+    MEMORY_BASIC_INFORMATION minfo;
+    char *map;
+
+    file = CreateFileA(fname, GENERIC_READ, FILE_SHARE_READ, NULL,
+                      OPEN_EXISTING, 0, NULL);
+    if (file == INVALID_HANDLE_VALUE)
+           return -1;
+
+    section = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL);
+    CloseHandle(file);
+    if (section == NULL)
+           return -1;
+
+    map = MapViewOfFile(section, FILE_MAP_READ, 0, 0, 0);
+    CloseHandle(section);
+    if (map == NULL)
+           return -1;
+
+    if (VirtualQuery(map, &minfo, sizeof(minfo)) != sizeof(minfo)) {
+           UnmapViewOfFile(map);
+           return -1;
+    }
+
+    /* pass it through the unifier */
+    unify((unsigned char *)map, minfo.RegionSize);
+
+    UnmapViewOfFile(map);
+#else
 	int fd;
 	struct stat st;	
 	char *map;
-	HANDLE view;
 
 	fd = open(fname, O_RDONLY|O_BINARY);
 	if (fd == -1 || fstat(fd, &st) != 0) {
@@ -250,33 +280,6 @@
 		return -1;
 	}
 
-#ifdef _WIN32
-    /* win32 equivalent of mmap is ViewMapOfFile, but malloc+read
-       may be better */
-    view = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL,
-                                    PAGE_READONLY|SEC_COMMIT, 0,0 , NULL);
-    if (NULL == view) {
-        cc_log("Failed to create file mapping %s: %s\n",
-               fname, strerror(errno));
-		stats_update(STATS_PREPROCESSOR);
-		return -1;
-	}
-
-	map = MapViewOfFile(view, FILE_MAP_READ, 0, 0, st.st_size);
-    if (NULL == map) {
-        cc_log("Failed to map view of file %s: %s\n",
-               fname, strerror(errno));
-		stats_update(STATS_PREPROCESSOR);
-		return -1;
-	}
-
-	/* pass it through the unifier */
-	unify((unsigned char *)map, st.st_size);
-
-    UnmapViewOfFile(map);
-    CloseHandle(view);
-    close(fd);
-#else
 	/* we use mmap() to make it easy to handle arbitrarily long
            lines in preprocessor output. I have seen lines of over
            100k in length, so this is well worth it */
@@ -292,6 +295,7 @@
 
 	munmap(map, st.st_size);
 #endif
+
 	return 0;
 }
 

Modified: trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/util.c
URL: http://svn.reactos.org/svn/reactos/trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/util.c?rev=34343&r1=34342&r2=34343&view=diff
==============================================================================
--- trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/util.c [iso-8859-1] (original)
+++ trunk/tools/RosBE/RosBE-Windows/Tools/ccache-2.4/util.c [iso-8859-1] Sun Jul  6 15:49:03 2008
@@ -20,19 +20,6 @@
 
 static FILE *logfile;
 
-#ifdef _WIN32
-#define fchmod(a, b)
-#endif
-
-#ifndef HAVE_MKSTEMP
-/* cheap and nasty mkstemp replacement */
-int mkstemp(char *template)
-{
-	_mktemp(template);
-	return open(template, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0600);
-}
-#endif
-
 /* log a message to the CCACHE_LOGFILE location */
 void cc_log(const char *format, ...)
 {
@@ -79,7 +66,10 @@
 	char buf[10240];
 	int n;
 	char *tmp_name;
+
+#ifndef _WIN32
 	mode_t mask;
+#endif
 
 	x_asprintf(&tmp_name, "%s.XXXXXX", dest);
 
@@ -109,9 +99,11 @@
 	close(fd1);
 
 	/* get perms right on the tmp file */
+#ifndef _WIN32
 	mask = umask(0);
 	fchmod(fd2, 0666 & ~mask);
 	umask(mask);
+#endif
 
 	/* the close can fail on NFS if out of space */
 	if (close(fd2) == -1) {
@@ -483,8 +475,8 @@
 #ifdef _WIN32
     static char szPath[MAX_PATH];
 
-    /* "Documents and Settings\user\Application Data" is CSIDL_APPDATA */
-    if(SHGetSpecialFolderPathA(NULL, szPath, CSIDL_PROFILE, FALSE))
+    /* "Documents and Settings\user\Application Data" is CSIDL_LOCAL_APPDATA */
+    if(SHGetSpecialFolderPathA(NULL, szPath, CSIDL_LOCAL_APPDATA, FALSE))
     {
         return szPath;
     }



More information about the Ros-diffs mailing list