summaryrefslogtreecommitdiffstats
path: root/remote/modules/run-virt/winres.c
diff options
context:
space:
mode:
authorSimon Rettberg2016-03-30 12:06:00 +0200
committerSimon Rettberg2016-03-30 12:06:00 +0200
commitd27c3de74a40b0544ecbc51cddd02f1277feb28f (patch)
treebb381f2a02c4b76032c2eb8a031221e9d03e4b2c /remote/modules/run-virt/winres.c
parent[vmchooser2] Pass --no-vtx to vmchooser if applicable (diff)
downloadtm-scripts-d27c3de74a40b0544ecbc51cddd02f1277feb28f.tar.gz
tm-scripts-d27c3de74a40b0544ecbc51cddd02f1277feb28f.tar.xz
tm-scripts-d27c3de74a40b0544ecbc51cddd02f1277feb28f.zip
[run-virt] Better support for win10 folder remapping
Diffstat (limited to 'remote/modules/run-virt/winres.c')
-rw-r--r--remote/modules/run-virt/winres.c1001
1 files changed, 0 insertions, 1001 deletions
diff --git a/remote/modules/run-virt/winres.c b/remote/modules/run-virt/winres.c
deleted file mode 100644
index 626a1048..00000000
--- a/remote/modules/run-virt/winres.c
+++ /dev/null
@@ -1,1001 +0,0 @@
-#define NTDDI_VERSION NTDDI_VISTA
-#define WINVER 0x0602
-#define _WIN32_WINNT 0x0602
-#define WIN32_LEAN_AND_MEAN
-#define _UNICODE
-#define UNICODE
-#include <windows.h>
-#include <winsock2.h>
-#include <winnetwk.h>
-#include <mmdeviceapi.h>
-#include <endpointvolume.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <initguid.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <wchar.h>
-#include <time.h>
-#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);
-DEFINE_GUID(ID_MMDeviceEnumerator, 0xBCDE0395, 0xE52F, 0x467C, 0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E);
-
-#define WM_SOCKDATA (WM_APP+1)
-
-typedef struct {
- const char* path;
- const char* letter;
- const char* shortcut;
- const char* user;
- const char* pass;
- BOOL success;
-} netdrive_t;
-
-static const ssize_t KEYLEN = 16;
-#define DRIVEMAX (100)
-#define LOGFILELEN (300)
-#define SETTINGS_FILE "B:\\OPENSLX.INI"
-#define SETTINGS_FILE_W L"B:\\OPENSLX.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;
-static const char* _remapHomeDrive = NULL;
-
-struct {
- BOOL documents;
- BOOL downloads;
- BOOL desktop;
- BOOL media;
- BOOL other;
-} remap;
-static BOOL _createMissingRemap = FALSE;
-
-static int setResolution();
-static int muteSound();
-static int setShutdownText();
-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);
-
-static void alog(const char *fmt, ...)
-{
- FILE *f = _wfopen(logFile, L"a+");
- if (f == NULL) return;
- time_t raw = time(NULL);
- struct tm *tinf;
- char buffer[80];
- tinf = localtime(&raw);
- strftime(buffer, 80, "%I:%M:%S ", tinf);
- fputs(buffer, f);
- va_list args;
- va_start(args, fmt);
- vfprintf(f, fmt, args);
- va_end(args);
- fputc('\n', f);
- fclose(f);
-}
-
-static void wlog(const wchar_t *fmt, ...)
-{
- 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);
-
- 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)
-{
- static BOOL bInProc = FALSE;
- if (!bInProc) {
- bInProc = TRUE;
- setShutdownText();
- bInProc = FALSE;
- }
-}
-
-static void CALLBACK tmrResolution(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
-{
- static BOOL bInProc = FALSE;
- if (!bInProc) {
- bInProc = TRUE;
- if (setResolution() == 0) {
- KillTimer(hWnd, idEvent);
- }
- bInProc = FALSE;
- }
-}
-
-static void CALLBACK setupNetworkDrives(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
-{
- static BOOL bInProc = FALSE;
- static int fails = 0;
- if (bInProc)
- return;
- bInProc = TRUE;
- if (!bGetShares && (_remapMode == RM_NATIVE_FALLBACK || _remapMode == RM_VMWARE)) {
- remapViaSharedFolder();
- } else {
- 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 && (_remapMode == RM_NATIVE_FALLBACK || _remapMode == RM_VMWARE)) {
- 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);
- }
- }
- return;
-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) {
- StringCchPrintfW(programsPath, MAX_PATH+1, L"C:\\Program Files");
- }
- }
- if (SHGetFolderPathW(HWND_DESKTOP, CSIDL_WINDOWS, NULL, SHGFP_TYPE_CURRENT, windowsPath) != S_OK) {
- DWORD ret = GetEnvironmentVariableW(L"windir", windowsPath, MAX_PATH+1);
- if (ret == 0 || ret > MAX_PATH) {
- StringCchPrintfW(windowsPath, MAX_PATH+1, L"C:\\WINDOWS");
- }
- }
- if (SHGetFolderPathW(HWND_DESKTOP, CSIDL_DESKTOPDIRECTORY, NULL, SHGFP_TYPE_CURRENT, desktopPath) != S_OK) {
- desktopPath[0] = 0;
- }
- if (GetTempPathW(MAX_PATH+1, tempPath) == 0) {
- tempPath[0] = 0;
- }
- StringCchPrintfW(logFile, LOGFILELEN, L"%s\\%s", desktopPath, L"openslx.log");
- FILE *tfh = _wfopen(logFile, L"a+");
- if (tfh == NULL) {
- StringCchPrintfW(logFile, LOGFILELEN, L"%s\\%s", tempPath, L"openslx.log");
- tfh = _wfopen(logFile, L"a+");
- }
- if (tfh != NULL) {
- fseek(tfh, 0, SEEK_END);
- long pos = ftell(tfh);
- fclose(tfh);
- if (pos < 3) {
- _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);
- if (_remapMode == RM_NONE) {
- _folderStatus = FS_OK;
- }
- char buffer[10];
- GetPrivateProfileStringA("openslx", "homeDrive", "H:", buffer, sizeof(buffer), SETTINGS_FILE);
- buffer[0] = toupper(buffer[0]);
- buffer[1] = ':';
- buffer[2] = '\0';
- _remapHomeDrive = strdup(buffer);
-}
-
-int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
-{
- OSVERSIONINFO version;
- version.dwOSVersionInfoSize = sizeof(version);
- BOOL retVer = GetVersionEx(&version);
- CoInitialize(NULL);
- _startTime = GetTickCount();
- loadPaths();
- // Mute sound by default
- if (retVer && version.dwMajorVersion >= 6)
- muteSound();
- // Disable screen saver as it might give the false impression that the session is securely locked
- SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
- // Disable standby and idle-mode (this is a VM!)
- if (version.dwMajorVersion >= 6) { // Vista+
- SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED | ES_AWAYMODE_REQUIRED);
- } else { // XP/2003
- SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
- }
- // Any network shares to mount?
- readShareFile();
- 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());
- }
- }
- // Shutdown button label
- if (retVer && version.dwMajorVersion == 6 && version.dwMinorVersion == 1) {
- // Only on Windows 7
- // Repeatedly set caption
- 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(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());
- }
- }
- // Message pump
- MSG Msg;
- while(GetMessage(&Msg, NULL, 0, 0) > 0) {
- TranslateMessage(&Msg);
- DispatchMessage(&Msg);
- }
- return 0;
-}
-
-static BOOL fileExists(wchar_t* szPath)
-{
- DWORD dwAttrib = GetFileAttributesW(szPath);
- 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()
-{
- int ret;
- static int width = 0, height = 0;
- if (width == 0 && height == 0) {
- // use config file in floppy
- char data[200] = "";
- GetPrivateProfileStringA("openslx", "resolution", "", data, sizeof(data), SETTINGS_FILE);
- char *x = strchr(data, 'x');
- if (x == NULL) {
- 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 " SETTINGS_FILE ": '%s' (parsed width=%d, height=%d)", data, width, height);
- return 0;
- }
- }
- // Try vmware tools
- static wchar_t path[MAX_PATH] = L"";
- if (path[0] == 0) {
- StringCchPrintfW(path, MAX_PATH, L"%s\\VMware\\VMware Tools\\VMwareResolutionSet.exe", programsPath);
- if (!fileExists(path)) {
- // Strip (x86) if found and try again
- wchar_t *x86 = wcsstr(path, L" (x86)");
- if (x86 != NULL) {
- while ((*x86 = *(x86 + 6)) != 0) ++x86;
- }
- }
- if (!fileExists(path)) {
- char buffer[300];
- WideCharToMultiByte(CP_UTF8, 0, path, -1, buffer, 300, NULL, NULL);
- alog("vmware tools not found, using winapi to set resolution (path: %s)", buffer);
- }
- }
- if (path[0] != 0 && fileExists(path)) {
- wchar_t cmdline[MAX_PATH];
- StringCchPrintfW(cmdline, MAX_PATH, L"VMwareResolutionSet.exe 0 1 , 0 0 %d %d", width, height);
- 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
- DEVMODE mode;
- int query = 1337;
- memset(&mode, 0, sizeof(mode));
- mode.dmSize = sizeof(mode);
- // MSDN recommends to fill the struct first by querying....
- query = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &mode);
- // Then set our own desired mode
- mode.dmPelsWidth = width;
- mode.dmPelsHeight = height;
- mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
- ret = ChangeDisplaySettings(&mode, CDS_GLOBAL | CDS_UPDATEREGISTRY);
- if (ret != DISP_CHANGE_SUCCESSFUL) {
- ret = ChangeDisplaySettings(&mode, CDS_GLOBAL);
- }
- if (ret != DISP_CHANGE_SUCCESSFUL) {
- ret = ChangeDisplaySettings(&mode, CDS_UPDATEREGISTRY);
- }
- if (ret != DISP_CHANGE_SUCCESSFUL) {
- ret = ChangeDisplaySettings(&mode, 0);
- }
- if (ret != DISP_CHANGE_SUCCESSFUL) {
- static int fails = 0;
- if (++fails == 5) {
- alog("Fehler beim Setzen der Auflösung: %d (soll: 0) / %d ( soll: !0) - Zielaufloesung: %d * %d",
- ret, query, width, height);
- }
- return 1;
- }
- return 0;
-}
-
-static int muteSound()
-{
- IMMDeviceEnumerator *deviceEnumerator = NULL;
- HRESULT hr = CoCreateInstance(&ID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &ID_IMMDeviceEnumerator, (LPVOID *)&deviceEnumerator);
- if (hr != S_OK) {
- alog("CoCreateInstance failed. Cannot mute.");
- return 1;
- }
- //deviceEnumerator->lpVtbl->AddRef(deviceEnumerator);
- IMMDevice *defaultDevice = NULL;
- hr = deviceEnumerator->lpVtbl->GetDefaultAudioEndpoint(deviceEnumerator, eRender, eConsole, &defaultDevice);
- if (hr != S_OK) {
- alog("GetDefaultAudioEndpoint failed. Cannot mute.");
- return 2;
- }
- //defaultDevice->lpVtbl->AddRef(defaultDevice);
- //deviceEnumerator->lpVtbl->Release(deviceEnumerator);
- IAudioEndpointVolume *endpointVolume = NULL;
- hr = defaultDevice->lpVtbl->Activate(defaultDevice, &ID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
- if (hr != S_OK) {
- alog("IMMDevice::Activate() failed. Cannot mute.");
- return 3;
- }
- //endpointVolume->lpVtbl->AddRef(endpointVolume);
- //defaultDevice->lpVtbl->Release(defaultDevice);
- float targetVolume = 1;
- endpointVolume->lpVtbl->SetMasterVolumeLevelScalar(endpointVolume, targetVolume, NULL);
- endpointVolume->lpVtbl->SetMute(endpointVolume, TRUE, NULL);
- //endpointVolume->lpVtbl->Release(endpointVolume);
- //CoUninitialize();
- return 0;
-}
-
-static int setShutdownText()
-{
- HWND hMenu = FindWindowA("DV2ControlHost", NULL);
- if (hMenu == NULL) return 1; // TODO: Enum all of them
- HWND hPane = FindWindowExA(hMenu, NULL, "DesktopLogoffPane", NULL);
- if (hMenu == NULL) return 2;
- HWND hButton = FindWindowExA(hPane, NULL, "Button", NULL);
- if (hButton == NULL) return 3;
- if (SendMessageA(hButton, WM_SETTEXT, 0, (LPARAM)"Abmelden") != TRUE) return 4;
- return 0;
-}
-
-static char *shost = NULL, *sport = NULL, *suser = NULL, *spass = NULL;
-static uint8_t *bkey1 = NULL, *bkey2 = NULL;
-
-static char* xorString(const uint8_t* text, int len, const uint8_t* key);
-static int getbin(int x);
-static uint8_t* hex2bin(char *szHexString);
-
-static char* getToken(char **ptr, BOOL doDup)
-{
- if (*ptr == NULL || **ptr == '\0') return NULL;
- char *dest = *ptr;
- while (**ptr != '\0') {
- if (**ptr == '\n' || **ptr == '\r' || **ptr == '\t') {
- *(*ptr)++ = '\0';
- break;
- }
- (*ptr)++;
- }
- if (doDup) {
- dest = strdup(dest);
- }
- return dest;
-}
-
-#define FREENULL(x) do { free((void*)(x)); (x) = NULL; } while (0)
-
-static void readShareFile()
-{
- if (bGetShares)
- return;
- memset(drives, 0, sizeof(drives));
- FILE *h = fopen("B:\\shares.dat", "r");
- if (h == NULL) return;
- char creds[300] = "", buffer[500] = "";
- char *skey1 = NULL, *skey2 = NULL;
- if (fgets(creds, sizeof(creds), h) != NULL) {
- char *ptr = creds;
- shost = getToken(&ptr, FALSE);
- sport = getToken(&ptr, FALSE);
- skey1 = getToken(&ptr, FALSE);
- skey2 = getToken(&ptr, FALSE);
- suser = getToken(&ptr, FALSE);
- }
- int idx = 0;
- while (fgets(buffer, sizeof(buffer), h) != NULL && idx < DRIVEMAX) {
- char *ptr = buffer;
- netdrive_t *d = &drives[idx];
- d->path = getToken(&ptr, TRUE);
- d->letter = getToken(&ptr, TRUE);
- d->shortcut = getToken(&ptr, TRUE);
- d->user = getToken(&ptr, TRUE);
- d->pass = getToken(&ptr, TRUE);
- if (d->path == NULL || d->path[0] == '\0')
- goto drive_fail;
- d->success = FALSE;
- idx++;
- continue;
-drive_fail:
- FREENULL(d->path);
- FREENULL(d->letter);
- FREENULL(d->shortcut);
- FREENULL(d->user);
- FREENULL(d->pass);
- }
- fclose(h);
- if (idx == 0) // No drives to map
- return;
- if (shost == NULL || sport == NULL || skey1 == NULL || skey2 == NULL || suser == NULL) // Credential stuff missing
- return;
- if (strlen(skey1) != KEYLEN*2 || strlen(skey2) != KEYLEN*2) // Messed up keys
- return;
- if (atoi(sport) < 1000 || atoi(sport) > 65535) // Invalid port
- return;
- shost = strdup(shost);
- sport = strdup(sport);
- bkey1 = hex2bin(skey1);
- bkey2 = hex2bin(skey2);
- if (bkey1 == NULL || bkey2 == NULL)
- return;
- bGetShares = TRUE;
-}
-
-static void udpReceived(SOCKET sock);
-
-LRESULT CALLBACK slxWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- if (uMsg != WM_SOCKDATA) {
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
- }
- // Socket event
- int event = LOWORD(lParam);
- int errorCode = HIWORD(lParam);
- if (errorCode == 0 && event == FD_READ) {
- udpReceived((SOCKET)wParam);
- }
- return 0;
-}
-
-static int queryPasswordDaemon()
-{
- // See if preconditions are met
- if (!bGetShares || spass != NULL)
- return 0;
- static int wsaInit = 1337;
- static SOCKET sock = INVALID_SOCKET;
- static HWND sockWnd = NULL;
- // Init socket stuff
- if (wsaInit == 1337) {
- WSADATA wsa;
- wsaInit = WSAStartup(MAKEWORD(2, 2), &wsa);
- }
- if (wsaInit != 0)
- return 2;
- // Create window for socket events
- if (sockWnd == NULL) {
- sockWnd = CreateWindowA("STATIC", "OpenSLX mystery window", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
- if (sockWnd == NULL)
- return GetLastError();
- SetWindowLong(sockWnd, GWL_WNDPROC, (LONG)&slxWindowProc);
- }
- // Create socket
- if (sock == INVALID_SOCKET) {
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sock == INVALID_SOCKET)
- return 3;
- if (WSAAsyncSelect(sock, sockWnd, WM_SOCKDATA, FD_READ) != 0) {
- alog("WSAAsyncSelect returned %d", (int)WSAGetLastError());
- }
- }
- SOCKADDR_IN remote;
- remote.sin_family = AF_INET;
- remote.sin_port = htons((u_short)atoi(sport));
- remote.sin_addr.s_addr = inet_addr(shost);
- // Send out request for password
- if (sendto(sock, (const char*)bkey1, KEYLEN, 0, (struct sockaddr*)&remote, sizeof(remote)) != KEYLEN)
- return 4;
- if (spass == NULL)
- return -1;
- return 0;
-}
-
-static void udpReceived(SOCKET sock)
-{
- int ret;
- uint8_t buffer[200];
- ret = recv(sock, (char*)buffer, sizeof(buffer), 0);
- // See if reply is valid
- if (ret < 2) return;
- uint16_t len = (uint16_t)(((uint16_t)buffer[0] << 8) | buffer[1]);
- if (ret - 2 != len) return;
- // Success
- spass = xorString(buffer + 2, len, bkey2);
- closesocket(sock);
- mountNetworkShares();
-}
-
-#define BUFLEN (200)
-
-static DWORD mount(LPNETRESOURCEW share, LPWSTR pass, LPWSTR user)
-{
- DWORD retval;
- // Now try to mount
- 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) {
- BOOL ok = TRUE;
- if (suser != NULL) {
- ok = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)suser, -1, (LPWSTR)nuser, BUFLEN) > 0 && ok;
- }
- if (spass != NULL) {
- ok = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)spass, -1, (LPWSTR)npass, BUFLEN) > 0 && ok;
- }
- if (!ok)
- return ERROR_INVALID_PARAMETER;
- }
- retval = WNetAddConnection2W(share, npass, nuser, CONNECT_TEMPORARY | CONNECT_CURRENT_MEDIA);
- return retval;
-}
-
-static void postSuccessfulMount(const netdrive_t *d, wchar_t *letter)
-{
- 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)
-{
- wchar_t path[BUFLEN] = L"", user[BUFLEN] = L"", pass[BUFLEN] = L"", letter[10] = L"", shortcut[BUFLEN] = L"";
- int ok = -1;
- ok &= MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)d->path, -1, (LPWSTR)path, BUFLEN) > 0;
- if (d->letter != NULL) {
- ok &= MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)d->letter, -1, (LPWSTR)letter, 10) > 0;
- }
- if (d->user != NULL) {
- ok &= MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)d->user, -1, (LPWSTR)user, BUFLEN) > 0;
- }
- if (d->pass != NULL) {
- ok &= MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)d->pass, -1, (LPWSTR)pass, BUFLEN) > 0;
- }
- if (d->shortcut != NULL) {
- ok &= MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)d->shortcut, -1, (LPWSTR)shortcut, BUFLEN) > 0;
- }
- if (!ok || path[0] == 0) { // Convert failed/no path - return true anyways since retrying wouldn't change anything
- alog("mountNetworkShare: utf8 to utf16 failed, or path empty (src: '%s')", d->path);
- return TRUE;
- }
- DWORD retval;
- NETRESOURCEW share;
- share.dwType = RESOURCETYPE_DISK;
- share.lpLocalName = letter;
- share.lpRemoteName = path;
- share.lpProvider = NULL;
- letter[1] = ':';
- letter[2] = 0;
- letter[3] = 0;
- if (letter[0] != 0) {
- // Try with specific letter
- // Connect defined share
- retval = mount(&share, pass, user);
- if (retval == NO_ERROR) {
- postSuccessfulMount(d, letter);
- return TRUE;
- }
- if (retval != ERROR_ALREADY_ASSIGNED && retval != ERROR_DEVICE_ALREADY_REMEMBERED
- && retval != ERROR_CONNECTION_UNAVAIL) {
- alog("mountNetworkShare: with letter failed: %d", (int)retval);
- return FALSE;
- }
- }
- // Try to find free drive letter
- for (letter[0] = 'Z'; letter[0] > 'C'; --letter[0]) {
- retval = mount(&share, pass, user);
- if (retval == ERROR_ALREADY_ASSIGNED || retval == ERROR_DEVICE_ALREADY_REMEMBERED
- || retval == ERROR_CONNECTION_UNAVAIL)
- continue;
- if (retval == NO_ERROR) {
- postSuccessfulMount(d, letter);
- return TRUE;
- }
- alog("mountNetworkShare: without letter failed: %d", (int)retval);
- if (retval == ERROR_INVALID_PASSWORD || retval == ERROR_LOGON_FAILURE
- || retval == ERROR_BAD_USERNAME || retval == ERROR_ACCESS_DENIED
- || retval == ERROR_SESSION_CREDENTIAL_CONFLICT) {
- return TRUE;
- }
- return FALSE;
- }
- return FALSE;
-}
-
-static BOOL mountNetworkShares()
-{
- if (!bGetShares)
- return TRUE;
- if (spass == NULL)
- return FALSE;
- int failCount = 0;
- for (int i = 0; i < DRIVEMAX; ++i) {
- if (drives[i].path == NULL)
- break;
- if (drives[i].success)
- continue;
- if (mountNetworkShare(&drives[i])) {
- drives[i].success = TRUE;
- } else {
- failCount++;
- }
- }
- if (failCount > 0)
- return FALSE;
- SecureZeroMemory(spass, strlen(spass));
- return TRUE;
-}
-
-static void remapViaSharedFolder()
-{
- static const char* homeDirA = "\\\\vmware-host\\Shared Folders\\home"; // thiscase!
- static const wchar_t* homeDirW = L"\\\\vmware-host\\shared folders\\home"; // lowercase!
- static BOOL once = FALSE;
- if (once) return;
- once = TRUE;
- netdrive_t d;
- d.path = homeDirA;
- d.letter = _remapHomeDrive;
- d.shortcut = "Home-Verzeichnis";
- d.user = "";
- d.pass = "";
- d.success = FALSE;
- // See if it's already mapped
- wchar_t letter[5] = L"C:\\";
- char buffer[600];
- UNIVERSAL_NAME_INFOW *uni = (UNIVERSAL_NAME_INFOW*)buffer;
- for (letter[0] = 'D'; letter[0] <= 'Z'; ++letter[0]) {
- //wlog(L"Checking %s", letter);
- DWORD len = (DWORD)sizeof(buffer);
- if (NO_ERROR == WNetGetUniversalNameW(letter, UNIVERSAL_NAME_INFO_LEVEL, uni, &len)) {
- _wcslwr(uni->lpUniversalName);
- //wlog(L"Is %s", uni->lpUniversalName);
- if (wcscmp(uni->lpUniversalName, homeDirW) == 0) {
- letter[2] = '\0';
- postSuccessfulMount(&d, letter);
- return;
- }
- }
- }
- // Map vmware shared folder
- mountNetworkShare(&d);
-}
-
-static char* xorString(const uint8_t* text, int len, const uint8_t* key)
-{
- int i;
- uint8_t *retval = malloc(len + 1);
- uint8_t *ptr = retval;
- for (i = 0; i < len; ++i) {
- ptr[i] = text[i] ^ key[i % KEYLEN];
- }
- ptr[len] = '\0';
- return (char*)retval;
-}
-
-static int getbin(int x)
-{
- if (x >= '0' && x <= '9')
- return x - '0';
- if (x >= 'A' && x <= 'F')
- return x - 'A' + 10;
- return x - 'a' + 10;
-}
-
-static uint8_t* hex2bin(char *szHexString)
-{
- int size = strlen(szHexString) / 2, i;
- char *p = szHexString;
- uint8_t *pBinary = malloc(size);
-
- for(i = 0; i < size; i++, p += 2) {
- pBinary[i] = (uint8_t)((getbin(p[0]) << 4) | getbin(p[1]));
- }
- return pBinary;
-}
-
-// Stuff for creating a simple shortcut (.lnk)
-
-static HRESULT createFolderShortcut(wchar_t* targetDir, wchar_t* linkFile, wchar_t* comment)
-{
- HRESULT hRes; /* Returned COM result code */
- IShellLink* pShellLink; /* IShellLink object pointer */
- IPersistFile* pPersistFile; /* IPersistFile object pointer */
-
- hRes = E_INVALIDARG;
- if (
- (targetDir != NULL) && (wcslen(targetDir) > 0) &&
- (linkFile != NULL) && (wcslen(linkFile) > 0)
- ) {
- hRes = CoCreateInstance(
- &CLSID_ShellLink, /* pre-defined CLSID of the IShellLink object */
- NULL, /* pointer to parent interface if part of aggregate */
- CLSCTX_INPROC_SERVER, /* caller and called code are in same process */
- &IID_IShellLink, /* pre-defined interface of the IShellLink object */
- (void**)&pShellLink); /* Returns a pointer to the IShellLink object */
- if (SUCCEEDED(hRes)) {
- wchar_t explorer[MAX_PATH];
- StringCchPrintfW(explorer, MAX_PATH, L"\"%s\\explorer.exe\"", windowsPath);
- // Set the fields in the IShellLink object
- hRes = pShellLink->lpVtbl->SetPath(pShellLink, explorer);
- hRes = pShellLink->lpVtbl->SetArguments(pShellLink, targetDir);
- if (comment != NULL) {
- hRes = pShellLink->lpVtbl->SetDescription(pShellLink, comment);
- }
- StringCchPrintfW(explorer, MAX_PATH, L"%s\\system32\\imageres.dll", windowsPath);
- hRes = pShellLink->lpVtbl->SetIconLocation(pShellLink, explorer, 137);
-
- /* Use the IPersistFile object to save the shell link */
- hRes = pShellLink->lpVtbl->QueryInterface(
- pShellLink, /* existing IShellLink object */
- &IID_IPersistFile, /* pre-defined interface of the IPersistFile object */
- (void**)&pPersistFile); /* returns a pointer to the IPersistFile object */
- if (SUCCEEDED(hRes)) {
- hRes = pPersistFile->lpVtbl->Save(pPersistFile, linkFile, TRUE);
- pPersistFile->lpVtbl->Release(pPersistFile);
- }
- pShellLink->lpVtbl->Release(pShellLink);
- }
-
- }
- return (hRes);
-}
-
-// Patch user directories
-
-static BOOL patchRegPath(BOOL *patchOk, BOOL *anyMapped, HKEY hKey, wchar_t *letter, wchar_t *value, ...)
-{
- wchar_t *folder = NULL;
- wchar_t first[MAX_PATH] = {0};
- wchar_t path[MAX_PATH];
- wchar_t oldvalue[MAX_PATH];
- va_list args;
- LONG ret;
- DWORD type;
- DWORD len;
- // Let's check the path in the registry first
- len = (DWORD)(sizeof(oldvalue) - sizeof(wchar_t));
- ret = RegQueryValueExW(hKey, value, NULL, &type, (BYTE*)oldvalue, &len);
- if (ret == ERROR_SUCCESS && (type == REG_EXPAND_SZ || type == REG_SZ)) {
- len /= 2;
- oldvalue[len] = '\0';
- if (towlower(oldvalue[0]) == towlower(letter[0]) && folderExists(oldvalue)) // Same drive, folder exists, yay
- return TRUE;
- }
- // Old registry value doesn't fit - figure out new value
- 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);
- }
- _wcslwr(folder);
- _wcslwr(oldvalue);
- if (wcscmp(folder, oldvalue) == 0) {
- // Path already in registry, don't update
- return TRUE;
- }
- ret = RegSetValueExW(hKey, value, 0, REG_SZ, (BYTE*)folder, (wcslen(folder) + 1) * sizeof(wchar_t));
- if (ret == ERROR_SUCCESS) {
- *anyMapped = TRUE;
- return TRUE;
- }
- wlog(L"Setting reg key %s to %s failed (return value %ld)", value, folder, (long)ret);
- *patchOk = FALSE;
- return FALSE;
-}
-
-static void patchUserPaths(wchar_t *letter)
-{
- LONG ret;
- HKEY hKey;
- BOOL patchOk = TRUE;
- BOOL killOk = FALSE;
- BOOL anyMapped = FALSE;
- _folderStatus = FS_ERROR;
- 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) {
- patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{56784854-C6CB-462B-8169-88E350ACB882}", L"Contacts", L"Profile\\Contacts", L"Kontakte", NULL);
- patchRegPath(&patchOk, &anyMapped, hKey, letter, L"Favorites", L"Favorites", L"Profile\\Favorites", L"Favoriten", NULL);
- patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{7D1D3A04-DEBB-4115-95CF-2F29DA2920DA}", L"Searches", L"Profile\\Searches", NULL);
- patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{BFB9D5E0-C6A9-404C-B2B2-AE6DB6AF4968}", L"Links", L"Profile\\Links", NULL);
- patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4}", L"Saved Games", L"SavedGames", L"Profile\\SavedGames", NULL);
- }
- if (remap.media) {
- patchRegPath(&patchOk, &anyMapped, hKey, letter, L"My Video", L"Videos", L"My Videos", L"Eigene Videos", NULL);
- patchRegPath(&patchOk, &anyMapped, hKey, letter, L"My Pictures", L"Pictures", L"My Pictures", L"Eigene Bilder", L"Bilder", NULL);
- patchRegPath(&patchOk, &anyMapped, hKey, letter, L"My Music", L"Music", L"My Music", L"Eigene Musik", L"Musik", NULL);
- }
- if (remap.downloads) {
- patchRegPath(&patchOk, &anyMapped, hKey, letter, L"{374DE290-123F-4565-9164-39C4925E467B}", L"Downloads", L"Profile\\Downloads", NULL);
- }
- if (remap.documents) {
- patchRegPath(&patchOk, &anyMapped, hKey, letter, L"Personal", L"Documents", L"Dokumente", L"My Documents", L"Eigene Dateien", NULL);
- }
- if (remap.desktop) {
- patchRegPath(&patchOk, &anyMapped, hKey, letter, L"Desktop", L"Windows Desktop", L"Desktop", L"Arbeitsfl\u00E4che", NULL);
- }
- RegCloseKey(hKey);
- if (!anyMapped) {
- _folderStatus = FS_OK;
- return;
- }
- // 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 = FS_OK;
- }
-}
-