Exemple #1
0
void ReportError(int err, LPCSTR szContext, LPCTSTR pszPath)
{
   BPRINT_BUFFER & bp = *g_pbpErr;

   bprint_EndLine(bp);
   bprint(bp, szContext);
   if (pszPath)
      {
      bprint_Sep(bp, ' ');
      bprint(bp, pszPath);
      }
   bprint_Sep(bp, ' ');
   bprint(bp, TEXT("Failed : "));
   bprint_AppendErrorText(bp, err);
   bprint_EndLine(bp);
}
Exemple #2
0
static void __cdecl bprintfl(BPRINT_BUFFER & bp, LPCTSTR pszFormat, ...)
{
   va_list va;
   va_start(va, pszFormat);
   int cch = bvprintf(bp, pszFormat, va);
   va_end(va);

   bprint_EndLine(bp);
}
Exemple #3
0
void bprint_Terminate(BPRINT_BUFFER & bp, bool fFlush)
{
   if (fFlush)
      bprint_EndLine(bp);

   if (bp.psz)
   {
      LocalFree(bp.psz);
      bp.psz = NULL;
   }
}
Exemple #4
0
void App_Cleanup(bool fFlush)
{
   bprint_Terminate(fFlush);
   if (g_bprintErr.hOut)
      {
      if (fFlush)
         bprint_EndLine(g_bprintErr);
      if (g_bprintErr.hOut != GetStdHandle(STD_ERROR_HANDLE))
         CloseHandle(g_bprintErr.hOut);
      g_bprintErr.hOut = NULL;
      }
   bprint_Terminate(g_bprintErr, false);
}
Exemple #5
0
int InitOwnerSid(BOOL fDiagnostic, BPRINT_BUFFER *pbp)
{
   int err = 0;
   if ( ! ls.OwnerSid)
      {
      LPVOID pvInfo = NULL;
      DWORD cbSize = 0;
      if ( ! GetTokenInformation(ls.hToken, TokenOwner,  NULL, 0, &cbSize))
         {
         err = GetLastError();
         if (ERROR_INSUFFICIENT_BUFFER == err)
            {
            err = 0;
            pvInfo = LocalAlloc(LPTR, cbSize);
            if ( ! pvInfo)
               {
               err = ERROR_OUTOFMEMORY;
               }
            else if ( ! GetTokenInformation(ls.hToken, TokenOwner,  pvInfo, cbSize, &cbSize))
               {
               err = GetLastError();
               ReportError(err, "GetTokenInformation(TokenOwner)");
               }
            else
               {
               err = 0;
               const TOKEN_OWNER * pOwner = (const TOKEN_OWNER *)pvInfo;
               ls.OwnerSid = pOwner->Owner;
               if (fDiagnostic)
                  {
                  bprintf(*pbp, TEXT("Got Owner Sid "));
                  PrintSidName(ls.OwnerSid, *pbp);
                  bprint_Sep(*pbp, ' ');
                  PrintSidText(ls.OwnerSid, *pbp);
                  bprint_EndLine(*pbp);
                  }
               }
            }
         }
      }

   return err;
}
Exemple #6
0
__inline bool bprint_Flush(BPRINT_BUFFER & bp) { return bprint_EndLine(bp); }
Exemple #7
0
static void __cdecl bprintl(BPRINT_BUFFER & bp, LPCTSTR psz)
{
   bprint(bp, psz);
   bprint_EndLine(bp);
}
Exemple #8
0
static int RecursiveDeleteDirectory(LPCTSTR pszPathIn, DWORD fdwFlags)
{
   BPRINT_BUFFER & bp = *g_pbpDiag;
   DeletePathData dpd;
   ZeroMemory(&dpd, sizeof(dpd));
   dpd.pbp = &g_bpErr;

   //this is for traversal testing...
   //dpd.fNoDelete = true;

   fdwFlags |= TDT_DIRLAST; // So we get directory callbacks after children have been deleted.

   // if the path isn't too long, convert to canonical form.  for long paths
   // they has better provide canonical form to begin with.
   //
   TCHAR szCanonPath[MAX_PATH+1];
   LPCTSTR pszPath = pszPathIn;
   if (lstrlen(pszPathIn) < MAX_PATH)
      {
      if (PathCanonicalize(szCanonPath, pszPathIn))
         pszPath = szCanonPath;      
      if (PathIsRelative(pszPath))
         return ERROR_INVALID_PARAMETER;
      }

   // the unicode versions of the windows file api's can handle very long
   // path names if they are canonical and if they are preceeded by \\?\.
   // if we are build unicode, take advantage of that capability.
   static const WCHAR szPre[]= L"\\\\?\\";
   WCHAR szFullPath[MAX_PATH + NUMCHARS(szPre)];
   WCHAR * pszFullPath = szFullPath;
   WCHAR * pszFilePart = NULL;

   lstrcpyW(szFullPath, szPre);
   MultiByteToWideChar(CP_ACP, 0, pszPath, -1, szFullPath + NUMCHARS(szPre)-1, MAX_PATH);
   /*
   UINT cchFullPath = GetFullPathNameW(pszPath, MAX_PATH, szFullPath + NUMCHARS(szPre)-1, &pszFilePart);
   if (cchFullPath >= NUMCHARS(szFullPath)-1)
      {
      pszFullPath = (TCHAR *)LocalAlloc(LPTR, (cchFullPath + NUMCHARS(szPre) + 2) * sizeof(WCHAR));
      if (pszFullPath)
         {
         lstrcpyW(pszFullPath, szPre);
         if (GetFullPathNameW(pszPath, cchFullPath+2, pszFullPath + NUMCHARS(szPre)-1, &pszFilePart) <= cchFullPath+2)
            pszPath = pszFullPath;
         }
      }
   else
      pszPath = szFullPath;
   */

   int err = 0;
   DWORD fdwFileAttributes = GetFileAttributesW(szFullPath);
   if (INVALID_FILE_ATTRIBUTES == fdwFileAttributes)
      {
      fdwFileAttributes = 0;
      err = GetLastError();
      ReportError(err, "Could not get attributes for ", pszPath);
      return err;
      }
   const bool fIsDir = (fdwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;

   if (fdwFlags & TDT_DIAGNOSTIC)
      bprintfl(bp, TEXT("Delete %s 0x%04X %s\\*"), fIsDir ? TEXT("Directory") : TEXT("File"), fdwFlags, pszPath);

   if (fIsDir)
      {
      err = TraverseDirectoryTreeW(szFullPath, L"*", fdwFlags, DeletePathCallback, &dpd, 0);
      if ( ! err || (fdwFlags & TDT_CONTINUE))
         {
         bprint_EndLine(bp);
         if ( ! dpd.fNoDelete && ! RemoveDirectoryW(szFullPath))
            {
            bprint_EndLine(bp);
            err = GetLastError();
            ReportError(err, "RemoveDirectory", pszPath);
            }
         }
      }
   else // initial path is a file, not a directory. 
      {
      if ( ! dpd.fNoDelete &&  ! DeleteFileW(szFullPath))
         {
         bprint_EndLine(bp);
         err = GetLastError();
         ReportError(err, "DeleteFile", pszPath);
         }
      }

   bprint_EndLine(bp);
   return err;
}
Exemple #9
0
static bool WINAPI DeletePathCallback (
   VOID *  pvUser, 
   LPCWSTR pszPath,   // path and filename, may be absolute or relative.
   int     ochName,   // offset from start of pszPath to first char of the file/dir name.
   DWORD   fdwFlags,
   int     cDepth,
   int     ixItem,
   const WIN32_FIND_DATAW & wfd)
{
   DeletePathData & dpd = *(DeletePathData*)pvUser;
   if (dpd.fAborting)
      return false;

   BPRINT_BUFFER & bp = *dpd.pbp;
   const bool fDirectory = (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
   const bool fProtected = (wfd.dwFileAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)) != 0;

   dpd.cTotalVisited += 1;
   if (fDirectory)
      dpd.cDirsVisited += 1;
   else
      dpd.cFilesVisited += 1;

   dpd.cLastDepth = cDepth;
   dpd.cMaxDepth = max(cDepth, dpd.cMaxDepth);

   if (fProtected)
      {
      // build attributes flags that don't contain readonly or system (or hidden)
      DWORD fdwAttr = wfd.dwFileAttributes & (FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_ATTRIBUTE_TEMPORARY);
      if ((fdwFlags & TDT_DIAGNOSTIC) || dpd.fDiagnostic)
         bprintfl(*dpd.pbp, TEXT("Clearing%s%s attrib(s) from %s"), 
                 (wfd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) ? TEXT(" SYS") : TEXT(""),
                 (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? TEXT(" RO") : TEXT(""),
                 pszPath);

      if ( ! SetFileAttributesW(pszPath,  fdwAttr))
         {
         int err = GetLastError();
         if (ERROR_ACCESS_DENIED == err)
            {
            int errT = RemoveFileDACLs(pszPath, dpd.fDiagnostic, dpd.pbp);
            if (errT)
               err = errT;
            else if (SetFileAttributesW(pszPath, fdwAttr))
               err = 0;
            else
               err = GetLastError();
            }
         }
      }

   if (fdwFlags & TDT_FIRST)
      dpd.fDirAlreadyTriedDACLRemove = false;

   bprint_EndLine(bp);
   int err = ERROR_SUCCESS;
   if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      {
      // When we get the DIRLAST callback, it should be after we have deleted all of the children.
      // NOW we can try and remove the directory.
      // 
      if (fdwFlags & TDT_DIRLAST)
         {
         err = DpdRemoveDirectory(pszPath, ochName, dpd, dpd.fDiagnostic, DPD_F_REMOVEDACLS);
         }
      }
   else
      {
      err = DpdDeleteFile(pszPath, ochName, dpd, dpd.fDiagnostic, DPD_F_REMOVEDACLS);
      }

   if (err && ! (fdwFlags & TDT_CONTINUE))
      {
      bprint_EndLine(bp);
      if (dpd.fDiagnostic)
         bprintl(bp, "Aborting.");
      dpd.fAborting = true;
      return false;
      }

   bprint_EndLine(bp);
   return true;
}
Exemple #10
0
int DeletePath(LPCTSTR pszPathIn, 
               LPCTSTR pszPattern, 
               DWORD   fdwTraverse, 
               DWORD   fdwSecurity, 
               DWORD   fdwVerbose, 
               BPRINT_BUFFER & bp)
{
   DWORD fdwFlags = fdwTraverse & (TDT_INPUTMASK & ~TDT_USERMASK);
   if (fdwVerbose & DP_V_VERBOSE)
      fdwFlags |= TDT_USER_F_VERBOSE;
   if (fdwVerbose & DP_V_DIAGNOSTIC)
      fdwFlags |= TDT_DIAGNOSTIC;

   bool fQuiet = (fdwVerbose & DP_V_QUIET) != 0;

   DeletePathData lad;
   ZeroStruct(&lad);
   lad.pbp = &bp;

   if (fdwSecurity & DP_S_NODELETE)
      lad.fNoDelete = true;

   fdwFlags |= TDT_DIRLAST; // So we get directory callbacks after children have been deleted.

   // if the path isn't too long, convert to canonical form.  for long paths
   // they has better provide canonical form to begin with.
   //
   TCHAR szCanonPath[MAX_PATH+1];
   LPCTSTR pszPath = pszPathIn;
   if (lstrlen(pszPathIn) < MAX_PATH &&
       PathCanonicalize(szCanonPath, pszPathIn))
      {
      pszPath = szCanonPath;      
      }

   // the unicode versions of the windows file api's can handle very long
   // path names if they are canonical and if they are preceeded by \\?\.
   // if we are build unicode, take advantage of that capability.
  #ifdef UNICODE
   static const TCHAR szPre[]= TEXT("\\\\?\\");
   TCHAR szFullPath[MAX_PATH + NUMCHARS(szPre)];
   TCHAR * pszFullPath = szFullPath;
   TCHAR * pszFilePart = NULL;

   lstrcpy(szFullPath, szPre);
   UINT cchFullPath = GetFullPathName(pszPath, MAX_PATH, szFullPath + NUMCHARS(szPre)-1, &pszFilePart);
   if (cchFullPath >= NUMCHARS(szFullPath)-1)
      {
      pszFullPath = (TCHAR *)LocalAlloc(LPTR, (cchFullPath + NUMCHARS(szPre) + 2) * sizeof(TCHAR));
      if (pszFullPath)
         {
         lstrcpy(pszFullPath, szPre);
         if (GetFullPathName(pszPath, cchFullPath+2, pszFullPath + NUMCHARS(szPre)-1, &pszFilePart) <= cchFullPath+2)
            pszPath = pszFullPath;
         }
      }
   else
      pszPath = szFullPath;
  #endif

   int err = 0;
   DWORD fdwFileAttributes = GetFileAttributes(pszPath);
   if (INVALID_FILE_ATTRIBUTES == fdwFileAttributes)
      {
      fdwFileAttributes = 0;
      err = GetLastError();
      ReportError(err, "Could not get attributes for ", pszPath);
      return err;
      }
   const bool fIsDir = (fdwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;

   if (fdwFlags & TDT_DIAGNOSTIC)
      bprintfl(bp, TEXT("Delete %s 0x%04X %s\\%s"), fIsDir ? TEXT("Directory") : TEXT("File"), fdwFlags, pszPath, pszPattern);

   if (fIsDir)
      {
      if (fdwTraverse & TDT_SUBDIRS)
         {
         if ( ! pszPattern || ! pszPattern[0])
            err = TraverseDirectoryTree(pszPath, TEXT("*"), fdwFlags, DeletePathCallback, &lad, 0);
         else
            err = TraverseDirectoryTree(pszPath, pszPattern, fdwFlags, DeletePathCallback, &lad, 0);
         }

      if ( ! err || (fdwFlags & TDT_CONTINUE))
         {
         bprint_EndLine(bp);
         if ( ! (fdwTraverse & TDT_NODIRS) && (!pszPattern || !pszPattern[0]))
            {
            if ( ! fQuiet)
               {
               bprint(bp, lad.fNoDelete ? TEXT("NoRemove ") : TEXT("Removing "));
               bprint(bp, pszPath);
               }
            if ( ! lad.fNoDelete && ! RemoveDirectory(pszPath))
               {
               bprint_EndLine(bp);
               err = GetLastError();
               ReportError(err, "RemoveDirectory", pszPath);
               if ( ! (fdwFlags & TDT_CONTINUE))
                  if ( ! fQuiet) bprintl(bp, "Aborting.");
               }
            }
         }
      }
   else // initial path is a file, not a directory. 
      {
      if (fdwTraverse & TDT_SUBDIRS)
         {
         if ( ! pszPattern || ! pszPattern[0])
            {
            err = TraverseDirectoryTree(pszPath, TEXT("*"), fdwFlags, DeletePathCallback, &lad, 0);
            }
         else
            {
            //#pragma REMIND("TJ: add code to split the file from the path and recurse on the filename.")
            }
         }
      if (fdwTraverse & TDT_NOFILES)
         {
         // Nothing to do.
         }
      else if ( ! pszPattern || ! pszPattern[0])
         {
         if ( ! fQuiet)
            {
            bprint(bp, lad.fNoDelete ? TEXT("NoDelete ") : TEXT("Deleting "));
            bprint(bp, pszPath);
            }
         if ( ! lad.fNoDelete &&  ! DeleteFile(pszPath))
            {
            bprint_EndLine(bp);
            err = GetLastError();
            ReportError(err, "DeleteFile", pszPath);
            if ( ! (fdwFlags & TDT_CONTINUE))
               if ( ! fQuiet) bprintl(bp, "Aborting.");
            }
         }
      }

   bprint_EndLine(bp);
   return err;
}