Main Page | File List | Globals

src/path.c

Go to the documentation of this file.
00001 /*
00002      This file is part of PlibC.
00003      (C) 2005 Nils Durner (and other contributing authors)
00004 
00005            This library is free software; you can redistribute it and/or
00006            modify it under the terms of the GNU Lesser General Public
00007            License as published by the Free Software Foundation; either
00008            version 2.1 of the License, or (at your option) any later version.
00009         
00010            This library is distributed in the hope that it will be useful,
00011            but WITHOUT ANY WARRANTY; without even the implied warranty of
00012            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013            Lesser General Public License for more details.
00014         
00015            You should have received a copy of the GNU Lesser General Public
00016            License along with this library; if not, write to the Free Software
00017            Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 */
00019 
00025 #include "plibc_private.h"
00026 
00027 extern char szRootDir[_MAX_PATH + 1];
00028 extern long lRootDirLen;
00029 extern char szHomeDir[_MAX_PATH + 2];
00030 extern long lHomeDirLen;
00031 extern char szUser[261];
00032 extern char *_pszOrg;
00033 extern char *_pszApp;
00034 
00035 
00041 long _plibc_DetermineRootDir()
00042 {
00043   char szModule[_MAX_PATH], szDrv[_MAX_DRIVE], szDir[_MAX_DIR];
00044   char *pszBin;
00045   long lDirLen;
00046 
00047   /* Get the path of the calling module.
00048      It should be located in one of the "bin" directories */
00049   GetModuleFileName(NULL, szModule, MAX_PATH);
00050   _splitpath(szModule, szDrv, szDir, NULL, NULL);
00051 
00052         lDirLen = strlen(szDir);
00053         pszBin = szDir + lDirLen - 5;
00054         if (lDirLen < 5 || strnicmp(pszBin, "\\bin\\", 5) != 0)
00055   {
00056         char szRegPath[251];
00057         
00058     /* Get the installation path from the registry */
00059     lDirLen = _MAX_PATH - 1;
00060     _win_snprintf(szRegPath, 250, "Software\\%s\\%s", _pszOrg, _pszApp);
00061     szRegPath[250] = 0;
00062 
00063     if(QueryRegistry
00064        (HKEY_CURRENT_USER, szRegPath, "InstallDir",
00065         szRootDir, &lDirLen) != ERROR_SUCCESS)
00066     {
00067       lDirLen = _MAX_PATH - 1;
00068 
00069       if(QueryRegistry
00070          (HKEY_LOCAL_MACHINE, szRegPath, "InstallDir",
00071           szRootDir, &lDirLen) != ERROR_SUCCESS)
00072       {
00073         return ERROR_BAD_ENVIRONMENT;
00074       }
00075     }
00076     strcat(szRootDir, "\\");
00077     lRootDirLen = lDirLen;
00078     szDrv[0] = 0;
00079   }
00080   else
00081   {
00082         pszBin[1] = 0;
00083         lDirLen -= 4;
00084   }
00085 
00086   if(szDrv[0])
00087   {
00088     strcpy(szRootDir, szDrv);
00089     lRootDirLen = 3 + lDirLen - 1;      /* 3 = strlen(szDir) */
00090     if(lRootDirLen > _MAX_PATH)
00091       return ERROR_BUFFER_OVERFLOW;
00092 
00093     strcat(szRootDir, szDir);
00094   }
00095 
00096   return ERROR_SUCCESS;
00097 }
00098 
00104 long _plibc_DetermineHomeDir()
00105 {
00106   char *lpszProfile = getenv("USERPROFILE");
00107   if(lpszProfile != NULL && lpszProfile[0] != 0)        /* Windows NT */
00108   {
00109     lHomeDirLen = strlen(lpszProfile);
00110     if(lHomeDirLen + 1 > _MAX_PATH)
00111       return ERROR_BUFFER_OVERFLOW;
00112 
00113     strcpy(szHomeDir, lpszProfile);
00114     if(szHomeDir[lHomeDirLen - 1] != '\\')
00115     {
00116       szHomeDir[lHomeDirLen] = '\\';
00117       szHomeDir[++lHomeDirLen] = 0;
00118     }
00119   }
00120   else
00121   {
00122     /* C:\My Documents */
00123     long lRet;
00124 
00125     lHomeDirLen = _MAX_PATH;
00126     lRet = QueryRegistry(HKEY_CURRENT_USER,
00127                          "Software\\Microsoft\\Windows\\CurrentVersion\\"
00128                          "Explorer\\Shell Folders",
00129                          "Personal", szHomeDir, &lHomeDirLen);
00130 
00131     if(lRet == ERROR_BUFFER_OVERFLOW)
00132       return ERROR_BUFFER_OVERFLOW;
00133     else if(lRet == ERROR_SUCCESS)
00134     {
00135       /* lHomeDirLen includes \0 */
00136       if (lHomeDirLen <= _MAX_PATH)
00137         strcat(szHomeDir, "\\");
00138       else
00139         return ERROR_BUFFER_OVERFLOW;
00140     }
00141     else
00142     {
00143       /* C:\Program Files\GNUnet\home\... */
00144       /* 5 = strlen("home\\") */
00145       lHomeDirLen = strlen(szRootDir) + strlen(szUser) + 5 + 1;
00146 
00147       if(_MAX_PATH < lHomeDirLen)
00148         return ERROR_BUFFER_OVERFLOW;
00149 
00150       strcpy(szHomeDir, szRootDir);
00151       strcat(szHomeDir, "home\\");
00152       strcat(szHomeDir, szUser);
00153       strcat(szHomeDir, "\\");
00154     }
00155   }
00156 
00157   return ERROR_SUCCESS;
00158 }
00159 
00166 int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows)
00167 {
00168         return plibc_conv_to_win_path_ex(pszUnix, pszWindows, 1);
00169 }
00170 
00178 int plibc_conv_to_win_path_ex(const char *pszUnix, char *pszWindows, int derefLinks)
00179 {
00180   char *pSrc, *pDest;
00181   long iSpaceUsed;
00182   int iUnixLen;
00183 
00184   iUnixLen = strlen(pszUnix);
00185 
00186   /* Check if we already have a windows path */
00187   if((strchr(pszUnix, '\\') != NULL) || (strchr(pszUnix, ':') != NULL))
00188   {
00189     if(iUnixLen > MAX_PATH)
00190       return ERROR_BUFFER_OVERFLOW;
00191     strcpy(pszWindows, pszUnix);
00192   }
00193 
00194   /* Is the unix path a full path? */
00195   if(pszUnix[0] == '/')
00196   {
00197     strcpy(pszWindows, szRootDir);
00198     iSpaceUsed = lRootDirLen;
00199     pDest = pszWindows + lRootDirLen;
00200     pSrc = (char *) pszUnix + 1;
00201   }
00202   /* Temp. dir? */
00203   else if(strncmp(pszUnix, "/tmp/", 5) == 0)
00204   {
00205     iSpaceUsed = GetTempPath(_MAX_PATH, pszWindows);
00206     if (iSpaceUsed > _MAX_PATH)
00207       return ERROR_BUFFER_OVERFLOW;
00208     pDest = pszWindows + iSpaceUsed;
00209     pSrc = (char *) pszUnix + 5;
00210   }
00211   /* Home dir? */
00212   else if(strncmp(pszUnix, "~/", 2) == 0)
00213   {
00214     strcpy(pszWindows, szHomeDir);
00215     iSpaceUsed = lHomeDirLen;
00216     pDest = pszWindows + lHomeDirLen;
00217     pSrc = (char *) pszUnix + 2;
00218   }
00219   /* Bit bucket? */
00220   else if (strncmp(pszUnix, "/dev/null", 9) == 0)
00221   {
00222     strcpy(pszWindows, "nul");
00223     iSpaceUsed = 3;
00224     pDest = pszWindows + lHomeDirLen;
00225     pSrc = (char *) pszUnix + 9;
00226   }
00227   else
00228   {
00229     pDest = pszWindows;
00230     iSpaceUsed = 0;
00231     pSrc = (char *) pszUnix;
00232   }
00233 
00234   iSpaceUsed += strlen(pSrc);
00235   if(iSpaceUsed + 1 > _MAX_PATH)
00236     return ERROR_BUFFER_OVERFLOW;
00237 
00238   /* substitute all slashes */
00239   while(*pSrc)
00240   {
00241     if(*pSrc == '/')
00242       *pDest = '\\';
00243     else
00244       *pDest = *pSrc;
00245 
00246     pDest++;
00247     pSrc++;
00248   }
00249   *pDest = 0;
00250 
00251   if (derefLinks)
00252     __win_deref(pszWindows);
00253   else
00254   {
00255     /* The filename possibly refers to a symlink, but the .lnk extension may be
00256        missing.
00257         1. Check if the requested file seems to be a normal file
00258         2. Check if the file exists
00259          2.1. Yes: Finished
00260          2.2. No: Check if "filename.lnk" exists
00261           2.2.1 Yes: Append ".lnk" */
00262     if (strnicmp(pDest - 4, ".lnk", 4) != 0)
00263     {
00264       HANDLE h = CreateFile(pszWindows, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
00265         NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00266       if (h == INVALID_HANDLE_VALUE)
00267       {
00268         /* File doesn't exist, try shortcut */
00269         char *pLnk;
00270         int mal;
00271         
00272         if (iSpaceUsed + 5 > _MAX_PATH)
00273         {
00274           pLnk = malloc(iSpaceUsed + 5);
00275           strcpy(pLnk, pszWindows);
00276           mal = 1;
00277         }
00278         else
00279         {
00280           pLnk = pszWindows;
00281           mal = 0;
00282         }
00283         strcat(pLnk, ".lnk");
00284         
00285         h = CreateFile(pLnk, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
00286           NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
00287           
00288         if (h != INVALID_HANDLE_VALUE)
00289         {
00290           /* Shortcut exists */
00291           CloseHandle(h);
00292           if (mal)
00293             /* Need to copy */
00294             if (iSpaceUsed + 5 <= _MAX_PATH)
00295               strcpy(pszWindows, pLnk);
00296             else
00297             {
00298               free(pLnk);
00299               return ERROR_BUFFER_OVERFLOW;
00300             }
00301         }
00302         else
00303           pLnk[iSpaceUsed] = 0;   
00304         
00305         if (mal)
00306           free(pLnk);
00307       }
00308       else
00309         CloseHandle(h);
00310     }
00311   }
00312 
00313 #if DEBUG_WINPROC
00314         {
00315                 char szInfo[1001];
00316 
00317         _win_snprintf(szInfo, 1000, "Posix path %s resolved to %s\n", pszUnix,
00318                 pszWindows);
00319         szInfo[1000] = 0;
00320         __plibc_panic(INT_MAX, szInfo);
00321         }
00322 #endif
00323 
00324   return ERROR_SUCCESS;
00325 }
00326 
00327 /* end of path.c */

Generated on Sun Sep 4 11:16:47 2005 for PlibC by  doxygen 1.4.2