diff options
| author | Simon Rettberg | 2016-03-14 15:10:07 +0100 |
|---|---|---|
| committer | Simon Rettberg | 2016-03-14 15:10:07 +0100 |
| commit | 4228b42680d139afc64717b84c6544dc4c609aa9 (patch) | |
| tree | 8b71dd9a272c43fc1e0115ce5044ee1d777dc2c8 /remote | |
| parent | [run-virt] Fix mapping of drive letter, shortcut on desktop (diff) | |
| download | tm-scripts-4228b42680d139afc64717b84c6544dc4c609aa9.tar.gz tm-scripts-4228b42680d139afc64717b84c6544dc4c609aa9.tar.xz tm-scripts-4228b42680d139afc64717b84c6544dc4c609aa9.zip | |
[run-virt] More progress on openslx.exe
Diffstat (limited to 'remote')
| -rw-r--r-- | remote/modules/run-virt/data/opt/openslx/scripts/includes/setup_virtual_floppy.inc | 26 | ||||
| -rw-r--r-- | remote/modules/run-virt/data/opt/openslx/scripts/pam_script_auth.d/99-run_virt_credentials | 8 | ||||
| -rwxr-xr-x | remote/modules/run-virt/data/opt/openslx/vmchooser/data/openslx.exe | bin | 52224 -> 57344 bytes | |||
| -rw-r--r-- | remote/modules/run-virt/winres.c | 349 |
4 files changed, 300 insertions, 83 deletions
diff --git a/remote/modules/run-virt/data/opt/openslx/scripts/includes/setup_virtual_floppy.inc b/remote/modules/run-virt/data/opt/openslx/scripts/includes/setup_virtual_floppy.inc index d1343700..2fdebf4c 100644 --- a/remote/modules/run-virt/data/opt/openslx/scripts/includes/setup_virtual_floppy.inc +++ b/remote/modules/run-virt/data/opt/openslx/scripts/includes/setup_virtual_floppy.inc @@ -14,9 +14,26 @@ mkfs.fat "${FLOPPYIMG}" || mkfs.vfat "${FLOPPYIMG}" || mkdosfs "${FLOPPYIMG}" # via virtual floppy #mcopy -i "${FLOPPYIMG}" "$xmlfile" "::/config.xml" -# Create file with resolution information -xrandr | grep -o -E 'connected\s*(primary)?\s*[0-9]+x[0-9]+\+0\+0' \ - | grep -o -E -m1 '[0-9]+x[0-9]+' > "${TMPDIR}/hostres.txt" +# Create file with resolution information etc. +. "/opt/openslx/inc/shares" +[ -z "$SHARE_REMAP_MODE" ] && SHARE_REMAP_MODE="1" +[ -z "$SHARE_CREATE_MISSING_REMAP" ] && SHARE_CREATE_MISSING_REMAP="1" +RESOLUTION=$(xrandr | grep -o -E 'connected\s*(primary)?\s*[0-9]+x[0-9]+\+0\+0' \ + | grep -o -E -m1 '[0-9]+x[0-9]+') + +cat > "${TMPDIR}/geraffel.ini" <<-HIER +[openslx] +resolution=${RESOLUTION} +createMissingRemap=${SHARE_CREATE_MISSING_REMAP} +remapMode=${SHARE_REMAP_MODE} + +[remap] +documents=${SHARE_DOCUMENTS} +downloads=${SHARE_DOWNLOADS} +desktop=${SHARE_DESKTOP} +media=${SHARE_MEDIA} +other=${SHARE_OTHER} +HIER # Create file for network shares to mount SHARES="${TMPDIR}/shares.dat" @@ -36,8 +53,9 @@ if pwdaemon --query "${TMPHOME}/.pwsocket" > "${SHARES}"; then fi # Copy all them files into floppy image -mcopy -i "${FLOPPYIMG}" "${TMPDIR}/hostres.txt" "::/" +mcopy -i "${FLOPPYIMG}" "${TMPDIR}/geraffel.ini" "::/" mcopy -i "${FLOPPYIMG}" "$VMCHOOSER_DIR/data/openslx.exe" "::/" mcopy -i "${FLOPPYIMG}" "${SHARES}" "::/" +rm -f -- "${SHARES}" unset SHARES VAR NETHOME diff --git a/remote/modules/run-virt/data/opt/openslx/scripts/pam_script_auth.d/99-run_virt_credentials b/remote/modules/run-virt/data/opt/openslx/scripts/pam_script_auth.d/99-run_virt_credentials index 1e2c18e7..a03d8886 100644 --- a/remote/modules/run-virt/data/opt/openslx/scripts/pam_script_auth.d/99-run_virt_credentials +++ b/remote/modules/run-virt/data/opt/openslx/scripts/pam_script_auth.d/99-run_virt_credentials @@ -18,17 +18,19 @@ if [ -n "$TEMP_HOME_DIR" ]; then [ -z "$XUSER" ] && XUSER="${PAM_USER}" # Guess domain XDOMAIN= - if [ -n "$PERSISTENT_OK" ]; then + if [ -n "$PERSISTENT_HOME_DIR" ]; then XDOMAIN=$(grep -F " ${PERSISTENT_HOME_DIR} " "/proc/mounts" | grep -m1 -F 'domain=' | sed -r 's/^.*[ ,]domain=([^ ,]+)[ ,].*$/\1/g') fi if [ -z "$XDOMAIN" ]; then - XDOMAIN=$(grep -m1 -i '^BASE\s*DC=' "/etc/ldap.conf" | sed -r 's/^BASE\s*DC=([^,;]+)[,;].*$/\1/I') + XDOMAIN=$(grep -m1 -i '^BASE\s*DC=' "/etc/ldap.conf" | sed -r 's/^BASE\s*DC=([^,;]+).*$/\1/I') fi if [ -z "$XDOMAIN" ]; then - XDOMAIN=$(grep -m1 -i '^ldap_search_base\s*=' "/etc/sssd/sssd.conf" | sed -r 's/^ldap_search_base\s*=\s*DC=([^,;]+)[,;].*$/\1/I') + XDOMAIN=$(grep -m1 -i '^ldap_search_base\s*=\s*DC=' "/etc/sssd/sssd.conf" | sed -r 's/^ldap_search_base\s*=\s*DC=([^,;]+).*$/\1/I') fi if [ -n "$XDOMAIN" ]; then XDOMAIN=$(echo "$XDOMAIN" | tr '[a-z]' '[A-Z]') + else + XDOMAIN="WORKGROUP" fi USERNAME="$XDOMAIN\\$XUSER" PASSWORD="$PAM_AUTHTOK" PWSOCKET="${TEMP_HOME_DIR}/.pwsocket" su -c 'pwdaemon --daemon &' "${PAM_USER}" & unset XUSER XDOMAIN diff --git a/remote/modules/run-virt/data/opt/openslx/vmchooser/data/openslx.exe b/remote/modules/run-virt/data/opt/openslx/vmchooser/data/openslx.exe Binary files differindex 39928c92..7b71ba90 100755 --- a/remote/modules/run-virt/data/opt/openslx/vmchooser/data/openslx.exe +++ b/remote/modules/run-virt/data/opt/openslx/vmchooser/data/openslx.exe diff --git a/remote/modules/run-virt/winres.c b/remote/modules/run-virt/winres.c index 54c0ad1b..e4fce258 100644 --- a/remote/modules/run-virt/winres.c +++ b/remote/modules/run-virt/winres.c @@ -20,6 +20,7 @@ #include <shlobj.h> #include <shlguid.h> #include <strsafe.h> +#include <tlhelp32.h> DEFINE_GUID(ID_IAudioEndpointVolume, 0x5CDF2C82, 0x841E, 0x4546, 0x97, 0x22, 0x0C, 0xF7, 0x40, 0x78, 0x22, 0x9A); DEFINE_GUID(ID_IMMDeviceEnumerator, 0xa95664d2, 0x9614, 0x4f35, 0xa7,0x46, 0xde,0x8d,0xb6,0x36,0x17,0xe6); @@ -39,11 +40,32 @@ typedef struct { static const ssize_t KEYLEN = 16; #define DRIVEMAX (100) #define LOGFILELEN (300) +#define SETTINGS_FILE "B:\\GERAFFEL.INI" +#define SETTINGS_FILE_W L"B:\\GERAFFEL.INI" static BOOL bGetShares = FALSE; static netdrive_t drives[DRIVEMAX]; static wchar_t desktopPath[MAX_PATH+1], tempPath[MAX_PATH+1], programsPath[MAX_PATH+1], windowsPath[MAX_PATH+1]; static wchar_t logFile[LOGFILELEN]; +static DWORD _startTime; +#define FS_UNKNOWN (-1) +#define FS_ERROR (0) +#define FS_OK (1) +static int _folderStatus = FS_UNKNOWN; // -1 = Not handled yet, 0 = patching failed, 1 = remapped ok +#define RM_NONE (0) +#define RM_NATIVE (1) +#define RM_NATIVE_FALLBACK (2) +#define RM_VMWARE (3) +static int _remapMode = RM_NONE; + +struct { + BOOL documents; + BOOL downloads; + BOOL desktop; + BOOL media; + BOOL other; +} remap; +static BOOL _createMissingRemap = FALSE; static int setResolution(); static int muteSound(); @@ -52,6 +74,9 @@ static void readShareFile(); static BOOL mountNetworkShares(); static int queryPasswordDaemon(); static BOOL fileExists(wchar_t* szPath); +static BOOL folderExists(wchar_t* szPath); +static void patchUserPaths(wchar_t *letter); +static void remapViaSharedFolder(); static HRESULT createFolderShortcut(wchar_t* sTargetfile, wchar_t* sLinkfile, wchar_t* comment); @@ -73,17 +98,30 @@ static void alog(const char *fmt, ...) fclose(f); } -/* static void wlog(const wchar_t *fmt, ...) { - char buffer[1000]; - if (MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)suser, -1, (LPWSTR)nuser, BUFLEN) == 0) - return; -} -*/ + wchar_t wbuffer[1000]; + char abuffer[1000]; + va_list args; + FILE *f = _wfopen(logFile, L"a+"); + if (f == NULL) return; + time_t raw = time(NULL); + struct tm *tinf; + tinf = localtime(&raw); + strftime(abuffer, 1000, "%I:%M:%S ", tinf); + fputs(abuffer, f); -// TODO: Figure out if no timers are running anymore so we can quit + va_start(args, fmt); + StringCchVPrintfW(wbuffer, 1000, fmt, args); + va_end(args); + if (WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, abuffer, 1000, NULL, NULL) == 0) { + snprintf(abuffer, 1000, "Cannot wlog: widechar to utf8 failed."); + } + fputs(abuffer, f); + fputc('\n', f); + fclose(f); +} static void CALLBACK resetShutdown(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { @@ -114,22 +152,40 @@ static void CALLBACK setupNetworkDrives(HWND hWnd, UINT uMsg, UINT_PTR idEvent, if (bInProc) return; bInProc = TRUE; - int ret = queryPasswordDaemon(); - if (ret != 0) { - if (++fails < 10) - goto exit_func; - alog("queryPasswordDaemon returned %d", ret); + if (!bGetShares && (_remapMode == RM_NATIVE_FALLBACK || _remapMode == RM_VMWARE)) { + remapViaSharedFolder(); } else { - if (!mountNetworkShares() && ++fails < 15) - goto exit_func; + int ret = queryPasswordDaemon(); + if (ret != 0) { + if (++fails < 10) + goto exit_func; + alog("queryPasswordDaemon returned %d", ret); + } else { + if (!mountNetworkShares()) { + if (GetTickCount() - _startTime < 30000 && ++fails < 15) + goto exit_func; + } + } + // Finished successfully or failed completely + if (_folderStatus != FS_OK) { + remapViaSharedFolder(); + } } KillTimer(hWnd, idEvent); + if (_remapMode != RM_NONE) { + if (_folderStatus == FS_ERROR) { + MessageBoxA(NULL, "Fehler beim Einbinden des Home-Verzeichnisses. Bitte nichts Wichtiges in der VM speichern, sondern z.B. einen USB-Stick verwenden.", "Warnung", MB_ICONERROR); + } else if (_folderStatus == FS_UNKNOWN) { + MessageBoxA(NULL, "Kein Home-Verzeichnis gefunden. Bitte nichts Wichtiges in der VM speichern, sondern z.B. einen USB-Stick verwenden.", "Warnung", MB_ICONERROR); + } + } exit_func: bInProc = FALSE; } static void loadPaths() { + // Determine a couple of default directories if (SHGetFolderPathW(HWND_DESKTOP, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, programsPath) != S_OK) { DWORD ret = GetEnvironmentVariableW(L"ProgramFiles", programsPath, MAX_PATH+1); if (ret == 0 || ret > MAX_PATH) { @@ -162,6 +218,14 @@ static void loadPaths() _wremove(logFile); } } + // Read settings from ini file + remap.documents = GetPrivateProfileIntA("remap", "documents", 1, SETTINGS_FILE) != 0; + remap.downloads = GetPrivateProfileIntA("remap", "downloads", 1, SETTINGS_FILE) != 0; + remap.desktop = GetPrivateProfileIntA("remap", "desktop", 0, SETTINGS_FILE) != 0; + remap.media = GetPrivateProfileIntA("remap", "media", 1, SETTINGS_FILE) != 0; + remap.other = GetPrivateProfileIntA("remap", "other", 0, SETTINGS_FILE) != 0; + _createMissingRemap = GetPrivateProfileIntA("openslx", "createMissingRemap", 1, SETTINGS_FILE) != 0; + _remapMode = GetPrivateProfileIntA("openslx", "remapMode", RM_NATIVE_FALLBACK, SETTINGS_FILE); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) @@ -170,6 +234,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine version.dwOSVersionInfoSize = sizeof(version); BOOL retVer = GetVersionEx(&version); CoInitialize(NULL); + _startTime = GetTickCount(); loadPaths(); // Mute sound by default if (retVer && version.dwMajorVersion >= 6) @@ -184,8 +249,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } // Any network shares to mount? readShareFile(); - if (bGetShares) { - UINT_PTR tRet = SetTimer(NULL, 0, 2550, (TIMERPROC)&setupNetworkDrives); + if (bGetShares || _remapMode != RM_NONE) { + UINT_PTR tRet = SetTimer(NULL, 0, 1550, (TIMERPROC)&setupNetworkDrives); if (tRet == 0) { alog("Could not create timer for mounting network shares: %d", (int)GetLastError()); } @@ -194,13 +259,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine if (retVer && version.dwMajorVersion == 6 && version.dwMinorVersion == 1) { // Only on Windows 7 // Repeatedly set caption - UINT_PTR tRet = SetTimer(NULL, 0, 5030, (TIMERPROC)&resetShutdown); + UINT_PTR tRet = SetTimer(NULL, 0, 5230, (TIMERPROC)&resetShutdown); if (tRet == 0) { alog("Could not create timer for shutdown button: %d", (int)GetLastError()); } } // Resolution - if (fileExists(L"B:\\hostres.txt") && setResolution() != 0) { + if (fileExists(SETTINGS_FILE_W) && setResolution() != 0) { UINT_PTR tRet = SetTimer(NULL, 0, 3111, (TIMERPROC)&tmrResolution); if (tRet == 0) { alog("Could not create timer for resolution setting: %d", (int)GetLastError()); @@ -218,7 +283,40 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine static BOOL fileExists(wchar_t* szPath) { DWORD dwAttrib = GetFileAttributesW(szPath); - return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); + return (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY) == 0); +} + +static BOOL folderExists(wchar_t* szPath) +{ + DWORD dwAttrib = GetFileAttributesW(szPath); + return (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY) != 0); +} + +static int execute(wchar_t *path, wchar_t *arguments) +{ + STARTUPINFOW si; + PROCESS_INFORMATION pi; + ZeroMemory(&si, sizeof(si)); + ZeroMemory(&pi, sizeof(pi)); + si.cb = sizeof(si); + if (!CreateProcessW(path, arguments, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { + return -1; + } + while (MsgWaitForMultipleObjects(1, &pi.hProcess, FALSE, INFINITE, QS_SENDMESSAGE) == WAIT_OBJECT_0+1) { + MSG Msg; + while(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE)) { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + } + DWORD exitCode; + BOOL ret = GetExitCodeProcess(pi.hProcess, &exitCode); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + if (!ret) { + return -2; + } + return (int)exitCode; } static int setResolution() @@ -227,24 +325,18 @@ static int setResolution() static int width = 0, height = 0; if (width == 0 && height == 0) { // use config file in floppy - FILE *h = fopen("B:\\hostres.txt", "rb"); - if (h == NULL) { - alog("b:\\hostres.txt not found"); - return 0; - } char data[200] = ""; - fread(data, 200, 1, h); - fclose(h); + GetPrivateProfileStringA("openslx", "resolution", "", data, sizeof(data), SETTINGS_FILE); char *x = strchr(data, 'x'); if (x == NULL) { - alog("Malformed resolution in hostres.txt: '%s'", data); + alog("Malformed resolution in " SETTINGS_FILE ": '%s'", data); return 0; } *x++ = '\0'; width = atoi(data); height = atoi(x); if (width < 320 || height < 240) { - alog("Invalid resolution in hostres.txt: '%s' (parsed width=%d, height=%d)", data, width, height); + alog("Invalid resolution in " SETTINGS_FILE ": '%s' (parsed width=%d, height=%d)", data, width, height); return 0; } } @@ -266,26 +358,13 @@ static int setResolution() } } if (path[0] != 0 && fileExists(path)) { - STARTUPINFOW si; - PROCESS_INFORMATION pi; wchar_t cmdline[MAX_PATH]; - ZeroMemory(&si, sizeof(si)); - ZeroMemory(&pi, sizeof(pi)); - si.cb = sizeof(si); StringCchPrintfW(cmdline, MAX_PATH, L"VMwareResolutionSet.exe 0 1 , 0 0 %d %d", width, height); - if (CreateProcessW(path, cmdline, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { - WaitForSingleObject(pi.hProcess, INFINITE); - DWORD exitCode; - BOOL ret = GetExitCodeProcess(pi.hProcess, &exitCode); - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - if (ret && exitCode == 0) { - return 0; - } - alog("vmware res set executed but failed (ret %d, code %d, lasterror %d)", - (int)ret, (int)exitCode, (int)GetLastError()); - } else { - alog("createprocess for vmware res set failed with code %d", (int)GetLastError()); + int ret = execute(path, cmdline); + if (ret == -1) { + alog("VmwareRes: CreateProcess failed (%d)", (int)GetLastError()); + } else if (ret == -2) { + alog("VmwareRes: GetExitCode failed (%d)", (int)GetLastError()); } } // Use WinAPI as fallback @@ -518,6 +597,7 @@ static void udpReceived(SOCKET sock) // Success spass = xorString(buffer + 2, len, bkey2); closesocket(sock); + mountNetworkShares(); } #define BUFLEN (200) @@ -526,20 +606,22 @@ static DWORD mount(LPNETRESOURCEW share, LPWSTR pass, LPWSTR user) { DWORD retval; // Now try to mount - retval = WNetAddConnection2W(share, pass, user, CONNECT_TEMPORARY | CONNECT_CURRENT_MEDIA); - if (retval == NO_ERROR) { - return retval; - } - if (retval != ERROR_INVALID_PASSWORD && retval != ERROR_LOGON_FAILURE - && retval != ERROR_BAD_USERNAME && retval != ERROR_ACCESS_DENIED - && retval != ERROR_SESSION_CREDENTIAL_CONFLICT) { - return retval; + if ((pass && *pass) || (user && *user)) { + retval = WNetAddConnection2W(share, pass, user, CONNECT_TEMPORARY | CONNECT_CURRENT_MEDIA); + if (retval == NO_ERROR) { + return retval; + } + if (retval != ERROR_INVALID_PASSWORD && retval != ERROR_LOGON_FAILURE + && retval != ERROR_BAD_USERNAME && retval != ERROR_ACCESS_DENIED + && retval != ERROR_SESSION_CREDENTIAL_CONFLICT) { + return retval; + } } static wchar_t nuser[BUFLEN] = L"", npass[BUFLEN] = L""; if (nuser[0] == 0 && npass[0] == 0) { - int ok = -1; - ok &= MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)suser, -1, (LPWSTR)nuser, BUFLEN) > 0; - ok &= MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)spass, -1, (LPWSTR)npass, BUFLEN) > 0; + BOOL ok = TRUE; + ok = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)suser, -1, (LPWSTR)nuser, BUFLEN) > 0 && ok; + ok = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)spass, -1, (LPWSTR)npass, BUFLEN) > 0 && ok; if (!ok) return ERROR_INVALID_PARAMETER; } @@ -547,17 +629,26 @@ static DWORD mount(LPNETRESOURCEW share, LPWSTR pass, LPWSTR user) return retval; } -static void mkshortcut(const netdrive_t *d, wchar_t *comment) +static void postSuccessfulMount(const netdrive_t *d, wchar_t *letter) { - if (d->shortcut == NULL || strlen(d->shortcut) == 0) - return; - wchar_t tmp[MAX_PATH], wShortcut[MAX_PATH], wTarget[MAX_PATH]; - MultiByteToWideChar(CP_UTF8, 0, d->shortcut, -1, tmp, MAX_PATH); - StringCchPrintfW(wShortcut, MAX_PATH, L"%s\\%s.lnk", desktopPath, tmp); - MultiByteToWideChar(CP_UTF8, 0, d->path, -1, tmp, MAX_PATH); - StringCchPrintfW(wTarget, MAX_PATH, L"\"%s\"", tmp); - DeleteFileW(wShortcut); - createFolderShortcut(wTarget, wShortcut, comment); + if (d->shortcut != NULL && strlen(d->shortcut) != 0) { + wchar_t tmp[MAX_PATH], wShortcut[MAX_PATH], wTarget[MAX_PATH]; + MultiByteToWideChar(CP_UTF8, 0, d->shortcut, -1, tmp, MAX_PATH); + StringCchPrintfW(wShortcut, MAX_PATH, L"%s\\%s.lnk", desktopPath, tmp); + MultiByteToWideChar(CP_UTF8, 0, d->path, -1, tmp, MAX_PATH); + StringCchPrintfW(wTarget, MAX_PATH, L"\"%s\"", tmp); + DeleteFileW(wShortcut); + createFolderShortcut(wTarget, wShortcut, letter); + // Fix paths and kill explorer if it's the home directory + if (_folderStatus != FS_OK && strncmp(d->shortcut, "Home-", 5) == 0) { + BOOL isVmware = strcmp(d->path, "\\\\vmware-host\\Shared Folders\\home") == 0; + if (_remapMode == RM_NATIVE_FALLBACK + || (isVmware && _remapMode == RM_VMWARE) + || (!isVmware && _remapMode == RM_NATIVE)) { + patchUserPaths(letter); + } + } + } } static BOOL mountNetworkShare(const netdrive_t *d) @@ -592,17 +683,10 @@ static BOOL mountNetworkShare(const netdrive_t *d) letter[3] = 0; if (letter[0] != 0) { // Try with specific letter - // Get anything there might be out of the way - WNetCancelConnection2W(letter, CONNECT_UPDATE_PROFILE, TRUE); - WNetCancelConnection2W(letter, 0, TRUE); - letter[2] = '\\'; - WNetCancelConnection2W(letter, 0, TRUE); - DeleteVolumeMountPointW(letter); - letter[2] = 0; // Connect defined share retval = mount(&share, pass, user); if (retval == NO_ERROR) { - mkshortcut(d, letter); + postSuccessfulMount(d, letter); return TRUE; } if (retval != ERROR_ALREADY_ASSIGNED && retval != ERROR_DEVICE_ALREADY_REMEMBERED @@ -618,7 +702,7 @@ static BOOL mountNetworkShare(const netdrive_t *d) || retval == ERROR_CONNECTION_UNAVAIL) continue; if (retval == NO_ERROR) { - mkshortcut(d, letter); + postSuccessfulMount(d, letter); return TRUE; } alog("mountNetworkShare: without letter failed: %d", (int)retval); @@ -656,6 +740,18 @@ static BOOL mountNetworkShares() return TRUE; } +static void remapViaSharedFolder() +{ + netdrive_t d; + d.path = (char*)"\\\\vmware-host\\Shared Folders\\home"; + d.letter = (char*)"H:"; + d.shortcut = (char*)"Home-Verzeichnis"; + d.user = NULL; + d.pass = NULL; + d.success = FALSE; + mountNetworkShare(&d); +} + static char* xorString(const uint8_t* text, int len, const uint8_t* key) { int i; @@ -734,3 +830,104 @@ static HRESULT createFolderShortcut(wchar_t* targetDir, wchar_t* linkFile, wchar return (hRes); } +// Patch user directories + +static BOOL patchRegPath(HKEY hKey, wchar_t *letter, wchar_t *value, ...) +{ + wchar_t *folder = NULL; + wchar_t first[MAX_PATH] = {0}; + wchar_t path[MAX_PATH]; + va_list args; + va_start(args, value); + while ((folder = va_arg(args, wchar_t*)) != NULL) { + StringCchPrintfW(path, MAX_PATH, L"%s\\%s", letter, folder); + if (folderExists(path)) + break; + if (*first == 0) { + wcsncpy(first, path, MAX_PATH); + } + } + va_end(args); + if (folder != NULL) { + // Found something existing + folder = path; + } else if (!_createMissingRemap) { + // Nothing found, must not create + wlog(L"Cannot remap %s to %s: target not found!", value, first); + return FALSE; + } else { + // Nothing found, use first element of list and create it + folder = first; + CreateDirectoryW(folder, NULL); + } + LONG ret = RegSetValueExW(hKey, value, 0, REG_SZ, (BYTE*)folder, (wcslen(folder) + 1) * sizeof(wchar_t)); + if (ret != ERROR_SUCCESS) { + alog("Setting reg key failed (return value %ld)", (long)ret); + } + return ret == ERROR_SUCCESS; +} + +static void patchUserPaths(wchar_t *letter) +{ + LONG ret; + HKEY hKey; + BOOL patchOk = TRUE; + BOOL killOk = FALSE; + _folderStatus = 0; + ret = RegOpenKeyExW(HKEY_CURRENT_USER, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders", + 0, KEY_WOW64_64KEY | KEY_READ | KEY_WRITE, &hKey); + if (ret != ERROR_SUCCESS) { + alog("Opening registry for patching of pathes failed with return code %ld", (long)ret); + return; + } + // Ha! + if (remap.other) { + patchOk = patchRegPath(hKey, letter, L"{56784854-C6CB-462B-8169-88E350ACB882}", L"Contacts", L"Profile\\Contacts", L"Kontakte", NULL) && patchOk; + patchOk = patchRegPath(hKey, letter, L"Favorites", L"Favorites", L"Profile\\Favorites", L"Favoriten", NULL) && patchOk; + patchOk = patchRegPath(hKey, letter, L"{7D1D3A04-DEBB-4115-95CF-2F29DA2920DA}", L"Searches", L"Profile\\Searches", NULL) && patchOk; + patchOk = patchRegPath(hKey, letter, L"{BFB9D5E0-C6A9-404C-B2B2-AE6DB6AF4968}", L"Links", L"Profile\\Links", NULL) && patchOk; + patchOk = patchRegPath(hKey, letter, L"{4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4}", L"Saved Games", L"SavedGames", L"Profile\\SavedGames", NULL) && patchOk; + } + if (remap.media) { + patchOk = patchRegPath(hKey, letter, L"My Video", L"Videos", L"My Videos", L"Eigene Videos", NULL) && patchOk; + patchOk = patchRegPath(hKey, letter, L"My Pictures", L"Pictures", L"My Pictures", L"Eigene Bilder", L"Bilder", NULL) && patchOk; + patchOk = patchRegPath(hKey, letter, L"My Music", L"Music", L"My Music", L"Eigene Musik", L"Musik", NULL) && patchOk; + } + if (remap.downloads) { + patchOk = patchRegPath(hKey, letter, L"{374DE290-123F-4565-9164-39C4925E467B}", L"Downloads", L"Profile\\Downloads", NULL) && patchOk; + } + if (remap.documents) { + patchOk = patchRegPath(hKey, letter, L"Personal", L"Documents", L"Dokumente", L"My Documents", L"Eigene Dateien", NULL) && patchOk; + } + if (remap.desktop) { + patchOk = patchRegPath(hKey, letter, L"Desktop", L"Windows Desktop", L"Desktop", L"Arbeitsfl\u00E4che", NULL) && patchOk; + } + RegCloseKey(hKey); + // Kill explorer + PROCESSENTRY32W entry; + entry.dwSize = sizeof(PROCESSENTRY32W); + HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (snapshot != INVALID_HANDLE_VALUE && Process32FirstW(snapshot, &entry)) { + do { + if (_wcsicmp(entry.szExeFile, L"explorer.exe") == 0) { + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); + if (hProcess == NULL) { + alog("Opening explorer.exe failed"); + } else { + if (TerminateProcess(hProcess, 23)) { + killOk = TRUE; + } + CloseHandle(hProcess); + } + } + } while (Process32NextW(snapshot, &entry)); + } else { + alog("Could not get process list"); + } + CloseHandle(snapshot); + if (patchOk && killOk) { + _folderStatus = 1; + } +} + |
