// 自从 wmware 6.0 以上,wmware 提供了一个 vix 的 sdk 包,
// 提供一些接口完成控制 wmware 的操作,但是这个 sdk 提供的接口很少,
// 下面提供一个简单的封装实例,对想了解 vix 朋友。
// 下面贴一个 host to guest , guest to host 文件夹 拷贝的实现函数,vix 没有提供次接口, 
呵呵。。,第一次封装别人的库函数,  

//////////////////////////////////////////////////////////////////////////
// 扩展实现, 现 vix 不支持
CVixJob* CVixVM::_CopyFileFromGuestToHost(
                     PCTSTR guestPathName, 
                     PCTSTR hostPathName,
                     int options,
                     VixHandle propertyListHandle,
                     VixEventProc* callbackProc,
                     void* clientData
                     )
{
  ASSERT(IsValid());
  
#ifdef _UNICODE
  CHAR _guestPathName[MAX_PATH], _hostPathName[MAX_PATH];
  if ( guestPathName != NULL )
  {
    wcstombs(_guestPathName, guestPathName, MAX_PATH);
    guestPathName = (PCTSTR)_guestPathName;
  }
  if ( hostPathName != NULL )
  {
    wcstombs(_hostPathName, hostPathName, MAX_PATH);
    hostPathName = (PCTSTR)_hostPathName;
  }
#endif
  
  VixHandle jobHandle = VixVM_CopyFileFromGuestToHost(m_Handle, (char*)guestPathName, (char*)hostPathName, options, propertyListHandle, callbackProc, clientData);
  return jobHandle != VIX_INVALID_HANDLE ? new CVixJob(jobHandle) : NULL;
}

BOOL CVixVM::CopyFileFromGuestToHost(
                   LPCTSTR guestPathName, 
                   LPCTSTR hostPathName,
                   int options,
                   VixHandle propertyListHandle,
                   VixEventProc* callbackProc,
                   void* clientData
                   )
{
  ASSERT(IsValid());
  
  CVixJob* jobHandle = _CopyFileFromGuestToHost(guestPathName, hostPathName, options, propertyListHandle, callbackProc, clientData);
  if ( jobHandle == NULL )
    return FALSE;
  
  BOOL bResult = jobHandle->Wait();
  jobHandle->ReleaseHandle();

  return bResult;
}

CVixJob* CVixVM::_CopyFileFromHostToGuest(
                   PCTSTR hostPathName,
                   PCTSTR guestPathName,
                   int options,
                   VixHandle propertyListHandle,
                   VixEventProc* callbackProc,
                   void* clientData
                   )
{
  ASSERT(IsValid());
  
#ifdef _UNICODE
  CHAR _guestPathName[MAX_PATH], _hostPathName[MAX_PATH];
  if ( guestPathName != NULL )
  {
    wcstombs(_guestPathName, guestPathName, MAX_PATH);
    guestPathName = (PCTSTR)_guestPathName;
  }
  if ( hostPathName != NULL )
  {
    wcstombs(_hostPathName, hostPathName, MAX_PATH);
    hostPathName = (PCTSTR)_hostPathName;
  }
#endif
  
  VixHandle jobHandle = VixVM_CopyFileFromHostToGuest(m_Handle, (char*)hostPathName, (char*)guestPathName, options, propertyListHandle, callbackProc, clientData);
  return jobHandle != VIX_INVALID_HANDLE ? new CVixJob(jobHandle) : NULL;
}

BOOL CVixVM::CopyFileFromHostToGuest(
                   PCTSTR hostPathName,
                   PCTSTR guestPathName,
                   int options,
                   VixHandle propertyListHandle,
                   VixEventProc* callbackProc,
                   void* clientData
                   )
{
  ASSERT(IsValid());
  
  CVixJob* jobHandle = _CopyFileFromHostToGuest(hostPathName, guestPathName, options, propertyListHandle, callbackProc, clientData);
  if ( jobHandle == NULL )
    return FALSE;

  BOOL bResult = jobHandle->Wait();
  jobHandle->ReleaseHandle();

  return bResult;
}

BOOL CVixVM::CopyDirectoryFromGuestToHost(PCTSTR guestDirectory, PCTSTR hostDirectory)
{
  BOOL bResult = TRUE;

  if ( GetFileAttributes(hostDirectory) == INVALID_FILE_ATTRIBUTES && !CreateDirectory(hostDirectory, NULL) )
    return FALSE;

  CVixJob* jobHandle = _ListDirectoryInGuest(guestDirectory);
  if ( jobHandle != NULL && jobHandle->Wait() )
  {
    int num = jobHandle->GetNumProperties(VIX_PROPERTY_JOB_RESULT_ITEM_NAME);
    for ( int i = 0; i < num; i++ )
    {
      TCHAR guest_szFilePath[MAX_PATH], host_szFilePath[MAX_PATH];
      char* fname;
      long flag;

      jobHandle->GetNthProperties(i, VIX_PROPERTY_JOB_RESULT_ITEM_NAME, &fname, VIX_PROPERTY_JOB_RESULT_FILE_FLAGS, &flag, VIX_PROPERTY_NONE);
#ifdef UNICODE
      fname 没有转换
#endif
      _stprintf(guest_szFilePath, _T("%s\\%s"), guestDirectory, fname);
      _stprintf(host_szFilePath, _T("%s\\%s"), hostDirectory, fname);
      if ( flag == VIX_FILE_ATTRIBUTES_DIRECTORY )
      {
        bResult = CopyDirectoryFromGuestToHost(guest_szFilePath, host_szFilePath) && bResult;
      }
      else
      {
        bResult = CopyFileFromGuestToHost(guest_szFilePath, host_szFilePath) && bResult;
      }

      FreeBuffer(fname);
    }

    jobHandle->ReleaseHandle();
  }

  return bResult;
}

BOOL CVixVM::CopyDirectoryFromHostToGuest(PCTSTR hostDirectory, PCTSTR guestDirectory)
{
  WIN32_FIND_DATA wfd;
  HANDLE hFindFile;
  BOOL bResult = TRUE;
  
  if ( !DirectoryExistsInGuest(guestDirectory) && !CreateDirectoryInGuest(guestDirectory) )
  {
    return FALSE;
  }
  
  TCHAR guest_szFilePath[MAX_PATH];
  TCHAR host_szFilePath[MAX_PATH];
  
  _stprintf(host_szFilePath, _T("%s\\*.*"), hostDirectory);
  hFindFile = FindFirstFile(host_szFilePath, &wfd);
  while ( hFindFile != INVALID_HANDLE_VALUE )
  {
    if ( _tcscmp(wfd.cFileName, _T(".")) != 0 && _tcscmp(wfd.cFileName, _T("..")) != 0 )
    {
      _stprintf(guest_szFilePath, _T("%s\\%s"), guestDirectory, wfd.cFileName);
      _stprintf(host_szFilePath, _T("%s\\%s"), hostDirectory, wfd.cFileName);

      if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
      {
        bResult = CopyDirectoryFromGuestToHost(host_szFilePath, guest_szFilePath) && bResult;
      }
      else
      {
        bResult = CopyFileFromHostToGuest(host_szFilePath, guest_szFilePath);
      }
    }

    if ( !FindNextFile(hFindFile, &wfd) )
    {
      FindClose(hFindFile);
      hFindFile = INVALID_HANDLE_VALUE;
      break;
    }
  }

  return bResult;
}