diff --git a/include/freerdp/channels/rdpdr.h b/include/freerdp/channels/rdpdr.h index 7b80db1a4..b6fbbbccb 100644 --- a/include/freerdp/channels/rdpdr.h +++ b/include/freerdp/channels/rdpdr.h @@ -22,6 +22,7 @@ #define FREERDP_CHANNEL_RDPDR_H #include +#include #include #include #include @@ -262,11 +263,14 @@ enum FSCTL_STRUCTURE #endif /* [MS-FSCC] FileFsDeviceInformation.DeviceType */ -enum FILE_FS_DEVICE_TYPE -{ - FILE_DEVICE_CD_ROM = 0x00000002, - FILE_DEVICE_DISK = 0x00000007 -}; + +#ifndef FILE_DEVICE_CD_ROM +#define FILE_DEVICE_CD_ROM 0x00000002 +#endif + +#ifndef FILE_DEVICE_DISK +#define FILE_DEVICE_DISK 0x00000007 +#endif /* [MS-FSCC] FileFsDeviceInformation.Characteristics */ enum FILE_FS_DEVICE_FLAG diff --git a/winpr/include/winpr/io.h b/winpr/include/winpr/io.h index 52d94ed17..f0ce89ed6 100644 --- a/winpr/include/winpr/io.h +++ b/winpr/include/winpr/io.h @@ -82,6 +82,88 @@ WINPR_API BOOL CancelSynchronousIo(HANDLE hThread); } #endif +/* + * WinPR I/O Manager Custom API + */ + +#define DEVICE_TYPE ULONG + +#define FILE_DEVICE_BEEP 0x00000001 +#define FILE_DEVICE_CD_ROM 0x00000002 +#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 +#define FILE_DEVICE_CONTROLLER 0x00000004 +#define FILE_DEVICE_DATALINK 0x00000005 +#define FILE_DEVICE_DFS 0x00000006 +#define FILE_DEVICE_DISK 0x00000007 +#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 +#define FILE_DEVICE_FILE_SYSTEM 0x00000009 +#define FILE_DEVICE_INPORT_PORT 0x0000000a +#define FILE_DEVICE_KEYBOARD 0x0000000b +#define FILE_DEVICE_MAILSLOT 0x0000000c +#define FILE_DEVICE_MIDI_IN 0x0000000d +#define FILE_DEVICE_MIDI_OUT 0x0000000e +#define FILE_DEVICE_MOUSE 0x0000000f +#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 +#define FILE_DEVICE_NAMED_PIPE 0x00000011 +#define FILE_DEVICE_NETWORK 0x00000012 +#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 +#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 +#define FILE_DEVICE_NULL 0x00000015 +#define FILE_DEVICE_PARALLEL_PORT 0x00000016 +#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 +#define FILE_DEVICE_PRINTER 0x00000018 +#define FILE_DEVICE_SCANNER 0x00000019 +#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a +#define FILE_DEVICE_SERIAL_PORT 0x0000001b +#define FILE_DEVICE_SCREEN 0x0000001c +#define FILE_DEVICE_SOUND 0x0000001d +#define FILE_DEVICE_STREAMS 0x0000001e +#define FILE_DEVICE_TAPE 0x0000001f +#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 +#define FILE_DEVICE_TRANSPORT 0x00000021 +#define FILE_DEVICE_UNKNOWN 0x00000022 +#define FILE_DEVICE_VIDEO 0x00000023 +#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 +#define FILE_DEVICE_WAVE_IN 0x00000025 +#define FILE_DEVICE_WAVE_OUT 0x00000026 +#define FILE_DEVICE_8042_PORT 0x00000027 +#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 +#define FILE_DEVICE_BATTERY 0x00000029 +#define FILE_DEVICE_BUS_EXTENDER 0x0000002a +#define FILE_DEVICE_MODEM 0x0000002b +#define FILE_DEVICE_VDM 0x0000002c +#define FILE_DEVICE_MASS_STORAGE 0x0000002d +#define FILE_DEVICE_SMB 0x0000002e +#define FILE_DEVICE_KS 0x0000002f +#define FILE_DEVICE_CHANGER 0x00000030 +#define FILE_DEVICE_SMARTCARD 0x00000031 +#define FILE_DEVICE_ACPI 0x00000032 +#define FILE_DEVICE_DVD 0x00000033 +#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 +#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035 +#define FILE_DEVICE_DFS_VOLUME 0x00000036 +#define FILE_DEVICE_SERENUM 0x00000037 +#define FILE_DEVICE_TERMSRV 0x00000038 +#define FILE_DEVICE_KSEC 0x00000039 +#define FILE_DEVICE_FIPS 0x0000003A +#define FILE_DEVICE_INFINIBAND 0x0000003B +#define FILE_DEVICE_VMBUS 0x0000003E +#define FILE_DEVICE_CRYPT_PROVIDER 0x0000003F +#define FILE_DEVICE_WPD 0x00000040 +#define FILE_DEVICE_BLUETOOTH 0x00000041 +#define FILE_DEVICE_MT_COMPOSITE 0x00000042 +#define FILE_DEVICE_MT_TRANSPORT 0x00000043 +#define FILE_DEVICE_BIOMETRIC 0x00000044 +#define FILE_DEVICE_PMI 0x00000045 + +typedef HANDLE PDRIVER_OBJECT_EX; +typedef HANDLE PDEVICE_OBJECT_EX; + +WINPR_API NTSTATUS _IoCreateDeviceEx(PDRIVER_OBJECT_EX DriverObject, ULONG DeviceExtensionSize, PUNICODE_STRING DeviceName, + DEVICE_TYPE DeviceType, ULONG DeviceCharacteristics, BOOLEAN Exclusive, PDEVICE_OBJECT_EX* DeviceObject); + +WINPR_API VOID _IoDeleteDeviceEx(PDEVICE_OBJECT_EX DeviceObject); + #endif #endif /* WINPR_IO_H */ diff --git a/winpr/libwinpr/io/CMakeLists.txt b/winpr/libwinpr/io/CMakeLists.txt index 58041b4a3..f913bd4a7 100644 --- a/winpr/libwinpr/io/CMakeLists.txt +++ b/winpr/libwinpr/io/CMakeLists.txt @@ -19,7 +19,9 @@ set(MODULE_NAME "winpr-io") set(MODULE_PREFIX "WINPR_IO") set(${MODULE_PREFIX}_SRCS - io.c) + device.c + io.c + io.h) if(MSVC AND (NOT MONOLITHIC_BUILD)) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def) @@ -31,6 +33,11 @@ add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT" set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib") +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} INTERNAL + MODULE winpr + MODULES winpr-crt winpr-path) + if(MONOLITHIC_BUILD) else() diff --git a/winpr/libwinpr/io/device.c b/winpr/libwinpr/io/device.c new file mode 100644 index 000000000..15ef9d22a --- /dev/null +++ b/winpr/libwinpr/io/device.c @@ -0,0 +1,201 @@ +/** + * WinPR: Windows Portable Runtime + * Asynchronous I/O Functions + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifndef _WIN32 + +#include "io.h" + +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include + +#include +#include +#include + +/** + * I/O Manager Routines + * http://msdn.microsoft.com/en-us/library/windows/hardware/ff551797/ + * + * These routines are only accessible to kernel drivers, but we need + * similar functionality in WinPR in user space. + * + * This is a best effort non-conflicting port of this API meant for + * non-Windows, WinPR usage only. + * + * References: + * + * Device Objects and Device Stacks: + * http://msdn.microsoft.com/en-us/library/windows/hardware/ff543153/ + * + * Driver Development Part 1: Introduction to Drivers: + * http://www.codeproject.com/Articles/9504/Driver-Development-Part-1-Introduction-to-Drivers/ + */ + +#define DEVICE_FILE_PREFIX_PATH "\\Device\\" + +char* GetDeviceFileNameWithoutPrefixA(LPCSTR lpName) +{ + char* lpFileName; + + if (!lpName) + return NULL; + + if (strncmp(lpName, DEVICE_FILE_PREFIX_PATH, sizeof(DEVICE_FILE_PREFIX_PATH) - 1) != 0) + return NULL; + + lpFileName = _strdup(&lpName[strlen(DEVICE_FILE_PREFIX_PATH)]); + + return lpFileName; +} + +char* GetDeviceFileUnixDomainSocketBaseFilePathA() +{ + char* lpTempPath; + char* lpPipePath; + + lpTempPath = GetKnownPath(KNOWN_PATH_TEMP); + lpPipePath = GetCombinedPath(lpTempPath, ".device"); + + free(lpTempPath); + + return lpPipePath; +} + +char* GetDeviceFileUnixDomainSocketFilePathA(LPCSTR lpName) +{ + char* lpPipePath; + char* lpFileName; + char* lpFilePath; + + lpPipePath = GetDeviceFileUnixDomainSocketBaseFilePathA(); + + lpFileName = GetDeviceFileNameWithoutPrefixA(lpName); + lpFilePath = GetCombinedPath(lpPipePath, (char*) lpFileName); + + free(lpPipePath); + free(lpFileName); + + return lpFilePath; +} + +/** + * IoCreateDevice: + * http://msdn.microsoft.com/en-us/library/windows/hardware/ff548397/ + */ + +NTSTATUS _IoCreateDeviceEx(PDRIVER_OBJECT_EX DriverObject, ULONG DeviceExtensionSize, PUNICODE_STRING DeviceName, + DEVICE_TYPE DeviceType, ULONG DeviceCharacteristics, BOOLEAN Exclusive, PDEVICE_OBJECT_EX* DeviceObject) +{ + int status; + char* DeviceBasePath; + DEVICE_OBJECT_EX* pDeviceObjectEx; + + DeviceBasePath = GetDeviceFileUnixDomainSocketBaseFilePathA(); + + if (!PathFileExistsA(DeviceBasePath)) + { + if (!mkdir(DeviceBasePath, S_IRUSR | S_IWUSR | S_IXUSR)) + { + free(DeviceBasePath); + return STATUS_ACCESS_DENIED; + } + } + + pDeviceObjectEx = (DEVICE_OBJECT_EX*) malloc(sizeof(DEVICE_OBJECT_EX)); + + if (!pDeviceObjectEx) + { + return STATUS_NO_MEMORY; + } + + ZeroMemory(pDeviceObjectEx, sizeof(DEVICE_OBJECT_EX)); + + ConvertFromUnicode(CP_UTF8, 0, DeviceName->Buffer, DeviceName->Length / 2, &(pDeviceObjectEx->DeviceName), 0, NULL, NULL); + + pDeviceObjectEx->DeviceFileName = GetDeviceFileUnixDomainSocketFilePathA(pDeviceObjectEx->DeviceName); + + if (PathFileExistsA(pDeviceObjectEx->DeviceFileName)) + { + unlink(pDeviceObjectEx->DeviceFileName); + } + + status = mkfifo(pDeviceObjectEx->DeviceFileName, 0666); + + *((ULONG_PTR*) (DeviceObject)) = (ULONG_PTR) pDeviceObjectEx; + + return STATUS_SUCCESS; +} + +/** + * IoDeleteDevice: + * http://msdn.microsoft.com/en-us/library/windows/hardware/ff549083/ + */ + +VOID _IoDeleteDeviceEx(PDEVICE_OBJECT_EX DeviceObject) +{ + DEVICE_OBJECT_EX* pDeviceObjectEx; + + pDeviceObjectEx = (DEVICE_OBJECT_EX*) DeviceObject; + + if (!pDeviceObjectEx) + return; + + unlink(pDeviceObjectEx->DeviceFileName); + + free(pDeviceObjectEx->DeviceName); + free(pDeviceObjectEx->DeviceFileName); + + free(pDeviceObjectEx); +} + +/** + * IoCreateSymbolicLink: + * http://msdn.microsoft.com/en-us/library/windows/hardware/ff549043/ + */ + +NTSTATUS _IoCreateSymbolicLinkEx(PUNICODE_STRING SymbolicLinkName, PUNICODE_STRING DeviceName) +{ + return STATUS_SUCCESS; +} + +/** + * IoDeleteSymbolicLink: + * http://msdn.microsoft.com/en-us/library/windows/hardware/ff549085/ + */ + +NTSTATUS _IoDeleteSymbolicLinkEx(PUNICODE_STRING SymbolicLinkName) +{ + return STATUS_SUCCESS; +} + +#endif diff --git a/winpr/libwinpr/io/io.h b/winpr/libwinpr/io/io.h new file mode 100644 index 000000000..d359bcf94 --- /dev/null +++ b/winpr/libwinpr/io/io.h @@ -0,0 +1,40 @@ +/** + * WinPR: Windows Portable Runtime + * Asynchronous I/O Functions + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_IO_PRIVATE_H +#define WINPR_IO_PRIVATE_H + +#ifndef _WIN32 + +#include + +#include "../handle/handle.h" + +typedef struct _DEVICE_OBJECT_EX DEVICE_OBJECT_EX; + +struct _DEVICE_OBJECT_EX +{ + char* DeviceName; + char* DeviceFileName; +}; + +#endif + +#endif /* WINPR_IO_PRIVATE_H */ + diff --git a/winpr/libwinpr/io/test/CMakeLists.txt b/winpr/libwinpr/io/test/CMakeLists.txt index 401fe15ca..734f0b6fb 100644 --- a/winpr/libwinpr/io/test/CMakeLists.txt +++ b/winpr/libwinpr/io/test/CMakeLists.txt @@ -5,6 +5,7 @@ set(MODULE_PREFIX "TEST_IO") set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) set(${MODULE_PREFIX}_TESTS + TestIoDevice.c TestIoGetOverlappedResult.c) create_test_sourcelist(${MODULE_PREFIX}_SRCS diff --git a/winpr/libwinpr/io/test/TestIoDevice.c b/winpr/libwinpr/io/test/TestIoDevice.c new file mode 100644 index 000000000..97d8ea80e --- /dev/null +++ b/winpr/libwinpr/io/test/TestIoDevice.c @@ -0,0 +1,28 @@ + +#include +#include +#include +#include + +int TestIoDevice(int argc, char* argv[]) +{ +#ifndef _WIN32 + NTSTATUS NtStatus; + ANSI_STRING aString; + UNICODE_STRING uString; + PDEVICE_OBJECT_EX pDeviceObject = NULL; + + _RtlInitAnsiString(&aString, "\\Device\\Example"); + _RtlAnsiStringToUnicodeString(&uString, &aString, TRUE); + + NtStatus = _IoCreateDeviceEx(NULL, 0, + &uString, FILE_DEVICE_UNKNOWN, + 0, FALSE, &pDeviceObject); + + _IoDeleteDeviceEx(pDeviceObject); + + _RtlFreeUnicodeString(&uString); +#endif + return 0; +} +