Listing 1: The CBcopy utility

///////////////////////////////////////////////////
// CBCopy.cpp
///////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include <windows.h>
#include <io.h>
#include <direct.h>
 
void ProcessFile( char *file );
void ProcessDirectory( char *file );
 
int failIfExistsFlag=0, ignoreSubdirFlag=0;
int silentFlag=0, noCopyFlag=0;
unsigned long errorCount=0, copyCount=0;
char basePath[_MAX_PATH], destPath[_MAX_PATH];
long basePathSize;
 
int main( int argc, char *argv[] )
   {
// Get command-line arguments 
   for (int i=1; i<argc; i++)
       {
       if (stricmp(argv[i],"-d")==0)       // ignore sub-dir flag
          ignoreSubdirFlag=1;
       else if (stricmp(argv[i],"-s")==0) // silent mode
          silentFlag=1;
       else if (stricmp(argv[i],"-f")==0) // fail if exists flag
          failIfExistsFlag=1;
       else if (stricmp(argv[i],"-nc")==0) // no copy flag
          noCopyFlag=1;
       else if (stricmp(argv[i],"-?")==0)  // show usage
          {
          cout << endl;
          cout << "Usage: " << argv[0] 
               << "  {[-d | -s | -f | -nc]}" << endl;
          cout << endl;
          cout << "       -d   (do not copy subdirectories)" 
               << endl;
          cout << "       -s   (silent mode)" << endl;
          cout << "       -f   (fail if file already exists)" 
               << endl;
          cout << "       -nc  (do not copy files, just list)" 
               << endl;
          cout << "       -?   (show usage)" << endl;
          cout << endl;
          return 1;
          }
       }
 
// Get info from clipboard
   TCHAR file[_MAX_PATH];
   HGLOBAL temp;
 
   if (!OpenClipboard(NULL))
      {
      cout << "Unable to open clipboard." << endl;
      return 0; 
      }
 
   temp=GetClipboardData(CF_HDROP);
   if (temp==NULL)
      {
      cout << "No files in the clipboard." << endl;
      CloseClipboard();
      return 0;
      }
 
// store current dir as destination
   GetCurrentDirectory( _MAX_PATH, destPath ); 
 
// Process each file in the clipboard
   HDROP dp= (HDROP)GlobalLock(temp);
   UINT count = DragQueryFile(dp, (UINT)-1, NULL, 0);
   for (i=0; (UINT)i<count; i++)
       {
       DragQueryFile(dp, i, file, _MAX_PATH);
 
       if (i==0)  // Get base path of source files
          {
          char drive[_MAX_DRIVE];
          char dir[_MAX_DIR];
          char fname[_MAX_FNAME];
          char ext[_MAX_EXT];
 
          _splitpath( file, drive, dir, fname, ext );
          strcpy(basePath,drive);
          strcat(basePath,dir);
          basePathSize=strlen(basePath);
          }
 
       ProcessFile( file );
       }
 
   GlobalUnlock((void *)temp);
   CloseClipboard();
 
// Output Statistics
   cout << endl << "Files Copied: " << copyCount << endl;
   if (errorCount>0)
      cout << "Errors      : " << errorCount << endl;
 
   return 1;
   }
//-------------------------------------------------------------
void ProcessFile( char *file )
   {
   long attr=GetFileAttributes( file );
 
   if (attr & FILE_ATTRIBUTE_DIRECTORY) // see if it is a dir
      {
      if (ignoreSubdirFlag==0)
         ProcessDirectory( file );
      }
   else  // it is a file
      {
      char destination[_MAX_PATH];  // determine dest path
      strcpy(destination,destPath);
      strcat(destination,&file[basePathSize-1]);
 
      if (noCopyFlag==0) // then copy files
         {
         if (CopyFile(file,destination,failIfExistsFlag )==0)
            {
            cout << "*** Unable to copy file:" << endl;
            cout << "    source     : " << file << endl;
            cout << "    destination: " << destination << endl;
            errorCount++;
            }
         else  // copy was successful
            {
            if (silentFlag==0)
               cout << "Copied: " << file << endl;
            copyCount++;
            }
         }
      else // just list file
         {
         cout << file << endl;
         }
      }
   }
//-------------------------------------------------------------
void ProcessDirectory( char *file )
   {
// Make new subdirectory if necessary
   char newDirectory[_MAX_PATH];
   strcpy(newDirectory,destPath);
   strcat(newDirectory,&file[basePathSize-1]);
 
   if (noCopyFlag==0)
      {
      long stat=GetFileAttributes( newDirectory);
      if (stat==0xFFFFFFFF)
         {
         if (_mkdir(newDirectory)==-1)
            {
            cout << "Unable to create directory: " 
                 << newDirectory << endl;
            errorCount++;
            return;
            }
      }
   }
 
// Go through all of the files in the subdirectory
   struct _finddata_t c_file;
   long hFile;
   char searchPath[_MAX_PATH], newFile[_MAX_PATH];
 
   sprintf(searchPath,"%s\\*.*",file); // search for all 
                                       // files in dir
 
   if ((hFile = _findfirst( searchPath, &c_file ))!=-1L)    
      {
      if (strcmp(c_file.name,".")!=0 &&
          strcmp(c_file.name,"..")!=0)
          { 
          sprintf(newFile,"%s\\%s",file,c_file.name);
          ProcessFile( newFile);
          }
      }
   
   if (hFile!=-1)
      {
      while (_findnext(hFile,&c_file)==0)
            {
            if (strcmp(c_file.name,".")!=0 && 
                strcmp(c_file.name,"..")!=0)
                {
                sprintf(newFile,"%s\\%s",file,c_file.name);
                ProcessFile( newFile );
                }
            }
      _findclose(hFile);
      }
   }