#include #include #include #include static void printHelp(); static bool copyDirRecursively( const wchar_t *srcPath, const wchar_t *dstPath ); int main() { /* Get command line args in Unicode */ wchar_t *commandLine = GetCommandLineW(); int argc; wchar_t **commandLineArgs = CommandLineToArgvW( commandLine, &argc ); /* wprintf(L"argc=%d\n", argc); for (int i = 0; i < argc; ++i) { wprintf( L"argv[%d]=\"%ls\"\n", i, commandLineArgs[i] ); } */ if (argc < 3) { printHelp(); LocalFree(commandLineArgs); return 1; } DWORD attr = GetFileAttributesW(commandLineArgs[1]); if (attr == INVALID_FILE_ATTRIBUTES) { printf("Illegal source directory.\n"); LocalFree(commandLineArgs); return (-1); } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) { printf("Source is not a directory.\n"); LocalFree(commandLineArgs); return (-1); } attr = GetFileAttributesW(commandLineArgs[2]); if (attr == INVALID_FILE_ATTRIBUTES) { printf("Illegal destination directory.\n"); LocalFree(commandLineArgs); return (-1); } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) { printf("Destination is not a directory.\n"); LocalFree(commandLineArgs); return (-1); } if (!copyDirRecursively(commandLineArgs[1], commandLineArgs[2])) { LocalFree(commandLineArgs); return (-1); } LocalFree(commandLineArgs); return 0; } static void printHelp() { wprintf( L"Copy contents of a directory recursively.\n" "Usage:\n" "\trcopy sourceDir destinationDir\n" ); } static bool copyDirRecursively( const wchar_t *srcPath, const wchar_t *dstPath ) { DWORD attr = GetFileAttributesW(srcPath); if ( attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY) == 0 ) { return false; } attr = GetFileAttributesW(dstPath); if ( attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY) == 0 ) { return false; } wchar_t srcFile[MAX_PATH]; wcscpy(srcFile, srcPath); size_t len = wcslen(srcFile); if (len == 0) return false; if (srcFile[len-1] != L'\\' && srcFile[len-1] != L'/') wcscat(srcFile, L"\\"); int srcLen = wcslen(srcFile); wchar_t pattern[MAX_PATH]; wcscpy(pattern, srcFile); wcscat(pattern, L"*"); wchar_t dstFile[MAX_PATH]; wcscpy(dstFile, dstPath); len = wcslen(dstFile); if (len == 0) return false; if (dstFile[len-1] != L'\\' && dstFile[len-1] != L'/') wcscat(dstFile, L"\\"); size_t dstLen = wcslen(dstFile); WIN32_FIND_DATAW findData; HANDLE h; h = FindFirstFileW(pattern, &findData); while (h != INVALID_HANDLE_VALUE) { if ( wcscmp(findData.cFileName, L"..") != 0 && wcscmp(findData.cFileName, L".") != 0 ) { wcscpy(srcFile + srcLen, findData.cFileName); wcscpy(dstFile + dstLen, findData.cFileName); wprintf(L"%ls -> %ls\n", srcFile, dstFile); if ( (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ) { // Make subdirectory in destination directory if (!CreateDirectoryW( dstFile, NULL )) { DWORD err = GetLastError(); if (err != 0 && err != ERROR_ALREADY_EXISTS) { wprintf(L"Cannot create a directory, err=%d\n", err); return false; } } if (!copyDirRecursively( srcFile, dstFile )) { wprintf( L"Failed to copy subdirectory %ls\n", findData.cFileName ); return false; } } else { // Normal file if (!CopyFileW(srcFile, dstFile, FALSE)) { wprintf( L"Cannot copy the file %ls\n", findData.cFileName ); return false; } } } if (!FindNextFileW(h, &findData)) break; } FindClose(h); return true; }