file.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 9k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*
  2.  * file.c - File routines module.
  3.  */
  4. /* Headers
  5.  **********/
  6. #include "project.h"
  7. #pragma hdrstop
  8. /* Constants
  9.  ************/
  10. /* size of file comparison buffer in bytes */
  11. #define COMP_BUF_SIZE      (16U * 1024U)
  12. /* Module Variables
  13.  *******************/
  14. #pragma data_seg(DATA_SEG_SHARED)
  15. /* lock count for file comparison buffer */
  16. PRIVATE_DATA ULONG MulcCompBufLock = 0;
  17. /* buffers for file comparison */
  18. PRIVATE_DATA PBYTE MrgbyteCompBuf1 = NULL;
  19. PRIVATE_DATA PBYTE MrgbyteCompBuf2 = NULL;
  20. /* length of file comparison buffers in bytes */
  21. PRIVATE_DATA UINT MucbCompBufLen = 0;
  22. #pragma data_seg()
  23. /****************************** Public Functions *****************************/
  24. /*
  25. ** BeginComp()
  26. **
  27. ** Increments file comparison buffers' lock count.
  28. **
  29. ** Arguments:     void
  30. **
  31. ** Returns:       TWINRESULT
  32. **
  33. ** Side Effects:  none
  34. */
  35. PUBLIC_CODE void BeginComp(void)
  36. {
  37.    ASSERT((MrgbyteCompBuf1 && MrgbyteCompBuf2 && MucbCompBufLen > 0) ||
  38.           (! MrgbyteCompBuf1 && ! MrgbyteCompBuf2 && ! MucbCompBufLen));
  39.    ASSERT(MulcCompBufLock < ULONG_MAX);
  40.    MulcCompBufLock++;
  41.    return;
  42. }
  43. /*
  44. ** EndComp()
  45. **
  46. ** Decrements file comparison buffers' lock count.
  47. **
  48. ** Arguments:     void
  49. **
  50. ** Returns:       void
  51. **
  52. ** Side Effects:  Frees file comparison buffers if lock count goes to 0.
  53. */
  54. PUBLIC_CODE void EndComp(void)
  55. {
  56.    ASSERT((MrgbyteCompBuf1 && MrgbyteCompBuf2 && MucbCompBufLen > 0) ||
  57.           (! MrgbyteCompBuf1 && ! MrgbyteCompBuf2 && ! MucbCompBufLen));
  58.    ASSERT(MulcCompBufLock > 0 || (! MrgbyteCompBuf1 && ! MrgbyteCompBuf2 && ! MucbCompBufLen));
  59.    if (EVAL(MulcCompBufLock > 0))
  60.       MulcCompBufLock--;
  61.    /* Are the comparison buffers still locked? */
  62.    if (! MulcCompBufLock && MrgbyteCompBuf1 && MrgbyteCompBuf2)
  63.    {
  64.       /* No.  Free them. */
  65.       FreeMemory(MrgbyteCompBuf1);
  66.       MrgbyteCompBuf1 = NULL;
  67.       FreeMemory(MrgbyteCompBuf2);
  68.       MrgbyteCompBuf2 = NULL;
  69.       TRACE_OUT((TEXT("EndComp(): Two %u byte file comparison buffers freed."),
  70.                  MucbCompBufLen));
  71.       MucbCompBufLen = 0;
  72.    }
  73.    return;
  74. }
  75. /*
  76. ** CompareFilesByHandle()
  77. **
  78. ** Determines whether or not two files are the same.
  79. **
  80. ** Arguments:     h1 - DOS file handle to first open file
  81. **                h2 - DOS file handle to second open file
  82. **                pbIdentical - pointer to BOOL to be filled in with value
  83. **                               indicating whether or not the files are
  84. **                               identical
  85. **
  86. ** Returns:       TWINRESULT
  87. **
  88. ** Side Effects:  Changes the position of the file pointer of each file.
  89. */
  90. PUBLIC_CODE TWINRESULT CompareFilesByHandle(HANDLE h1, HANDLE h2,
  91.                                               PBOOL pbIdentical)
  92. {
  93.    TWINRESULT tr;
  94.    ASSERT(IS_VALID_HANDLE(h1, FILE));
  95.    ASSERT(IS_VALID_HANDLE(h2, FILE));
  96.    ASSERT(IS_VALID_WRITE_PTR(pbIdentical, BOOL));
  97.    ASSERT((MrgbyteCompBuf1 && MrgbyteCompBuf2 && MucbCompBufLen > 0) ||
  98.           (! MrgbyteCompBuf1 && ! MrgbyteCompBuf2 && ! MucbCompBufLen));
  99.    ASSERT(MulcCompBufLock || (! MrgbyteCompBuf1 && ! MrgbyteCompBuf2 && ! MucbCompBufLen));
  100.    /* Have the comparison buffers already been allocated? */
  101.    if (MrgbyteCompBuf1)
  102.       tr = TR_SUCCESS;
  103.    else
  104.    {
  105.       /* No.  Allocate them. */
  106.       tr = TR_OUT_OF_MEMORY;
  107.       if (AllocateMemory(COMP_BUF_SIZE, &MrgbyteCompBuf1))
  108.       {
  109.          if (AllocateMemory(COMP_BUF_SIZE, &MrgbyteCompBuf2))
  110.          {
  111.             /* Success! */
  112.             MucbCompBufLen = COMP_BUF_SIZE;
  113.             tr = TR_SUCCESS;
  114.             TRACE_OUT((TEXT("CompareFilesByHandle(): Two %u byte file comparison buffers allocated."),
  115.                        MucbCompBufLen));
  116.          }
  117.          else
  118.          {
  119.             FreeMemory(MrgbyteCompBuf1);
  120.             MrgbyteCompBuf1 = NULL;
  121.          }
  122.       }
  123.    }
  124.    if (tr == TR_SUCCESS)
  125.    {
  126.       DWORD dwcbLen1;
  127.       BeginComp();
  128.       /* Get file lengths to compare. */
  129.       tr = TR_SRC_READ_FAILED;
  130.       dwcbLen1 = SetFilePointer(h1, 0, NULL, FILE_END);
  131.       if (dwcbLen1 != INVALID_SEEK_POSITION)
  132.       {
  133.          DWORD dwcbLen2;
  134.          dwcbLen2 = SetFilePointer(h2, 0, NULL, FILE_END);
  135.          if (dwcbLen2 != INVALID_SEEK_POSITION)
  136.          {
  137.             /* Are the files the same length? */
  138.             if (dwcbLen1 == dwcbLen2)
  139.             {
  140.                /* Yes.  Move to the beginning of the files. */
  141.                if (SetFilePointer(h1, 0, NULL, FILE_BEGIN) != INVALID_SEEK_POSITION)
  142.                {
  143.                   if (SetFilePointer(h2, 0, NULL, FILE_BEGIN) != INVALID_SEEK_POSITION)
  144.                   {
  145.                      tr = TR_SUCCESS;
  146.                      do
  147.                      {
  148.                         DWORD dwcbRead1;
  149.                         if (ReadFile(h1, MrgbyteCompBuf1, MucbCompBufLen, &dwcbRead1, NULL))
  150.                         {
  151.                            DWORD dwcbRead2;
  152.                            if (ReadFile(h2, MrgbyteCompBuf2, MucbCompBufLen, &dwcbRead2, NULL))
  153.                            {
  154.                               if (dwcbRead1 == dwcbRead2)
  155.                               {
  156.                                  /* At EOF? */
  157.                                  if (! dwcbRead1)
  158.                                  {
  159.                                     /* Yes. */
  160.                                     *pbIdentical = TRUE;
  161.                                     break;
  162.                                  }
  163.                                  else if (MyMemComp(MrgbyteCompBuf1, MrgbyteCompBuf2, dwcbRead1) != CR_EQUAL)
  164.                                  {
  165.                                     /* Yes. */
  166.                                     *pbIdentical = FALSE;
  167.                                     break;
  168.                                  }
  169.                               }
  170.                               else
  171.                                  tr = TR_SRC_READ_FAILED;
  172.                            }
  173.                            else
  174.                               tr = TR_SRC_READ_FAILED;
  175.                         }
  176.                         else
  177.                            tr = TR_SRC_READ_FAILED;
  178.                      } while (tr == TR_SUCCESS);
  179.                   }
  180.                }
  181.             }
  182.             else
  183.             {
  184.                /* No.  Files different lengths. */
  185.                *pbIdentical = FALSE;
  186.                tr = TR_SUCCESS;
  187.             }
  188.          }
  189.       }
  190.       EndComp();
  191.    }
  192.    return(tr);
  193. }
  194. /*
  195. ** CompareFilesByName()
  196. **
  197. **
  198. **
  199. ** Arguments:
  200. **
  201. ** Returns:       TWINRESULT
  202. **
  203. ** Side Effects:  none
  204. */
  205. PUBLIC_CODE TWINRESULT CompareFilesByName(HPATH hpath1, HPATH hpath2,
  206.                                           PBOOL pbIdentical)
  207. {
  208.    TWINRESULT tr;
  209.    ASSERT(IS_VALID_HANDLE(hpath1, PATH));
  210.    ASSERT(IS_VALID_HANDLE(hpath2, PATH));
  211.    ASSERT(IS_VALID_WRITE_PTR(pbIdentical, BOOL));
  212.    /* Only verify source and destination volumes once up front. */
  213.    if (IsPathVolumeAvailable(hpath1) &&
  214.        IsPathVolumeAvailable(hpath2))
  215.    {
  216.       HANDLE h1;
  217.       TCHAR rgchFile1[MAX_PATH_LEN];
  218.       /* Try to open files.  Assume sequential reads. */
  219.       GetPathString(hpath1, 0, rgchFile1);
  220.       h1 = CreateFile(rgchFile1, GENERIC_READ, FILE_SHARE_READ, NULL,
  221.                       OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  222.       if (h1 != INVALID_HANDLE_VALUE)
  223.       {
  224.          HANDLE h2;
  225.          TCHAR rgchFile2[MAX_PATH_LEN];
  226.          GetPathString(hpath2, 0, rgchFile2);
  227.          h2 = CreateFile(rgchFile2, GENERIC_READ, FILE_SHARE_READ, NULL,
  228.                          OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  229.          if (h2 != INVALID_HANDLE_VALUE)
  230.          {
  231.             TRACE_OUT((TEXT("CompareFilesByHandle(): Comparing files %s and %s."),
  232.                        DebugGetPathString(hpath1),
  233.                        DebugGetPathString(hpath2)));
  234.             tr = CompareFilesByHandle(h1, h2, pbIdentical);
  235. #ifdef DEBUG
  236.             if (tr == TR_SUCCESS)
  237.             {
  238.                if (*pbIdentical)
  239.                   TRACE_OUT((TEXT("CompareFilesByHandle(): %s and %s are identical."),
  240.                              DebugGetPathString(hpath1),
  241.                              DebugGetPathString(hpath2)));
  242.                else
  243.                   TRACE_OUT((TEXT("CompareFilesByHandle(): %s and %s are different."),
  244.                              DebugGetPathString(hpath1),
  245.                              DebugGetPathString(hpath2)));
  246.             }
  247. #endif
  248.             /*
  249.              * Failing to close the file properly is not a failure condition here.
  250.              */
  251.             CloseHandle(h2);
  252.          }
  253.          else
  254.             tr = TR_DEST_OPEN_FAILED;
  255.           /*
  256.            * Failing to close the file properly is not a failure condition here.
  257.            */
  258.          CloseHandle(h1);
  259.       }
  260.       else
  261.          tr = TR_SRC_OPEN_FAILED;
  262.    }
  263.    else
  264.       tr = TR_UNAVAILABLE_VOLUME;
  265.    return(tr);
  266. }