// (C) 2016 Intel Deutschland GmbH // Author: Michael Soegtrop // Released to the public under CC0 // See https://creativecommons.org/publicdomain/zero/1.0/ // Windows drop in repacement for Linux ln // Supports command form "ln TARGET LINK_NAME" // Supports -s and -f options // Does not support hard links to folders (but symlinks are ok) #include #include #include // Cygwin MinGW doesn't have this Vista++ function in windows.h #ifdef UNICODE WINBASEAPI BOOLEAN APIENTRY CreateSymbolicLinkW ( LPCWSTR, LPCWSTR, DWORD ); #define CreateSymbolicLink CreateSymbolicLinkW #define CommandLineToArgv CommandLineToArgvW #else WINBASEAPI BOOLEAN APIENTRY CreateSymbolicLinkA ( LPCSTR, LPCSTR, DWORD ); #define CreateSymbolicLink CreateSymbolicLinkA #define CommandLineToArgv CommandLineToArgvA #endif #define SYMBOLIC_LINK_FLAG_DIRECTORY 1 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLineA, int nShowCmd ) { int iarg; BOOL symbolic = FALSE; BOOL force = FALSE; BOOL folder; const _TCHAR *target; const _TCHAR *link; LPTSTR lpCmdLine; int argc; LPTSTR *argv; // Parse command line // This is done explicitly here for two reasons // 1.) MinGW doesn't seem to support _tmain, wWinMain and the like // 2.) We want to make sure that CommandLineToArgv is used lpCmdLine = GetCommandLine(); argv = CommandLineToArgv( lpCmdLine, &argc ); // Get target and link name if( argc<3 ) { _ftprintf( stderr, _T("Expecting at least 2 arguments, got %d\n"), argc-1 ); return 1; } target = argv[argc-2]; link = argv[argc-1]; // Parse options // The last two arguments are interpreted as file names // All other arguments must be -s or -f os multi letter options like -sf for(iarg=1; iarg '%s'!\n"), link, target ); return 1; } } else { if( folder ) { _ftprintf( stderr, _T("Cannot create hard link to folder") ); return 1; } else { if( !CreateHardLink( link, target, NULL ) ) { _ftprintf( stderr, _T("Error creating hard link '%s' -> '%s'!\n"), link, target ); return 1; } } } // Everything is fine return 0; }