add_subdirectory(appwiz)
add_subdirectory(cat)
+add_subdirectory(hackssign)
add_subdirectory(ntfsinfo)
add_subdirectory(rosvboxmgmt)
add_subdirectory(tee)
--- /dev/null
+add_executable(hackssign_client client.c hackssign.rc)
+set_module_type(hackssign_client win32cui UNICODE)
+add_importlibs(hackssign_client msvcrt kernel32 advapi32)
+add_cd_file(TARGET hackssign_client DESTINATION reactos/bin FOR all)
+
+add_library(hackssign_driver SHARED driver.c hackssign.rc)
+set_module_type(hackssign_driver kernelmodedriver)
+add_importlibs(hackssign_driver ntoskrnl hal)
+add_cd_file(TARGET hackssign_driver DESTINATION reactos/bin FOR all)
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: Hackssign application & driver
+ * FILE: cmdutils/hackssign/client.c
+ * PURPOSE: Client: Assign drive letter to shared folders for VMware/VBox VMs
+ * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
+ */
+
+#include <stdio.h>
+#include <wchar.h>
+#include <windows.h>
+
+#include "ioctl.h"
+
+/* DON'T MESS AROUND THIS! */
+typedef enum _HV_TYPES
+{
+ vmVMware,
+ vmVirtualBox,
+ vmMax,
+} HV_TYPES;
+PCWSTR hV[] = { L"vmware", L"virtualbox" };
+PCWSTR dev[] = { L"\\Device\\hgfs\\;", L"\\Device\\VBoxMiniRdr\\;" };
+PCWSTR unc[] = { L":\\vmware-host\\Shared Folders\\", L":\\vboxsvr\\" };
+
+BOOL performDevIoCtl(DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize)
+{
+ BOOL ret;
+ HANDLE dev;
+ DWORD lpBytesReturned;
+
+ dev = CreateFile(L"\\\\.\\hackssign",
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, 0, NULL);
+ if (dev == INVALID_HANDLE_VALUE)
+ {
+ wprintf(L"Opening device failed\n");
+ return FALSE;
+ }
+
+ ret = DeviceIoControl(dev, dwIoControlCode, lpInBuffer, nInBufferSize, NULL, 0, &lpBytesReturned, NULL);
+ wprintf(L"Done: it %s with error: %lx\n", (ret != 0 ? L"succeed" : L"failed"), (ret != 0 ? ERROR_SUCCESS : GetLastError()));
+
+ CloseHandle(dev);
+
+ return ret;
+}
+
+
+BOOL startService()
+{
+ PWSTR fileName;
+ WCHAR path[MAX_PATH];
+ SC_HANDLE hManager, hService;
+
+ hManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
+ if (hManager == NULL)
+ {
+ wprintf(L"Service manager opening failed\n");
+ return FALSE;
+ }
+
+ hService = OpenService(hManager, L"hackssign", SERVICE_START | SERVICE_STOP | DELETE);
+ if (hService == NULL)
+ {
+ if (GetModuleFileName(NULL, path, MAX_PATH) == 0)
+ {
+ wprintf(L"Getting own path failed\n");
+ CloseServiceHandle(hManager);
+ return FALSE;
+ }
+
+ fileName = wcsrchr(path, L'\\');
+ if (fileName == NULL)
+ {
+ wprintf(L"Invalid path: %s\n", path);
+ CloseServiceHandle(hManager);
+ return FALSE;
+ }
+
+ ++fileName;
+ *fileName = UNICODE_NULL;
+ wcscat(path, L"hackssign_driver.sys");
+
+ if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES)
+ {
+ wprintf(L"Driver not found: %s\n", path);
+ CloseServiceHandle(hManager);
+ return FALSE;
+ }
+
+ hService = CreateService(hManager, L"hackssign", L"hackssign",
+ SERVICE_START | SERVICE_STOP | DELETE, SERVICE_KERNEL_DRIVER,
+ SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, path, NULL, NULL,
+ NULL, NULL, NULL);
+ if (hService == NULL)
+ {
+ wprintf(L"Creating service failed\n");
+ CloseServiceHandle(hManager);
+ return FALSE;
+ }
+ }
+
+ if (!StartService(hService, 0, NULL) &&
+ GetLastError() != ERROR_SERVICE_ALREADY_RUNNING)
+ {
+ wprintf(L"Starting service failed\n");
+ CloseServiceHandle(hService);
+ CloseServiceHandle(hManager);
+ return FALSE;
+ }
+
+ wprintf(L"Starting service succeed\n");
+ CloseServiceHandle(hService);
+ CloseServiceHandle(hManager);
+ return TRUE;
+}
+
+int assignLetter(WCHAR letter, PCWSTR path, PCWSTR device)
+{
+ BOOL ret;
+ DWORD len;
+ PWSTR str;
+ HV_TYPES vm;
+ WCHAR capsLetter;
+ DWORD inputBufferSize;
+ PASSIGN_INPUT inputBuffer;
+
+ for (vm = vmVMware; vm < vmMax; ++vm)
+ {
+ if (_wcsicmp(device, hV[vm]) == 0)
+ {
+ break;
+ }
+ }
+ if (vm == vmMax)
+ {
+ wprintf(L"Unsupported VM type\n");
+ return 1;
+ }
+
+ if (iswalpha(letter) == 0)
+ {
+ wprintf(L"Invalid letter provided\n");
+ return 1;
+ }
+
+ capsLetter = towupper(letter);
+ if (capsLetter == L'C')
+ {
+ wprintf(L"Looks suspicious, won't proceed\n");
+ return 1;
+ }
+
+ len = wcslen(path);
+ if (len == 0)
+ {
+ wprintf(L"Invalid share name\n");
+ return 1;
+ }
+
+ if (wcschr(path, L'\\') != NULL)
+ {
+ wprintf(L"Only give the name of a share\n");
+ return 1;
+ }
+
+ inputBufferSize = len * sizeof(WCHAR) + sizeof(ASSIGN_INPUT) + (wcslen(dev[vm]) + wcslen(unc[vm]) + 2) * sizeof(WCHAR);
+ inputBuffer = malloc(inputBufferSize);
+ if (inputBuffer == NULL)
+ {
+ wprintf(L"Memory failure\n");
+ return 1;
+ }
+
+ inputBuffer->letter = capsLetter;
+ inputBuffer->offset = sizeof(ASSIGN_INPUT);
+ inputBuffer->len = len * sizeof(WCHAR) + (wcslen(dev[vm]) + wcslen(unc[vm]) + 1) * sizeof(WCHAR);
+ str = (PWSTR)((ULONG_PTR)inputBuffer + inputBuffer->offset);
+ swprintf(str, L"%s%c%s%s", dev[vm], capsLetter, unc[vm], path);
+
+ if (!startService())
+ {
+ free(inputBuffer);
+ return 1;
+ }
+
+ Sleep(500);
+
+ ret = performDevIoCtl(FSCTL_HACKSSIGN_ASSIGN, inputBuffer, inputBufferSize);
+ free(inputBuffer);
+
+ return (ret == FALSE);
+}
+
+int deleteLetter(WCHAR letter)
+{
+ WCHAR capsLetter;
+
+ if (iswalpha(letter) == 0)
+ {
+ wprintf(L"Invalid letter provided\n");
+ return 1;
+ }
+
+ capsLetter = towupper(letter);
+ if (capsLetter == L'C')
+ {
+ wprintf(L"Looks suspicious, won't proceed\n");
+ return 1;
+ }
+
+ if (!startService())
+ {
+ return 1;
+ }
+
+ Sleep(500);
+
+ return (performDevIoCtl(FSCTL_HACKSSIGN_DELETE, &capsLetter, sizeof(WCHAR)) == FALSE);
+}
+
+void printUsage(void)
+{
+ wprintf(L"ReactOS Hackssign application\n");
+ wprintf(L"\assign <letter> <share name> <vmtype>: Assign a drive letter to the share given the VM type\n");
+ wprintf(L"\t\tVM types are: vmware or virtual\n");
+ wprintf(L"\tdelete <letter>: delete driver letter assignation\n");
+}
+
+int wmain(int argc, wchar_t *argv[])
+{
+ PCWSTR cmd;
+
+ if (argc < 3)
+ {
+ printUsage();
+ return 0;
+ }
+
+ cmd = argv[1];
+
+ if (_wcsicmp(cmd, L"assign") == 0)
+ {
+ if (argc < 5)
+ {
+ printUsage();
+ return 0;
+ }
+
+ return assignLetter(argv[2][0], argv[3], argv[4]);
+ }
+ else if (_wcsicmp(cmd, L"delete") == 0)
+ {
+ return deleteLetter(argv[2][0]);
+ }
+ else
+ {
+ printUsage();
+ return 0;
+ }
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: Hackssign application & driver
+ * FILE: cmdutils/hackssign/driver.c
+ * PURPOSE: Driver: Assign drive letter to shared folders for VMware/VBox VMs
+ * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
+ */
+
+#include <wdm.h>
+#include <ntifs.h>
+#include <wchar.h>
+#define NDEBUG
+#include <debug.h>
+
+#include "ioctl.h"
+
+typedef struct _HS_VCB
+{
+ SHARE_ACCESS shareAccess;
+} HS_VCB, *PHS_VCB;
+
+ERESOURCE globalLock;
+PDEVICE_OBJECT gDevObj;
+
+NTSTATUS
+NTAPI
+hsDispatch(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PHS_VCB vcb;
+ NTSTATUS status;
+ WCHAR dosBuffer[7];
+ PFILE_OBJECT fileObject;
+ PIO_STACK_LOCATION stack;
+ PASSIGN_INPUT inputBuffer;
+ UNICODE_STRING target, source;
+
+ FsRtlEnterFileSystem();
+ ExAcquireResourceExclusiveLite(&globalLock, TRUE);
+
+ stack = IoGetCurrentIrpStackLocation(Irp);
+ fileObject = stack->FileObject;
+ switch (stack->MajorFunction)
+ {
+ case IRP_MJ_CREATE:
+ if (fileObject->FileName.Length != 0)
+ {
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+ status = IoCheckShareAccess(stack->Parameters.Create.SecurityContext->DesiredAccess,
+ stack->Parameters.Create.ShareAccess,
+ fileObject, &((PHS_VCB)DeviceObject->DeviceExtension)->shareAccess, TRUE);
+ if (NT_SUCCESS(status))
+ {
+ DPRINT1("Device opened\n");
+
+ Irp->IoStatus.Information = FILE_OPENED;
+ fileObject->FsContext = DeviceObject->DeviceExtension;
+ status = STATUS_SUCCESS;
+ }
+ break;
+
+ case IRP_MJ_FILE_SYSTEM_CONTROL:
+ if (stack->Parameters.FileSystemControl.FsControlCode == FSCTL_HACKSSIGN_ASSIGN)
+ {
+ if (stack->Parameters.FileSystemControl.InputBufferLength <= sizeof(ASSIGN_INPUT) ||
+ Irp->AssociatedIrp.SystemBuffer == NULL)
+ {
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+ inputBuffer = Irp->AssociatedIrp.SystemBuffer;
+
+ swprintf(dosBuffer, L"\\??\\%c:", inputBuffer->letter);
+ RtlInitUnicodeString(&source, dosBuffer);
+ target.Buffer = (PWSTR)((ULONG_PTR)inputBuffer + inputBuffer->offset);
+ target.Length = inputBuffer->len;
+ target.MaximumLength = target.Length;
+
+ DPRINT1("Will link %wZ to %wZ\n", &source, &target);
+
+ status = IoCreateSymbolicLink(&source, &target);
+ break;
+ }
+ else if (stack->Parameters.FileSystemControl.FsControlCode == FSCTL_HACKSSIGN_DELETE)
+ {
+ if (stack->Parameters.FileSystemControl.InputBufferLength < sizeof(WCHAR) ||
+ Irp->AssociatedIrp.SystemBuffer == NULL)
+ {
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+ inputBuffer = Irp->AssociatedIrp.SystemBuffer;
+
+ swprintf(dosBuffer, L"\\??\\%c:", inputBuffer->letter);
+ RtlInitUnicodeString(&source, dosBuffer);
+
+ DPRINT1("Will unlink %wZ\n", &source);
+
+ status = IoDeleteSymbolicLink(&source);
+ break;
+ }
+
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+
+ case IRP_MJ_CLEANUP:
+ vcb = fileObject->FsContext;
+ if (vcb == NULL)
+ {
+ status = STATUS_INVALID_HANDLE;
+ break;
+ }
+
+ DPRINT1("Device cleaned up\n");
+ IoRemoveShareAccess(fileObject, &vcb->shareAccess);
+ status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MJ_CLOSE:
+ vcb = fileObject->FsContext;
+ if (vcb == NULL)
+ {
+ status = STATUS_INVALID_HANDLE;
+ break;
+ }
+
+ DPRINT1("Device closed\n");
+ fileObject->FsContext = NULL;
+ status = STATUS_SUCCESS;
+ break;
+
+ default:
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+ ExReleaseResourceLite(&globalLock);
+ FsRtlExitFileSystem();
+
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+VOID
+NTAPI
+hsUnload(PDRIVER_OBJECT DriverObject)
+{
+ IoDeleteDevice(gDevObj);
+ ExDeleteResourceLite(&globalLock);
+}
+
+NTSTATUS
+NTAPI
+DriverEntry(PDRIVER_OBJECT DriverObject,
+ PUNICODE_STRING RegistryPath)
+{
+ NTSTATUS status;
+ PDEVICE_OBJECT devObj;
+ UNICODE_STRING devName, uDevName;
+
+ DPRINT1("Starting hackssign driver\n");
+
+ RtlInitUnicodeString(&devName, L"\\Device\\hackssign");
+ status = IoCreateDevice(DriverObject, sizeof(HS_VCB), &devName, FILE_DEVICE_FILE_SYSTEM, 0, FALSE, &devObj);
+ if (!NT_SUCCESS(status))
+ {
+ DPRINT1("IoCreateDevice failed\n");
+ return status;
+ }
+
+ RtlInitUnicodeString(&uDevName, L"\\??\\hackssign");
+ status = IoCreateSymbolicLink(&uDevName, &devName);
+ if (!NT_SUCCESS(status))
+ {
+ DPRINT1("IoCreateSymbolicLink failed\n");
+ IoDeleteDevice(devObj);
+ return status;
+ }
+
+ gDevObj = devObj;
+ ExInitializeResourceLite(&globalLock);
+ RtlZeroMemory(devObj->DeviceExtension, sizeof(HS_VCB));
+
+ DriverObject->DriverUnload = hsUnload;
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = hsDispatch;
+ DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = hsDispatch;
+ DriverObject->MajorFunction[IRP_MJ_CLEANUP] = hsDispatch;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = hsDispatch;
+
+ return STATUS_SUCCESS;
+}
--- /dev/null
+
+#define REACTOS_STR_FILE_DESCRIPTION "Hack assign letters\0"
+#define REACTOS_STR_INTERNAL_NAME "hackssign\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "hackssign.exe\0"
+#include <reactos/version.rc>
--- /dev/null
+typedef struct _ASSIGN_INPUT
+{
+ WCHAR letter;
+ USHORT offset;
+ USHORT len;
+} ASSIGN_INPUT, *PASSIGN_INPUT;
+
+#define FSCTL_HACKSSIGN_ASSIGN CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x42, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSCTL_HACKSSIGN_DELETE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS VBox Shared Folders Management
+ * FILE: cmdutils/hackssign/client.c
+ * PURPOSE: Communicate with VBox mini redirector to deal with shared folders
+ * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
+ */
+
#include <stdio.h>
#include <wchar.h>
#include <windows.h>