void write_argument_path (char *path, int len) { assert(arg_writing); assert(len >= 0); if (len == 0) { return; } // cmake is broken and may give gives unix style paths with backshashes char *fixed = HeapAlloc(GetProcessHeap(), 0, len + 1); if (!fixed) { fail("HeapAlloc failed"); } int i; for (i = 0; i < len; i++) { if (path[i] == '\\') { fixed[i] = '/'; } else { fixed[i] = path[i]; } } fixed[i] = '\0'; // convert to windows path WCHAR *conv_path = wine_get_dos_file_name_ptr(fixed); if (!conv_path) { fail("cannot convert path"); } write_argument_w(conv_path, wcslen(conv_path)); HeapFree(GetProcessHeap(), 0, fixed); HeapFree(GetProcessHeap(), 0, conv_path); }
/* * Main function */ int wmain(int argc, WCHAR *argv[]) { LPSTR (*CDECL wine_get_unix_file_name_ptr)(LPCWSTR) = NULL; LPWSTR (*CDECL wine_get_dos_file_name_ptr)(LPCSTR) = NULL; WCHAR dos_pathW[MAX_PATH]; char path[MAX_PATH]; int outputformats; int i; outputformats = parse_options(argv); if (outputformats == 0) outputformats = UNIXFORMAT; if (outputformats & UNIXFORMAT) { wine_get_unix_file_name_ptr = (void*) GetProcAddress(GetModuleHandleA("KERNEL32"), "wine_get_unix_file_name"); if (wine_get_unix_file_name_ptr == NULL) { fprintf(stderr, "%s: cannot get the address of " "'wine_get_unix_file_name'\n", progname); exit(3); } } if (outputformats & WINDOWSFORMAT) { wine_get_dos_file_name_ptr = (void*) GetProcAddress(GetModuleHandleA("KERNEL32"), "wine_get_dos_file_name"); if (wine_get_dos_file_name_ptr == NULL) { fprintf(stderr, "%s: cannot get the address of " "'wine_get_dos_file_name'\n", progname); exit(3); } } for (i = 1; argv[i]; i++) { *path='\0'; if (outputformats & LONGFORMAT) { if (GetLongPathNameW(argv[i], dos_pathW, MAX_PATH)) WideCharToMultiByte(CP_UNIXCP, 0, dos_pathW, -1, path, MAX_PATH, NULL, NULL); printf("%s\n", path); } if (outputformats & SHORTFORMAT) { if (GetShortPathNameW(argv[i], dos_pathW, MAX_PATH)) WideCharToMultiByte(CP_UNIXCP, 0, dos_pathW, -1, path, MAX_PATH, NULL, NULL); printf("%s\n", path); } if (outputformats & UNIXFORMAT) { WCHAR *ntpath, *tail; int ntpathlen=lstrlenW(argv[i]); ntpath=HeapAlloc(GetProcessHeap(), 0, sizeof(*ntpath)*(ntpathlen+1)); lstrcpyW(ntpath, argv[i]); tail=NULL; while (1) { char *unix_name; WCHAR *slash, *c; unix_name = wine_get_unix_file_name_ptr(ntpath); if (unix_name) { if (tail) { WideCharToMultiByte(CP_UNIXCP, 0, tail+1, -1, path, MAX_PATH, NULL, NULL); printf("%s/%s\n", unix_name, path); } else { printf("%s\n", unix_name); } HeapFree( GetProcessHeap(), 0, unix_name ); break; } slash=(tail ? tail : ntpath+ntpathlen); while (slash != ntpath && *slash != '/' && *slash != '\\') slash--; if (slash == ntpath) { /* This is a complete path conversion failure. * It would typically happen if ntpath == "". */ printf("\n"); break; } c=slash+1; while (*c != '\0' && *c != '*' && *c != '?' && *c != '<' && *c != '>' && *c != '|' && *c != '"') c++; if (*c != '\0') { /* If this is not a valid NT path to start with, * then obviously we cannot convert it. */ printf("\n"); break; } if (tail) *tail='/'; tail=slash; *tail='\0'; } HeapFree(GetProcessHeap(), 0, ntpath); } if (outputformats & WINDOWSFORMAT) { WCHAR* windows_name; char* unix_name; DWORD size; size=WideCharToMultiByte(CP_UNIXCP, 0, argv[i], -1, NULL, 0, NULL, NULL); unix_name=HeapAlloc(GetProcessHeap(), 0, size); WideCharToMultiByte(CP_UNIXCP, 0, argv[i], -1, unix_name, size, NULL, NULL); if ((windows_name = wine_get_dos_file_name_ptr(unix_name))) { WideCharToMultiByte(CP_UNIXCP, 0, windows_name, -1, path, MAX_PATH, NULL, NULL); printf("%s\n", path); HeapFree( GetProcessHeap(), 0, windows_name ); } else printf( "\n" ); HeapFree( GetProcessHeap(), 0, unix_name ); } } exit(0); }
int wmain (int argc, WCHAR *argv[]) { SHELLEXECUTEINFOW sei; WCHAR *args = NULL; int i; int unix_mode = 0; int progid_open = 0; WCHAR *dos_filename = NULL; WCHAR *parent_directory = NULL; DWORD binary_type; static const WCHAR openW[] = { 'o', 'p', 'e', 'n', 0 }; static const WCHAR unixW[] = { 'u', 'n', 'i', 'x', 0 }; static const WCHAR progIDOpenW[] = { 'p', 'r', 'o', 'g', 'I', 'D', 'O', 'p', 'e', 'n', 0}; memset(&sei, 0, sizeof(sei)); sei.cbSize = sizeof(sei); sei.lpVerb = openW; sei.nShow = SW_SHOWNORMAL; /* Dunno what these mean, but it looks like winMe's start uses them */ sei.fMask = SEE_MASK_FLAG_DDEWAIT| SEE_MASK_FLAG_NO_UI| SEE_MASK_NO_CONSOLE; /* Canonical Microsoft commandline flag processing: * flags start with /, are case insensitive, * and may be run together in same word. */ for (i=1; i<argc; i++) { int ci; if (argv[i][0] != '/') break; /* Unix paths can start with / so we have to assume anything following /U is not a flag */ if (unix_mode || progid_open) break; /* Handle all options in this word */ for (ci=0; argv[i][ci]; ) { /* Skip slash */ ci++; switch(argv[i][ci]) { case 'b': case 'B': break; /* FIXME: should stop new window from being created */ case 'i': case 'I': break; /* FIXME: should ignore any changes to current environment */ case 'l': case 'L': license(); break; /* notreached */ case 'm': case 'M': if (argv[i][ci+1] == 'a' || argv[i][ci+1] == 'A') sei.nShow = SW_SHOWMAXIMIZED; else sei.nShow = SW_SHOWMINIMIZED; break; case 'r': case 'R': /* sei.nShow = SW_SHOWNORMAL; */ break; case 'u': case 'U': if (strncmpiW(&argv[i][ci], unixW, 4) == 0) unix_mode = 1; else { WINE_ERR("Option '%s' not recognized\n", wine_dbgstr_w( argv[i]+ci-1)); usage(); } break; case 'p': case 'P': if (strncmpiW(&argv[i][ci], progIDOpenW, 17) == 0) progid_open = 1; else { WINE_ERR("Option '%s' not recognized\n", wine_dbgstr_w( argv[i]+ci-1)); usage(); } break; case 'w': case 'W': sei.fMask |= SEE_MASK_NOCLOSEPROCESS; break; default: WINE_ERR("Option '%s' not recognized\n", wine_dbgstr_w( argv[i]+ci-1)); usage(); } /* Skip to next slash */ while (argv[i][ci] && (argv[i][ci] != '/')) ci++; } } if (i == argc) usage(); if (progid_open) { sei.lpClass = argv[i++]; sei.fMask |= SEE_MASK_CLASSNAME; } sei.lpFile = argv[i++]; args = build_args( argc - i, &argv[i] ); sei.lpParameters = args; if (unix_mode || progid_open) { LPWSTR (*CDECL wine_get_dos_file_name_ptr)(LPCSTR); char* multibyte_unixpath; int multibyte_unixpath_len; wine_get_dos_file_name_ptr = (void*)GetProcAddress(GetModuleHandleA("KERNEL32"), "wine_get_dos_file_name"); if (!wine_get_dos_file_name_ptr) fatal_string(STRING_UNIXFAIL); multibyte_unixpath_len = WideCharToMultiByte(CP_UNIXCP, 0, sei.lpFile, -1, NULL, 0, NULL, NULL); multibyte_unixpath = HeapAlloc(GetProcessHeap(), 0, multibyte_unixpath_len); WideCharToMultiByte(CP_UNIXCP, 0, sei.lpFile, -1, multibyte_unixpath, multibyte_unixpath_len, NULL, NULL); dos_filename = wine_get_dos_file_name_ptr(multibyte_unixpath); HeapFree(GetProcessHeap(), 0, multibyte_unixpath); if (!dos_filename) fatal_string(STRING_UNIXFAIL); sei.lpFile = dos_filename; sei.lpDirectory = parent_directory = get_parent_dir(dos_filename); sei.fMask &= ~SEE_MASK_FLAG_NO_UI; if (GetBinaryTypeW(sei.lpFile, &binary_type)) { WCHAR *commandline; STARTUPINFOW startup_info; PROCESS_INFORMATION process_information; static WCHAR commandlineformat[] = {'"','%','s','"','%','s',0}; /* explorer on windows always quotes the filename when running a binary on windows (see bug 5224) so we have to use CreateProcessW in this case */ commandline = HeapAlloc(GetProcessHeap(), 0, (strlenW(sei.lpFile)+3+strlenW(sei.lpParameters))*sizeof(WCHAR)); sprintfW(commandline, commandlineformat, sei.lpFile, sei.lpParameters); ZeroMemory(&startup_info, sizeof(startup_info)); startup_info.cb = sizeof(startup_info); if (!CreateProcessW( NULL, /* lpApplicationName */ commandline, /* lpCommandLine */ NULL, /* lpProcessAttributes */ NULL, /* lpThreadAttributes */ FALSE, /* bInheritHandles */ CREATE_NEW_CONSOLE, /* dwCreationFlags */ NULL, /* lpEnvironment */ sei.lpDirectory, /* lpCurrentDirectory */ &startup_info, /* lpStartupInfo */ &process_information /* lpProcessInformation */ )) { fatal_string_error(STRING_EXECFAIL, GetLastError(), sei.lpFile); } sei.hProcess = process_information.hProcess; goto done; } } if (!ShellExecuteExW(&sei)) fatal_string_error(STRING_EXECFAIL, GetLastError(), sei.lpFile); done: HeapFree( GetProcessHeap(), 0, args ); HeapFree( GetProcessHeap(), 0, dos_filename ); HeapFree( GetProcessHeap(), 0, parent_directory ); if (sei.fMask & SEE_MASK_NOCLOSEPROCESS) { DWORD exitcode; WaitForSingleObject(sei.hProcess, INFINITE); GetExitCodeProcess(sei.hProcess, &exitcode); ExitProcess(exitcode); } ExitProcess(0); }