gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r420 - GNUnet/src/util/win


From: durner
Subject: [GNUnet-SVN] r420 - GNUnet/src/util/win
Date: Wed, 9 Mar 2005 13:33:21 -0800 (PST)

Author: durner
Date: 2005-03-09 13:33:19 -0800 (Wed, 09 Mar 2005)
New Revision: 420

Modified:
   GNUnet/src/util/win/win.cc
   GNUnet/src/util/win/winproc.c
Log:
Various fixes & improvements

Modified: GNUnet/src/util/win/win.cc
===================================================================
--- GNUnet/src/util/win/win.cc  2005-03-09 12:22:23 UTC (rev 419)
+++ GNUnet/src/util/win/win.cc  2005-03-09 21:33:19 UTC (rev 420)
@@ -115,6 +115,7 @@
   char *pszLnk;
   int iErr, iLen;
   HRESULT hRes;
+  HANDLE hLink;
 
   CoInitialize(NULL);
   
@@ -145,16 +146,47 @@
   iLen = strlen(pszShortcut);
   if (iLen > 4 && (strcmp(pszShortcut + iLen - 4, ".lnk") != 0))
   {
+    HANDLE hLink;
+    
     pszLnk = (char *) malloc(iLen + 5);
     sprintf(pszLnk, "%s.lnk", pszShortcut);
   }
   else
     pszLnk = strdup(pszShortcut);
 
+  /* Make sure the path refers to a file */
+  hLink = CreateFile(pszLnk, FILE_READ_DATA, FILE_SHARE_READ | 
FILE_SHARE_WRITE,
+                   NULL, OPEN_EXISTING, 0, NULL);
+  if (hLink == INVALID_HANDLE_VALUE)
+  {
+    free(pszLnk);
+    SetErrnoFromWinError(GetLastError());
+    
+    if (errno == ENOENT)
+    {
+      /* There's no path with the ".lnk" extension.
+         We don't quit here, because we have to decide whether the path doesn't
+         exist or the path isn't a link. */
+
+      /* Is it a directory? */
+      if (GetFileAttributes(pszShortcut) & FILE_ATTRIBUTE_DIRECTORY)
+      {
+        errno = EINVAL;
+        return FALSE;
+      }
+
+      pszLnk = strdup(pszShortcut);
+      
+      hLink = CreateFile(pszLnk, FILE_READ_DATA, FILE_SHARE_READ |
+                FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+      SetErrnoFromWinError(GetLastError());      
+    }
+    else
+      return FALSE; /* File/link is there but unaccessible */
+  }
+    
   MultiByteToWideChar(CP_ACP, 0, pszLnk, -1, pwszShortcut, _MAX_PATH);
   
-  free(pszLnk);
-  
   /* Open shortcut */
   if (FAILED(hRes = pFile->Load((LPCOLESTR) pwszShortcut, STGM_READ)))
   {
@@ -162,11 +194,37 @@
     pFile->Release();
     free(pwszShortcut);
     CoUninitialize();
-    SetErrnoFromHRESULT(hRes);
     
+    /* For some reason, opening an invalid link sometimes fails with 
ACCESSDENIED.
+       Since we have opened the file previously, insufficient priviledges
+       are rather not the problem. */
+    if (hRes == E_FAIL || hRes == E_ACCESSDENIED)
+    {
+      /* Check file magic */
+      if (hLink != INVALID_HANDLE_VALUE)
+      {
+        DWORD dwRead;
+        char pMagic[4] = {0, 0, 0, 0};
+        
+        ReadFile(hLink, pMagic, 4, &dwRead, NULL);
+        if (memcmp(pMagic, "L\0\0\0", 4) == 0)
+          SetErrnoFromHRESULT(hRes);
+        else
+          errno = EINVAL; /* No link */
+      }
+      /* else: errno was set above! */
+    }
+    else
+      SetErrnoFromHRESULT(hRes);
+
+    free(pszLnk);
+          
+    CloseHandle(hLink);
     return FALSE;
   }
   
+  CloseHandle(hLink);
+  free(pszLnk);
   free(pwszShortcut);
   
   /* Get target file */

Modified: GNUnet/src/util/win/winproc.c
===================================================================
--- GNUnet/src/util/win/winproc.c       2005-03-09 12:22:23 UTC (rev 419)
+++ GNUnet/src/util/win/winproc.c       2005-03-09 21:33:19 UTC (rev 420)
@@ -638,6 +638,27 @@
 }
 
 /**
+ * Dereference a symlink recursively
+ */
+int __win_deref(char *path)
+{
+  int iDepth = 0;
+
+  errno = 0;
+   
+  while (DereferenceShortcut(path))
+  {
+    if (iDepth++ > 10)
+    {
+      errno = ELOOP;
+      return -1;
+    }
+  }
+  
+  return errno ? -1 : 0;
+}
+
+/**
  * Convert a POSIX-sytle path to a Windows-style path
  * @param pszUnix POSIX path
  * @param pszWindows Windows path
@@ -648,11 +669,14 @@
 {
   char *pSrc, *pDest;
   long iSpaceUsed;
+  int iUnixLen;
 
+  iUnixLen = strlen(pszUnix);
+
   /* Check if we already have a windows path */
   if((strchr(pszUnix, '\\') != NULL) || (strchr(pszUnix, ':') != NULL))
   {
-    if(strlen(pszUnix) > MAX_PATH)
+    if(iUnixLen > MAX_PATH)
       return ERROR_BUFFER_OVERFLOW;
     strcpy(pszWindows, pszUnix);
   }
@@ -714,7 +738,7 @@
   *pDest = 0;
   
   if (derefLinks)
-    DereferenceShortcut(pszWindows);
+    __win_deref(pszWindows);
 
 #if DEBUG_WINPROC
   LOG(LOG_EVERYTHING, "Posix path %s resolved to %s\n", pszUnix, pszWindows);
@@ -1626,27 +1650,6 @@
 }
 
 /**
- * Dereference a symlink recursively
- */
-int __win_deref(const char *path)
-{
-  int iDepth = 0;
-
-  errno = 0;
-   
-  while (DereferenceShortcut(path))
-  {
-    if (iDepth++ > 10)
-    {
-      errno = ELOOP;
-      return -1;
-    }
-  }
-  
-  return errno ? -1 : 0;
-}
-
-/**
  * Get status information on a file
  */
 int __win_stat(const char *path, struct stat *buffer, int iDeref)
@@ -1670,7 +1673,7 @@
   /* Dereference symlinks */
   if (iDeref)
   {
-    if (__win_deref(szFile) == -1)
+    if (__win_deref(szFile) == -1 && errno != EINVAL)
       return -1;
   }
   
@@ -1862,7 +1865,7 @@
   }  
   
   /* CreateShortcut sets errno */
-  lRet = CreateShortcut(path1, path2);
+  lRet = CreateShortcut(szFile1, szFile2);
   
   return lRet ? 0 : -1;
 }





reply via email to

[Prev in Thread] Current Thread [Next in Thread]