[HACKSSIGN]
[reactos.git] / rosapps / applications / cmdutils / hackssign / driver.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: Hackssign application & driver
4 * FILE: cmdutils/hackssign/driver.c
5 * PURPOSE: Driver: Assign drive letter to shared folders for VMware/VBox VMs
6 * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
7 */
8
9 #include <wdm.h>
10 #include <ntifs.h>
11 #include <wchar.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 #include "ioctl.h"
16
17 typedef struct _HS_VCB
18 {
19 SHARE_ACCESS shareAccess;
20 } HS_VCB, *PHS_VCB;
21
22 ERESOURCE globalLock;
23 PDEVICE_OBJECT gDevObj;
24
25 NTSTATUS
26 NTAPI
27 hsDispatch(PDEVICE_OBJECT DeviceObject,
28 PIRP Irp)
29 {
30 PHS_VCB vcb;
31 NTSTATUS status;
32 WCHAR dosBuffer[7];
33 PFILE_OBJECT fileObject;
34 PIO_STACK_LOCATION stack;
35 PASSIGN_INPUT inputBuffer;
36 UNICODE_STRING target, source;
37
38 FsRtlEnterFileSystem();
39 ExAcquireResourceExclusiveLite(&globalLock, TRUE);
40
41 stack = IoGetCurrentIrpStackLocation(Irp);
42 fileObject = stack->FileObject;
43 switch (stack->MajorFunction)
44 {
45 case IRP_MJ_CREATE:
46 if (fileObject->FileName.Length != 0)
47 {
48 status = STATUS_INVALID_DEVICE_REQUEST;
49 break;
50 }
51
52 status = IoCheckShareAccess(stack->Parameters.Create.SecurityContext->DesiredAccess,
53 stack->Parameters.Create.ShareAccess,
54 fileObject, &((PHS_VCB)DeviceObject->DeviceExtension)->shareAccess, TRUE);
55 if (NT_SUCCESS(status))
56 {
57 DPRINT1("Device opened\n");
58
59 Irp->IoStatus.Information = FILE_OPENED;
60 fileObject->FsContext = DeviceObject->DeviceExtension;
61 status = STATUS_SUCCESS;
62 }
63 break;
64
65 case IRP_MJ_FILE_SYSTEM_CONTROL:
66 if (stack->Parameters.FileSystemControl.FsControlCode == FSCTL_HACKSSIGN_ASSIGN)
67 {
68 if (stack->Parameters.FileSystemControl.InputBufferLength <= sizeof(ASSIGN_INPUT) ||
69 Irp->AssociatedIrp.SystemBuffer == NULL)
70 {
71 status = STATUS_INVALID_DEVICE_REQUEST;
72 break;
73 }
74
75 inputBuffer = Irp->AssociatedIrp.SystemBuffer;
76
77 swprintf(dosBuffer, L"\\??\\%c:", inputBuffer->letter);
78 RtlInitUnicodeString(&source, dosBuffer);
79 target.Buffer = (PWSTR)((ULONG_PTR)inputBuffer + inputBuffer->offset);
80 target.Length = inputBuffer->len;
81 target.MaximumLength = target.Length;
82
83 DPRINT1("Will link %wZ to %wZ\n", &source, &target);
84
85 status = IoCreateSymbolicLink(&source, &target);
86 break;
87 }
88 else if (stack->Parameters.FileSystemControl.FsControlCode == FSCTL_HACKSSIGN_DELETE)
89 {
90 if (stack->Parameters.FileSystemControl.InputBufferLength < sizeof(WCHAR) ||
91 Irp->AssociatedIrp.SystemBuffer == NULL)
92 {
93 status = STATUS_INVALID_DEVICE_REQUEST;
94 break;
95 }
96
97 inputBuffer = Irp->AssociatedIrp.SystemBuffer;
98
99 swprintf(dosBuffer, L"\\??\\%c:", inputBuffer->letter);
100 RtlInitUnicodeString(&source, dosBuffer);
101
102 DPRINT1("Will unlink %wZ\n", &source);
103
104 status = IoDeleteSymbolicLink(&source);
105 break;
106 }
107
108 status = STATUS_INVALID_DEVICE_REQUEST;
109 break;
110
111 case IRP_MJ_CLEANUP:
112 vcb = fileObject->FsContext;
113 if (vcb == NULL)
114 {
115 status = STATUS_INVALID_HANDLE;
116 break;
117 }
118
119 DPRINT1("Device cleaned up\n");
120 IoRemoveShareAccess(fileObject, &vcb->shareAccess);
121 status = STATUS_SUCCESS;
122 break;
123
124 case IRP_MJ_CLOSE:
125 vcb = fileObject->FsContext;
126 if (vcb == NULL)
127 {
128 status = STATUS_INVALID_HANDLE;
129 break;
130 }
131
132 DPRINT1("Device closed\n");
133 fileObject->FsContext = NULL;
134 status = STATUS_SUCCESS;
135 break;
136
137 default:
138 status = STATUS_INVALID_DEVICE_REQUEST;
139 break;
140 }
141
142 ExReleaseResourceLite(&globalLock);
143 FsRtlExitFileSystem();
144
145 Irp->IoStatus.Status = status;
146 IoCompleteRequest(Irp, IO_NO_INCREMENT);
147
148 return status;
149 }
150
151 VOID
152 NTAPI
153 hsUnload(PDRIVER_OBJECT DriverObject)
154 {
155 IoDeleteDevice(gDevObj);
156 ExDeleteResourceLite(&globalLock);
157 }
158
159 NTSTATUS
160 NTAPI
161 DriverEntry(PDRIVER_OBJECT DriverObject,
162 PUNICODE_STRING RegistryPath)
163 {
164 NTSTATUS status;
165 PDEVICE_OBJECT devObj;
166 UNICODE_STRING devName, uDevName;
167
168 DPRINT1("Starting hackssign driver\n");
169
170 RtlInitUnicodeString(&devName, L"\\Device\\hackssign");
171 status = IoCreateDevice(DriverObject, sizeof(HS_VCB), &devName, FILE_DEVICE_FILE_SYSTEM, 0, FALSE, &devObj);
172 if (!NT_SUCCESS(status))
173 {
174 DPRINT1("IoCreateDevice failed\n");
175 return status;
176 }
177
178 RtlInitUnicodeString(&uDevName, L"\\??\\hackssign");
179 status = IoCreateSymbolicLink(&uDevName, &devName);
180 if (!NT_SUCCESS(status))
181 {
182 DPRINT1("IoCreateSymbolicLink failed\n");
183 IoDeleteDevice(devObj);
184 return status;
185 }
186
187 gDevObj = devObj;
188 ExInitializeResourceLite(&globalLock);
189 RtlZeroMemory(devObj->DeviceExtension, sizeof(HS_VCB));
190
191 DriverObject->DriverUnload = hsUnload;
192 DriverObject->MajorFunction[IRP_MJ_CREATE] = hsDispatch;
193 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = hsDispatch;
194 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = hsDispatch;
195 DriverObject->MajorFunction[IRP_MJ_CLOSE] = hsDispatch;
196
197 return STATUS_SUCCESS;
198 }