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>
17 typedef struct _HS_VCB
19 SHARE_ACCESS shareAccess
;
23 PDEVICE_OBJECT gDevObj
;
27 hsDispatch(PDEVICE_OBJECT DeviceObject
,
33 PFILE_OBJECT fileObject
;
34 PIO_STACK_LOCATION stack
;
35 PASSIGN_INPUT inputBuffer
;
36 UNICODE_STRING target
, source
;
38 FsRtlEnterFileSystem();
39 ExAcquireResourceExclusiveLite(&globalLock
, TRUE
);
41 stack
= IoGetCurrentIrpStackLocation(Irp
);
42 fileObject
= stack
->FileObject
;
43 switch (stack
->MajorFunction
)
46 if (fileObject
->FileName
.Length
!= 0)
48 status
= STATUS_INVALID_DEVICE_REQUEST
;
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
))
57 DPRINT1("Device opened\n");
59 Irp
->IoStatus
.Information
= FILE_OPENED
;
60 fileObject
->FsContext
= DeviceObject
->DeviceExtension
;
61 status
= STATUS_SUCCESS
;
65 case IRP_MJ_FILE_SYSTEM_CONTROL
:
66 if (stack
->Parameters
.FileSystemControl
.FsControlCode
== FSCTL_HACKSSIGN_ASSIGN
)
68 if (stack
->Parameters
.FileSystemControl
.InputBufferLength
<= sizeof(ASSIGN_INPUT
) ||
69 Irp
->AssociatedIrp
.SystemBuffer
== NULL
)
71 status
= STATUS_INVALID_DEVICE_REQUEST
;
75 inputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
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
;
83 DPRINT1("Will link %wZ to %wZ\n", &source
, &target
);
85 status
= IoCreateSymbolicLink(&source
, &target
);
88 else if (stack
->Parameters
.FileSystemControl
.FsControlCode
== FSCTL_HACKSSIGN_DELETE
)
90 if (stack
->Parameters
.FileSystemControl
.InputBufferLength
< sizeof(WCHAR
) ||
91 Irp
->AssociatedIrp
.SystemBuffer
== NULL
)
93 status
= STATUS_INVALID_DEVICE_REQUEST
;
97 inputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
99 swprintf(dosBuffer
, L
"\\??\\%c:", inputBuffer
->letter
);
100 RtlInitUnicodeString(&source
, dosBuffer
);
102 DPRINT1("Will unlink %wZ\n", &source
);
104 status
= IoDeleteSymbolicLink(&source
);
108 status
= STATUS_INVALID_DEVICE_REQUEST
;
112 vcb
= fileObject
->FsContext
;
115 status
= STATUS_INVALID_HANDLE
;
119 DPRINT1("Device cleaned up\n");
120 IoRemoveShareAccess(fileObject
, &vcb
->shareAccess
);
121 status
= STATUS_SUCCESS
;
125 vcb
= fileObject
->FsContext
;
128 status
= STATUS_INVALID_HANDLE
;
132 DPRINT1("Device closed\n");
133 fileObject
->FsContext
= NULL
;
134 status
= STATUS_SUCCESS
;
138 status
= STATUS_INVALID_DEVICE_REQUEST
;
142 ExReleaseResourceLite(&globalLock
);
143 FsRtlExitFileSystem();
145 Irp
->IoStatus
.Status
= status
;
146 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
153 hsUnload(PDRIVER_OBJECT DriverObject
)
155 IoDeleteDevice(gDevObj
);
156 ExDeleteResourceLite(&globalLock
);
161 DriverEntry(PDRIVER_OBJECT DriverObject
,
162 PUNICODE_STRING RegistryPath
)
165 PDEVICE_OBJECT devObj
;
166 UNICODE_STRING devName
, uDevName
;
168 DPRINT1("Starting hackssign driver\n");
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
))
174 DPRINT1("IoCreateDevice failed\n");
178 RtlInitUnicodeString(&uDevName
, L
"\\??\\hackssign");
179 status
= IoCreateSymbolicLink(&uDevName
, &devName
);
180 if (!NT_SUCCESS(status
))
182 DPRINT1("IoCreateSymbolicLink failed\n");
183 IoDeleteDevice(devObj
);
188 ExInitializeResourceLite(&globalLock
);
189 RtlZeroMemory(devObj
->DeviceExtension
, sizeof(HS_VCB
));
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
;
197 return STATUS_SUCCESS
;