#define _CRT_SECURE_NO_WARNINGS #define _CRT_NON_CONFORMING_SWPRINTFS #include #include LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("SymbolLink"); HWND hwnd; MSG msg; WNDCLASSEX wndclassex = {0}; wndclassex.cbSize = sizeof(WNDCLASSEX); wndclassex.style = CS_HREDRAW | CS_VREDRAW; wndclassex.lpfnWndProc = WndProc; wndclassex.cbClsExtra = 0; wndclassex.cbWndExtra = 0; wndclassex.hInstance = hInstance; wndclassex.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclassex.hCursor = LoadCursor (NULL, IDC_ARROW); wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclassex.lpszMenuName = NULL; wndclassex.lpszClassName = szAppName; wndclassex.hIconSm = wndclassex.hIcon; if (!RegisterClassEx (&wndclassex)) { MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW, szAppName, TEXT ("SymbolLink"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); //ShowWindow (hwnd, iCmdShow); //UpdateWindow (hwnd); while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage (&msg); } return (int)msg.wParam; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: { TCHAR *psz_cmmnd_line = GetCommandLine(); if (psz_cmmnd_line == NULL) { MessageBox(hwnd, _T("Wrong parameters!"), _T("SymbolLink Error"), MB_OK); return -1; } int n_count = 0; WCHAR **psz_arg_list = CommandLineToArgvW(psz_cmmnd_line, &n_count); if (psz_arg_list == NULL) { MessageBox(hwnd, _T("Failed to parse parameters!"), _T("SymbolLink Error"), MB_OK); return -1; } if (n_count != 3 && n_count != 2) { MessageBox(hwnd, _T("Wrong parameters!\nUsage: symbollink [source] link"), _T("SymbolLink Error"), MB_OK); LocalFree(psz_arg_list); return -1; } // what type the source is DWORD dwAttr = GetFileAttributes(psz_arg_list[1]); if (dwAttr == INVALID_FILE_ATTRIBUTES) { int n_err_msg_len = 60 + _tcslen(psz_arg_list[1]); TCHAR *psz_err_msg = new TCHAR[n_err_msg_len]; _stprintf(psz_err_msg, _T("Failed to get attributes\nfor %s"), psz_arg_list[1]); MessageBox(hwnd, psz_err_msg, _T("SymbolLink Error"), MB_OK); LocalFree(psz_arg_list); delete [] psz_err_msg; return -1; } if ((dwAttr & FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT) { // delete symbolic link WIN32_FIND_DATA wfd; ZeroMemory(&wfd, sizeof(WIN32_FIND_DATA)); HANDLE hFile = FindFirstFile(psz_arg_list[1], &wfd); FindClose(hFile); if (wfd.dwReserved0 == IO_REPARSE_TAG_SYMLINK) { if ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { RemoveDirectory(psz_arg_list[1]); } else { DeleteFile(psz_arg_list[1]); } } } else { // // create symbolic link // // get the link name from source TCHAR *psz_link_name = _tcsrchr(psz_arg_list[1], _T('\\')); if (psz_link_name == NULL) { int n_err_msg_len = 60 + _tcslen(psz_arg_list[1]); TCHAR *psz_err_msg = new TCHAR[n_err_msg_len]; _stprintf(psz_err_msg, _T("Failed to get name\nfrom %s"), psz_arg_list[1]); MessageBox(hwnd, psz_err_msg, _T("SymbolLink Error"), MB_OK); LocalFree(psz_arg_list); delete [] psz_err_msg; return -1; } // skip slash psz_link_name++; // append the link name to target/link path int n_link_path_len = _tcslen(psz_arg_list[2]) + _tcslen(psz_link_name) + 8; TCHAR *psz_link_path = new TCHAR[n_link_path_len]; _stprintf(psz_link_path, _T("%s\\%s"), psz_arg_list[2], psz_link_name); DWORD dw_flag = ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) ? 0x1 : 0x0; if (!CreateSymbolicLink(psz_link_path, psz_arg_list[1], dw_flag)) { DWORD dwError = GetLastError(); TCHAR sz_error_buf[MAX_PATH * 10] = _T(""); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, 0, sz_error_buf, MAX_PATH * 10, NULL); int n_err_msg_len = 60 + _tcslen(psz_link_path) + _tcslen(psz_arg_list[1]) + _tcslen(sz_error_buf); TCHAR *psz_err_msg = new TCHAR[n_err_msg_len]; _stprintf(psz_err_msg, _T("Failed to create symobl link\nfrom %s\nto %s\nCause: %s"), psz_arg_list[1], psz_link_path, sz_error_buf); MessageBox(hwnd, psz_err_msg, _T("SymbolLink Error"), MB_OK); delete [] psz_err_msg; delete [] psz_link_path; LocalFree(psz_arg_list); return -1; } delete [] psz_link_path; } LocalFree(psz_arg_list); DestroyWindow(hwnd); //CreateSymbolicLink() } return (0); case WM_DESTROY: PostQuitMessage (0); return (0); } return DefWindowProc (hwnd, message, wParam, lParam); }