FindFirstFile and SHFileOperation

I have a simple little code snippet that checks two files last write date/time to see whether they are different. If they are (or the Local doesn't exist), the code should then copy the Network copy over the local.

I am having two problems:
   1) The program is ALWAYS copying the file.
   2) The SHFileOperation sometimes comes back with it can't copy 'xxxx' file where 'xxxx' is just some stray garbage.

Here is the code snippet. Any suggestions?

      // create the paths to the database
      CString LocalDatabasePath,NetworkDatabasePath;
      if (CSPECFileName.IsEmpty()) NetworkDatabasePath = (LimitsDatabasePath + "\\Limits");
      else NetworkDatabasePath = (LimitsDatabasePath + "\\" + CSPECFileName);
      if (CSPECFileName.IsEmpty()) LocalDatabasePath = (LocalDataPath + "\\Limits");
      else LocalDatabasePath = (LocalDataPath + "\\" + CSPECFileName);

      // find file and get it's info (display error if we get invalid handles)
      WIN32_FIND_DATA NetFileInfo,LocFileInfo;
      if ((FindFirstFile((NetworkDatabasePath + ".dbf"),&NetFileInfo) == INVALID_HANDLE_VALUE) &&
            (FindFirstFile((LocalDatabasePath + ".dbf"),&LocFileInfo) == INVALID_HANDLE_VALUE))
            AfxMessageBox("Unable To Open Network Or Local Limits Files.\nNetwork Not Available Or Paths Incorrect.",
                  MB_OK | MB_ICONEXCLAMATION);
      // if we get good net handle and the file dates do not match, copy the net to the local
      else if (NetworkStatus)
            {
            if (NetFileInfo.ftLastWriteTime.dwLowDateTime != LocFileInfo.ftLastWriteTime.dwLowDateTime ||
                  NetFileInfo.ftLastWriteTime.dwHighDateTime != LocFileInfo.ftLastWriteTime.dwHighDateTime)
                  {
                  SHFILEOPSTRUCT sfo;
                  memset(&sfo,0,sizeof(sfo));
                  sfo.hwnd = ::GetTopWindow(NULL);
                  sfo.wFunc = FO_COPY;
                  sfo.pFrom = (NetworkDatabasePath + ".*\0\0");
                  sfo.pTo = (LocalDataPath + "\0\0");
                  sfo.fFlags = FOF_NOCONFIRMATION | FOF_SIMPLEPROGRESS;
                  sfo.lpszProgressTitle = ("Copying Modified Limits Database Files - Please Wait...");
                  ::SHFileOperation(&sfo);
                  }
            }
maknightAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jtwine100697Commented:
  At first glance (I am tired), I do not know why the files is always being copied, but here is a guess for your "garbage filenames xxx" problem:

   When you use (CString + "constant") you are creating a temporary object.  Try storing composite filenames in a seperate CString object, AND putting NULLs into a CString tends to confuse the CString class.  Try using a regular char buffer.

-=- James.
0
jtwine100697Commented:
Two more things:

   o  You should be storing the HANDLE returned by FindFirstFile(...) to use with FindClose(...) later on.

   o  Check the ftLastWriteTime structures for both the remote and the local file:  If any of them they are zero (initalize them first with ZeroMemory(...) ), it means that the times could not be obtained.

-=- James.
0
chensuCommented:
There is a logical error in your code.

Look at
if ((FindFirstFile((NetworkDatabasePath + ".dbf"),&NetFileInfo) == INVALID_HANDLE_VALUE) && 
(FindFirstFile((LocalDatabasePath + ".dbf"),&LocFileInfo) == INVALID_HANDLE_VALUE))

Shouldn't you use || instead of &&?
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

jtwine100697Commented:
  chensu...  Yes, there is a logical error in his error checking, and he would need still further (more robust) error checking to make it right, but that answers neither of his questions.

-=- James.
0
chensuCommented:
jtwine,

I should have indicated that this error is likely to cause those two problems if only one of the FindFirstFile() functions returns INVALID_HANDLE_VALUE.
0
maknightAuthor Commented:
I am aware of the  of the lack of robust error-checking. That in itself should not cause the failure altogether of FindFirstFile to get the correct LastWriteTime. Added robustness is a secondary issue I'll resolve once the core code functions.

The && is correct since I am looking for the case when both files are not available- meaning the system cannot continue (handled elsewhere). The additional conditions in the else just make sure that at least the network copy is available for copying.

Let me look over your comments further and see if they point the way. I think I'm running into a NetWare issue (network file) since my local file is returning the LastWriteTime data properly.
0
maknightAuthor Commented:
jtwine, Got your first comment taken care of. I knew that about CString. Guess I was tired yesterday as well...
0
chensuCommented:
I don't think the usage of CString causes any problems. Yes, it is a temporary object. But it is alive as long as the execution does not go out of the scope. Using a regular char buffer is the same unless you use a global or static char buffer. The best way is to debug it carefully. Use TRACE and ASSERT liberally. They will help you avoid many problems.
0
maknightAuthor Commented:
I removed the TRACE and ASSERT statements from what I posted to make it cleaner for you folks here to read. They tend to clutter code sometimes <g>. Once I changed the two CStrings in the SHFILEOPSTRUCT to char SomeVar[Max_Path] that problem went away. The double NULL (\0\0) was seemingly driving it nuts. It was a soft drive to insanity b/c it would never really trap anything I could put in to try to trap it, but nonetheless it was going nuts.
0
maknightAuthor Commented:
Everything appears to be functioning well now. Thanks.
0
chensuCommented:
You should have rejected my answer and given the points to jtwine since he did mention "putting NULLs into a CString tends to confuse the CString class". I didn't notice the double NULL problem.
0
maknightAuthor Commented:
Oops! Actually I didn't look to see who had it locked. Assumed the first to respond had locked it, but jtwine had only commented. Sorry, James. Thanks both.

About CString: It's nice, but it can also be a pain in the rear end sometimes since it seems several things can confuse it.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.